diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/404.html b/404.html new file mode 100644 index 000000000..024343d02 --- /dev/null +++ b/404.html @@ -0,0 +1,4 @@ + +Redirecting... \ No newline at end of file diff --git a/CNAME b/CNAME new file mode 100644 index 000000000..c22a09993 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +docs.flare.network \ No newline at end of file diff --git a/api-icon.svg b/api-icon.svg new file mode 100644 index 000000000..ee5792677 --- /dev/null +++ b/api-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apis/index.html b/apis/index.html new file mode 100644 index 000000000..6b1fd560f --- /dev/null +++ b/apis/index.html @@ -0,0 +1,3855 @@ + + + + + + + + + + + + + + + + + + APIs - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+ + + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/AddressUpdatable/index.html b/apis/smart-contracts/AddressUpdatable/index.html new file mode 100644 index 000000000..26d07faa9 --- /dev/null +++ b/apis/smart-contracts/AddressUpdatable/index.html @@ -0,0 +1,4040 @@ + + + + + + + + + + + + + + + + + + AddressUpdatable - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

AddressUpdatable#

+
+

Source | Inherits from IIAddressUpdatable

+
+
+

Abstract base class for contracts that depend on other contracts whose addresses can change.

+

The AddressUpdater contract keeps a list of addresses for all unique and special +platform contracts. By inheriting from AddressUpdatable a contract will receive updates +if any of the platform contract addresses change.

+

A contract's address changes when it is redeployed, so AddressUpdatable offers a way +to keep up to date with the latest address for all dependencies.

+
+
+

Functions#

+
+

getAddressUpdater#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
function getAddressUpdater(
+) public view returns (
+    address _addressUpdater);
+
+

Returns the configured address updater.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_addressUpdateraddressThe AddresUpdater contract that can update our contract address list, as a response to a governance call.
+
+
+
+

updateContractAddresses#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
function updateContractAddresses(
+    bytes32[] _contractNameHashes,
+    address[] _contractAddresses
+) external;
+
+

External method called from AddressUpdater only.

+
+
+
+
+

Modifiers#

+
+

onlyAddressUpdater#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
modifier onlyAddressUpdater()
+
+

Only the AdressUpdater contract can call this method. +Its address is set at construction time but it can also update itself.

+
+
+
+
+

Variables#

+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/AddressUpdater/index.html b/apis/smart-contracts/AddressUpdater/index.html new file mode 100644 index 000000000..542ac906a --- /dev/null +++ b/apis/smart-contracts/AddressUpdater/index.html @@ -0,0 +1,4696 @@ + + + + + + + + + + + + + + + + + + AddressUpdater - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + +

AddressUpdater#

+
+

Source | Inherits from IIAddressUpdater, Governed

+
+
+

Keeps track of the current address for all unique and special platform contracts.

+

This contract keeps a list of addresses that gets updated by governance every time +any of the tracked contracts is redeployed. +This list is then used by the FlareContractRegistry, and also by AddressUpdatable +to inform all dependent contracts of any address change.

+
+
+

Functions#

+
+

addOrUpdateContractNamesAndAddresses#

+
+

Defined in AddressUpdater (Docs, Source).

+
+
+
function addOrUpdateContractNamesAndAddresses(
+    string[] _contractNames,
+    address[] _contractAddresses
+) external;
+
+

Add or update contract names and addresses that are later used in updateContractAddresses calls.

+

Can only be called by governance.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_contractNamesstring[]Contracts names.
_contractAddressesaddress[]Addresses of corresponding contracts names.
+
+
+
+

cancelGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function cancelGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Cancel a timelocked governance call before it has been executed.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector.
+
+
+
+

constructor#

+
+

Defined in AddressUpdater (Docs, Source).

+
+
+
constructor(
+    address _governance
+) public;
+
+
+
+
+

constructor#

+
+

Defined in Governed (Docs, Source).

+
+
+
constructor(
+    address _governance
+) public;
+
+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_governanceaddressGovernance contract. Must not be zero.
+
+
+
+

executeGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function executeGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Execute the timelocked governance calls once the timelock period expires.

+

Only executor can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector (only one timelocked call per method is stored).
+
+
+
+

getContractAddress#

+
+

Defined in AddressUpdater (Docs, Source).

+
+
+
function getContractAddress(
+    string _name
+) external view returns (
+    address);
+
+

Returns contract address for the given name, which might be address(0).

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_namestringName of the contract to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]addressCurrent address for the queried contract.
+
+
+
+

getContractAddressByHash#

+
+

Defined in AddressUpdater (Docs, Source).

+
+
+
function getContractAddressByHash(
+    bytes32 _nameHash
+) external view returns (
+    address);
+
+

Returns contract address for the given name hash, which might be address(0).

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_nameHashbytes32Hash of the contract name: keccak256(abi.encode(name))
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]addressCurrent address for the queried contract.
+
+
+
+

getContractAddresses#

+
+

Defined in AddressUpdater (Docs, Source).

+
+
+
function getContractAddresses(
+    string[] _names
+) external view returns (
+    address[]);
+
+

Returns contract addresses for the given names, which might be address(0).

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_namesstring[]Names of the contracts to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]address[]Current addresses for the queried contracts.
+
+
+
+

getContractAddressesByHash#

+
+

Defined in AddressUpdater (Docs, Source).

+
+
+
function getContractAddressesByHash(
+    bytes32[] _nameHashes
+) external view returns (
+    address[]);
+
+

Returns contract addresses for the given name hashes, which might be address(0).

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_nameHashesbytes32[]Hashes of the contract names: keccak256(abi.encode(name))
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]address[]Current addresses for the queried contracts.
+
+
+
+

getContractNamesAndAddresses#

+
+

Defined in AddressUpdater (Docs, Source).

+
+
+
function getContractNamesAndAddresses(
+) external view returns (
+    string[] _contractNames,
+    address[] _contractAddresses);
+
+

Returns all contract names and corresponding addresses currently being tracked.

+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_contractNamesstring[]Array of contract names.
_contractAddressesaddress[]Array of contract addresses.
+
+
+
+

governance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function governance(
+) public view returns (
+    address);
+
+

Returns the current effective governance address.

+
+
+
+

removeContracts#

+
+

Defined in AddressUpdater (Docs, Source).

+
+
+
function removeContracts(
+    string[] _contractNames
+) external;
+
+

Remove contracts with given names.

+

Can only be called by governance.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_contractNamesstring[]Contract names.
+
+
+
+

switchToProductionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function switchToProductionMode(
+) external;
+
+

Enter the production mode after all the initial governance settings have been set. +This enables timelocks and the governance can be obtained afterward by calling +governanceSettings.getGovernanceAddress(). +Emits GovernedProductionModeEntered.

+
+
+
+

update#

+
+

Defined in AddressUpdater (Docs, Source).

+
+
+
function update(
+    string[] _contractNames,
+    address[] _contractAddresses,
+    contract IIAddressUpdatable[] _contractsToUpdate
+) external;
+
+

Set or update contract names and addresses, and then apply changes to specific contracts.

+

This is a combination of addOrUpdateContractNamesAndAddresses and updateContractAddresses. +Can only be called by governance.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_contractNamesstring[]Contracts names.
_contractAddressesaddress[]Addresses of corresponding contracts names.
_contractsToUpdatecontract IIAddressUpdatable[]Contracts to be updated.
+
+
+
+

updateContractAddresses#

+
+

Defined in AddressUpdater (Docs, Source).

+
+
+
function updateContractAddresses(
+    contract IIAddressUpdatable[] _contractsToUpdate
+) external;
+
+

Updates contract addresses on specific contracts.

+

Can only be called by governance.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_contractsToUpdatecontract IIAddressUpdatable[]Contracts to be updated, which must implement the IIAddressUpdatable interface.
+
+
+
+
+

Variables#

+
+

governanceSettings#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    contract IGovernanceSettings governanceSettings
+
+

Governance Settings.

+
+
+
+

productionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    bool productionMode
+
+

When true, governance is enabled and cannot be disabled. See switchToProductionMode.

+
+
+
+

timelockedCalls#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    mapping(bytes4 => struct GovernedBase.TimelockedCall) timelockedCalls
+
+

List of pending timelocked governance calls.

+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/CheckPointable/index.html b/apis/smart-contracts/CheckPointable/index.html new file mode 100644 index 000000000..6c2b91110 --- /dev/null +++ b/apis/smart-contracts/CheckPointable/index.html @@ -0,0 +1,4272 @@ + + + + + + + + + + + + + + + + + + CheckPointable - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

CheckPointable#

+
+

Source

+
+
+

Check-Pointable ERC20 Behavior.

+

ERC20 behavior that adds balance check-point features.

+
+
+

Events#

+
+

CreatedTotalSupplyCache#

+
+

Defined in CheckPointable (Docs, Source).

+
+
+
event CreatedTotalSupplyCache(
+    uint256 _blockNumber
+)
+
+

Emitted when a total supply cache entry is created. +Allows history cleaners to track total supply cache cleanup opportunities off-chain.

+
+
+
+
+

Functions#

+
+

balanceHistoryCleanup#

+
+

Defined in CheckPointable (Docs, Source).

+
+
+
function balanceHistoryCleanup(
+    address _owner,
+    uint256 _count
+) external returns (
+    uint256);
+
+

Delete balance checkpoints that expired (i.e. are before cleanupBlockNumber). +Method can only be called from the cleanerContract (which may be a proxy to external cleaners).

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressbalance owner account address
_countuint256maximum number of checkpoints to delete
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256the number of checkpoints deleted
+
+
+
+

totalSupplyCacheCleanup#

+
+

Defined in CheckPointable (Docs, Source).

+
+
+
function totalSupplyCacheCleanup(
+    uint256 _blockNumber
+) external returns (
+    uint256);
+
+

Delete total supply cache entry that expired (i.e. is before cleanupBlockNumber). +Method can only be called from the cleanerContract (which may be a proxy to external cleaners).

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockNumberuint256the block number for which total supply value was cached
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256the number of cache entries deleted (always 0 or 1)
+
+
+
+

totalSupplyHistoryCleanup#

+
+

Defined in CheckPointable (Docs, Source).

+
+
+
function totalSupplyHistoryCleanup(
+    uint256 _count
+) external returns (
+    uint256);
+
+

Delete total supply checkpoints that expired (i.e. are before cleanupBlockNumber). +Method can only be called from the cleanerContract (which may be a proxy to external cleaners).

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_countuint256maximum number of checkpoints to delete
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256the number of checkpoints deleted
+
+
+
+
+

Modifiers#

+
+

notBeforeCleanupBlock#

+
+

Defined in CheckPointable (Docs, Source).

+
+
+
modifier notBeforeCleanupBlock(    uint256 _blockNumber)
+
+

This method cannot be called for _blockNumber lower than the current cleanup block number.

+
+
+
+

onlyCleaner#

+
+

Defined in CheckPointable (Docs, Source).

+
+
+
modifier onlyCleaner()
+
+

Only the cleanerContract can call this method.

+
+
+
+
+

Variables#

+
+

cleanerContract#

+
+

Defined in CheckPointable (Docs, Source).

+
+
+
    address cleanerContract
+
+

Address of the contract that is allowed to call methods for history cleaning.

+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/ClaimSetupManager/index.html b/apis/smart-contracts/ClaimSetupManager/index.html new file mode 100644 index 000000000..93337ef14 --- /dev/null +++ b/apis/smart-contracts/ClaimSetupManager/index.html @@ -0,0 +1,6388 @@ + + + + + + + + + + + + + + + + + + ClaimSetupManager - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

ClaimSetupManager#

+
+

Source | Inherits from IIClaimSetupManager, Governed, AddressUpdatable, CloneFactory, ReentrancyGuard

+
+
+

Manages automation of operations related to reward claiming.

+

Rewards include FTSO rewards and +airdrops. +Managed operations include Automatic Claiming and +Personal Delegation Accounts.

+
+
+

Functions#

+
+

accountToDelegationAccount#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function accountToDelegationAccount(
+    address _owner
+) external view returns (
+    address);
+
+

Gets the PDA of an account.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressAccount to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]addressAddress of its PDA or address(0) if it has not been created yet.
+
+
+
+

allowedClaimRecipients#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function allowedClaimRecipients(
+    address _owner
+) external view returns (
+    address[]);
+
+

Gets the addresses of recipients allowed to receive rewards on behalf of an account. +Beside these, the owner of the rewards is always authorized. +See setAllowedClaimRecipients.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddress
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]address[]Addresses of all set authorized recipients.
+
+
+
+

batchDelegate#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function batchDelegate(
+    address[] _delegatees,
+    uint256[] _bips
+) external;
+
+

Undelegates all percentage delegations from the caller's +PDA and then delegate to a list of accounts.

+

See delegate.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_delegateesaddress[]The addresses of the new recipients.
_bipsuint256[]The percentage of voting power to be delegated to each delegatee, expressed in basis points (1/100 of one percent). Total of all _bips values must be lower than 10000.
+
+
+
+

cancelGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function cancelGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Cancel a timelocked governance call before it has been executed.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector.
+
+
+
+

checkExecutorAndAllowedRecipient#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function checkExecutorAndAllowedRecipient(
+    address _executor,
+    address _claimFor,
+    address _recipient
+) external view;
+
+

Checks if an executor can claim on behalf of a given account and send funds to a given recipient address.

+

Reverts if claiming is not possible, does nothing otherwise.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_executoraddressThe executor to query.
_claimForaddress
_recipientaddressThe address where the reward would be sent.
+
+
+
+

claimExecutors#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function claimExecutors(
+    address _owner
+) external view returns (
+    address[]);
+
+

Gets the addresses of executors authorized to claim for an account. +See setClaimExecutors.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe account to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]address[]Addresses of all set executors.
+
+
+
+

constructor#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
constructor(
+    address _governance,
+    address _addressUpdater,
+    uint256 _feeValueUpdateOffset,
+    uint256 _minFeeValueWei,
+    uint256 _maxFeeValueWei,
+    uint256 _registerExecutorFeeValueWei
+) public;
+
+
+
+
+

constructor#

+
+

Defined in Governed (Docs, Source).

+
+
+
constructor(
+    address _governance
+) public;
+
+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_governanceaddressGovernance contract. Must not be zero.
+
+
+
+

delegate#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function delegate(
+    address _to,
+    uint256 _bips
+) external;
+
+

Delegates a percentage of the caller's +PDA's voting power to another address.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_toaddressThe address of the recipient.
_bipsuint256The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: Every call resets the delegation value. A value of 0 revokes delegation.
+
+
+
+

delegateGovernance#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function delegateGovernance(
+    address _to
+) external;
+
+

Delegates all the governance vote power of the caller's +PDA to another account.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_toaddressAddress of the recipient of the delegation.
+
+
+
+

disableDelegationAccount#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function disableDelegationAccount(
+) external;
+
+

Disables the +Personal Delegation Account (PDA).

+

When using automatic claiming, all airdrops and FTSO rewards will be sent to the owner's account. +Rewards accrued by the PDA will no longer be automatically claimed.

+

Reverts if there is no PDA.

+
+
+
+

enableDelegationAccount#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function enableDelegationAccount(
+) external returns (
+    contract IDelegationAccount);
+
+

Enables (or creates) a +Personal Delegation Account (PDA).

+

When using automatic claiming, all airdrops and FTSO rewards will be sent to the PDA, and any rewards +accrued by the PDA will be claimed too.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]contract IDelegationAccountAddress of the delegation account contract.
+
+
+
+

executeGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function executeGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Execute the timelocked governance calls once the timelock period expires.

+

Only executor can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector (only one timelocked call per method is stored).
+
+
+
+

getAddressUpdater#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
function getAddressUpdater(
+) public view returns (
+    address _addressUpdater);
+
+

Returns the configured address updater.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_addressUpdateraddressThe AddresUpdater contract that can update our contract address list, as a response to a governance call.
+
+
+
+

getAutoClaimAddressesAndExecutorFee#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function getAutoClaimAddressesAndExecutorFee(
+    address _executor,
+    address[] _owners
+) external view returns (
+    address[] _recipients,
+    uint256 _executorFeeValue);
+
+

Gets the Personal Delegation Account (PDA) for +a list of accounts for which an executor is claiming. +Returns owner address instead if the PDA is not created yet or not enabled.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_executoraddressExecutor to query.
_ownersaddress[]Array of reward owners which must have set _executor as their executor.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_recipientsaddress[]Addresses which will receive the claimed rewards. Can be the reward owners or their PDAs.
_executorFeeValueuint256Executor's fee value, in wei.
+
+
+
+

getDelegationAccountData#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function getDelegationAccountData(
+    address _owner
+) external view returns (
+    contract IDelegationAccount _delegationAccount,
+    bool _enabled);
+
+

Gets PDA data for an account.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressAccount to query.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_delegationAccountcontract IDelegationAccountAccount's PDA address or address(0) if it has not been created yet.
_enabledboolWhether the PDA is enabled.
+
+
+
+

getExecutorCurrentFeeValue#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function getExecutorCurrentFeeValue(
+    address _executor
+) public view returns (
+    uint256);
+
+

Returns the current fee of a registered executor. +Reverts if the executor is not registered.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_executoraddressThe executor to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Fee in wei.
+
+
+
+

getExecutorFeeValue#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function getExecutorFeeValue(
+    address _executor,
+    uint256 _rewardEpoch
+) external view returns (
+    uint256);
+
+

Returns the fee of an executor at a given reward epoch.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_executoraddressThe executor to query.
_rewardEpochuint256Reward Epoch ID to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Fee in wei at that reward epoch.
+
+
+
+

getExecutorInfo#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function getExecutorInfo(
+    address _executor
+) external view returns (
+    bool _registered,
+    uint256 _currentFeeValue);
+
+

Returns information about an executor.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_executoraddressThe executor to query.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_registeredboolWhether the executor is registered.
_currentFeeValueuint256Executor's current fee value, if registered.
+
+
+
+

getExecutorScheduledFeeValueChanges#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function getExecutorScheduledFeeValueChanges(
+    address _executor
+) external view returns (
+    uint256[] _feeValue,
+    uint256[] _validFromEpoch,
+    bool[] _fixed);
+
+

Returns the currently scheduled fee changes of an executor.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_executoraddressExecutor to query.
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_feeValueuint256[]Array of scheduled fees.
_validFromEpochuint256[]Array of reward epochs ID where the scheduled fees will become effective.
_fixedbool[]Array of booleans indicating if an scheduled fee change is fixed or it might still be changed.
+
+
+
+

getRegisteredExecutors#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function getRegisteredExecutors(
+    uint256 _start,
+    uint256 _end
+) external view returns (
+    address[] _registeredExecutors,
+    uint256 _totalLength);
+
+

Returns the list of executors registered through registerExecutor. +Supports paging.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_startuint256First executor to return.
_enduint256Last executor to return.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_registeredExecutorsaddress[]Addresses of the registered executors.
_totalLengthuint256Total amount of executors.
+
+
+
+

governance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function governance(
+) public view returns (
+    address);
+
+

Returns the current effective governance address.

+
+
+
+

isClaimExecutor#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function isClaimExecutor(
+    address _owner,
+    address _executor
+) external view returns (
+    bool);
+
+

Returns whether an executor is authorized to claim on behalf of a reward owner. +See setClaimExecutors.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe reward owner to query.
_executoraddressThe executor to query.
+
+
+
+

registerExecutor#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function registerExecutor(
+    uint256 _feeValue
+) external payable returns (
+    uint256);
+
+

Registers the caller as an executor and sets its initial fee value.

+

If the executor was already registered, this method only updates the fee, which will take effect after +feeValueUpdateOffset reward epochs have elapsed.

+

Executor must pay a fee in order to register. See registerExecutorFeeValueWei.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_feeValueuint256Desired fee, in wei. Must be between minFeeValueWei and maxFeeValueWei. 0 means no fee.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Reward epoch ID when the changes become effective.
+
+
+
+

revokeDelegationAt#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function revokeDelegationAt(
+    address _who,
+    uint256 _blockNumber
+) external;
+
+

Revokes all delegation from the caller's PDA +to a given account at a given block.

+

Only affects the reads via votePowerOfAtCached() in the specified block.

+

This method should be used only to prevent rogue delegate voting in the current voting block. +To stop delegating use delegate with percentage of 0 or undelegateAll.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe account to revoke.
_blockNumberuint256Block number where the revoking will take place. Must be in the past.
+
+
+
+

setAllowedClaimRecipients#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function setAllowedClaimRecipients(
+    address[] _recipients
+) external;
+
+

Set the addresses of allowed recipients. +The reward owner is always an allowed recipient.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_recipientsaddress[]The new allowed recipients. All old recipients will be deleted and replaced by these.
+
+
+
+

setAutoClaiming#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function setAutoClaiming(
+    address[] _executors,
+    bool _enableDelegationAccount
+) external payable;
+
+

Sets the addresses of executors and optionally enables (creates) a +Personal Delegation Account (PDA).

+

If any of the executors is a registered executor, some fee needs to be paid.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_executorsaddress[]The new executors. All old executors will be deleted and replaced by these.
_enableDelegationAccountboolWhether the PDA should be enabled.
+
+
+
+

setClaimExecutors#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function setClaimExecutors(
+    address[] _executors
+) external payable;
+
+

Sets the addresses of executors.

+

If any of the executors is a registered executor, some fee needs to be paid.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_executorsaddress[]The new executors. All old executors will be deleted and replaced by these.
+
+
+
+

setLibraryAddress#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function setLibraryAddress(
+    address _libraryAddress
+) external;
+
+

Sets new library address.

+

Only governance can call this.

+
+
+
+

setMaxFeeValueWei#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function setMaxFeeValueWei(
+    uint256 _maxFeeValueWei
+) external;
+
+

Sets maximum fee allowed for executors, in wei.

+

Only governance can call this.

+
+
+
+

setMinFeeValueWei#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function setMinFeeValueWei(
+    uint256 _minFeeValueWei
+) external;
+
+

Sets minimum fee allowed for executors, in wei.

+

Only governance can call this.

+
+
+
+

setRegisterExecutorFeeValueWei#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function setRegisterExecutorFeeValueWei(
+    uint256 _registerExecutorFeeValueWei
+) external;
+
+

Sets the fee required to register an executor, which must be higher than 0.

+

Only governance can call this.

+
+
+
+

switchToProductionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function switchToProductionMode(
+) external;
+
+

Enter the production mode after all the initial governance settings have been set. +This enables timelocks and the governance can be obtained afterward by calling +governanceSettings.getGovernanceAddress(). +Emits GovernedProductionModeEntered.

+
+
+
+

transferExternalToken#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function transferExternalToken(
+    contract IERC20 _token,
+    uint256 _amount
+) external;
+
+

Allows the caller to transfer ERC-20 tokens from their +PDA to the owner account.

+

The main use case is to move ERC-20 tokes received by mistake (by an airdrop, for example) out of the PDA +and into the main account, where they can be more easily managed.

+

Reverts if the target token is the WNat contract: use method withdraw for that.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_tokencontract IERC20Target token contract address.
_amountuint256Amount of tokens to transfer.
+
+
+
+

undelegateAll#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function undelegateAll(
+) external;
+
+

Removes all delegations from the caller's PDA.

+
+
+
+

undelegateGovernance#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function undelegateGovernance(
+) external;
+
+

Undelegates all governance vote power currently delegated by +the caller's PDA.

+
+
+
+

unregisterExecutor#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function unregisterExecutor(
+) external returns (
+    uint256 _validFromEpoch);
+
+

Unregisters the caller as an executor.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_validFromEpochuint256Reward epoch ID when the change becomes effective.
+
+
+
+

updateContractAddresses#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
function updateContractAddresses(
+    bytes32[] _contractNameHashes,
+    address[] _contractAddresses
+) external;
+
+

External method called from AddressUpdater only.

+
+
+
+

updateExecutorFeeValue#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function updateExecutorFeeValue(
+    uint256 _feeValue
+) external returns (
+    uint256);
+
+

Sets the caller's executor fee. The caller must be an executor registered through registerExecutor.

+

When called multiple times inside the same reward epoch, only the last value remains.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_feeValueuint256Desired fee, in wei. Must be between minFeeValueWei and maxFeeValueWei. 0 means no fee.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Reward epoch ID when the changes become effective.
+
+
+
+

wNat#

+
+

Defined in IIClaimSetupManager (Docs, Source).

+
+
+
function wNat(
+) external view returns (
+    contract WNat);
+
+

Returns the WNat contract.

+
+
+
+

withdraw#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
function withdraw(
+    uint256 _amount
+) external;
+
+

Allows the caller to transfer WNat wrapped tokens from their +PDA to the owner account.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_amountuint256Amount of tokens to transfer, in wei.
+
+
+
+
+

Modifiers#

+
+

nonReentrant#

+
+

Defined in ReentrancyGuard (Source).

+
+
+
modifier nonReentrant()
+
+

Prevents a contract from calling itself, directly or indirectly. +Calling a nonReentrant function from another nonReentrant +function is not supported. It is possible to prevent this from happening +by making the nonReentrant function external, and make it call a +private function that does the actual work.

+
+
+
+

onlyAddressUpdater#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
modifier onlyAddressUpdater()
+
+

Only the AdressUpdater contract can call this method. +Its address is set at construction time but it can also update itself.

+
+
+
+

onlyGovernance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
modifier onlyGovernance()
+
+
+
+
+

onlyImmediateGovernance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
modifier onlyImmediateGovernance()
+
+
+
+
+

onlyOwnerOrExecutor#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
modifier onlyOwnerOrExecutor(    address _executor,
+    address[] _owners)
+
+
+
+
+
+

Structures#

+
+

DelegationAccountData#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
struct DelegationAccountData {
+  contract IIDelegationAccount delegationAccount;
+  bool enabled;
+}
+
+
+
+

ExecutorFee#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
struct ExecutorFee {
+  uint256 value;
+  uint256 validFromEpoch;
+}
+
+
+
+

TimelockedCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
struct TimelockedCall {
+  uint256 allowedAfterTimestamp;
+  bytes encodedCall;
+}
+
+
+
+
+

Variables#

+
+

feeValueUpdateOffset#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
    uint256 feeValueUpdateOffset
+
+

Number of reward epochs that must elapse before an executor's fee change takes effect.

+
+
+
+

ftsoManager#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
    contract IFtsoManager ftsoManager
+
+

The FtsoManager contract.

+
+
+
+

governanceSettings#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    contract IGovernanceSettings governanceSettings
+
+

Governance Settings.

+
+
+
+

governanceVP#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
    contract IGovernanceVotePower governanceVP
+
+

The GovernanceVotePower contract.

+
+
+
+

libraryAddress#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
    address libraryAddress
+
+
+
+
+

maxFeeValueWei#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
    uint256 maxFeeValueWei
+
+

Maximum allowed value for an executor's fee.

+
+
+
+

minFeeValueWei#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
    uint256 minFeeValueWei
+
+

Minimum allowed value for an executor's fee.

+
+
+
+

productionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    bool productionMode
+
+

When true, governance is enabled and cannot be disabled. See switchToProductionMode.

+
+
+
+

registerExecutorFeeValueWei#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
    uint256 registerExecutorFeeValueWei
+
+

Fee that must be paid to register an executor.

+
+
+
+

timelockedCalls#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    mapping(bytes4 => struct GovernedBase.TimelockedCall) timelockedCalls
+
+

List of pending timelocked governance calls.

+
+
+
+

wNat#

+
+

Defined in ClaimSetupManager (Docs, Source).

+
+
+
    contract WNat wNat
+
+

The WNat contract.

+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/CleanupBlockNumberManager/index.html b/apis/smart-contracts/CleanupBlockNumberManager/index.html new file mode 100644 index 000000000..0a9764261 --- /dev/null +++ b/apis/smart-contracts/CleanupBlockNumberManager/index.html @@ -0,0 +1,4878 @@ + + + + + + + + + + + + + + + + + + CleanupBlockNumberManager - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + +

CleanupBlockNumberManager#

+
+

Source | Inherits from Governed, AddressUpdatable

+
+
+

Token history cleanup manager.

+

Maintains the list of cleanable tokens for which history cleanup can be collectively executed.

+
+
+

Events#

+
+

CleanupBlockNumberSet#

+
+

Defined in CleanupBlockNumberManager (Docs, Source).

+
+
+
event CleanupBlockNumberSet(
+    contract IICleanable theContract,
+    uint256 blockNumber,
+    bool success
+)
+
+

Emitted when an attempt has been made to set the cleanup block number.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
theContractcontract IICleanableThe token contract address.
blockNumberuint256The block number being set.
successboolWhether it succeeded or not.
+
+
+
+

GovernanceCallTimelocked#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event GovernanceCallTimelocked(
+    bytes4 selector,
+    uint256 allowedAfterTimestamp,
+    bytes encodedCall
+)
+
+

Emitted when a new governance call has been recorded and is now waiting for the time lock to expire.

+
+
+
+

GovernanceInitialised#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event GovernanceInitialised(
+    address initialGovernance
+)
+
+

Emitted when the governance address is initialized. +This address will be used until production mode is entered (see GovernedProductionModeEntered). +At that point the governance address is taken from GovernanceSettings.

+
+
+
+

GovernedProductionModeEntered#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event GovernedProductionModeEntered(
+    address governanceSettings
+)
+
+

Emitted when governance is enabled and the governance address cannot be changed anymore +(only through a network fork).

+
+
+
+

RegistrationUpdated#

+
+

Defined in CleanupBlockNumberManager (Docs, Source).

+
+
+
event RegistrationUpdated(
+    contract IICleanable theContract,
+    bool add
+)
+
+

Emitted when a new token has been registered to have its history managed by us, or +an old one unregistered.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
theContractcontract IICleanableThe token contract address.
addbooltrue is the token has been registered, false if unregistered.
+
+
+
+

TimelockedGovernanceCallCanceled#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event TimelockedGovernanceCallCanceled(
+    bytes4 selector,
+    uint256 timestamp
+)
+
+

Emitted when a timelocked governance call is canceled before execution.

+
+
+
+

TimelockedGovernanceCallExecuted#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event TimelockedGovernanceCallExecuted(
+    bytes4 selector,
+    uint256 timestamp
+)
+
+

Emitted when a timelocked governance call is executed.

+
+
+
+
+

Functions#

+
+

cancelGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function cancelGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Cancel a timelocked governance call before it has been executed.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector.
+
+
+
+

constructor#

+
+

Defined in CleanupBlockNumberManager (Docs, Source).

+
+
+
constructor(
+    address _governance,
+    address _addressUpdater,
+    string _triggerContractName
+) public;
+
+

Build a new instance.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_governanceaddressContract address that can make governance calls. See Governed.
_addressUpdateraddressContract address that can update redeployable addresses. See AdressUpdatable.
_triggerContractNamestringContract name that can trigger history cleanups.
+
+
+
+

executeGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function executeGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Execute the timelocked governance calls once the timelock period expires.

+

Only executor can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector (only one timelocked call per method is stored).
+
+
+
+

getAddressUpdater#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
function getAddressUpdater(
+) public view returns (
+    address _addressUpdater);
+
+

Returns the configured address updater.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_addressUpdateraddressThe AddresUpdater contract that can update our contract address list, as a response to a governance call.
+
+
+
+

governance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function governance(
+) public view returns (
+    address);
+
+

Returns the current effective governance address.

+
+
+
+

registerToken#

+
+

Defined in CleanupBlockNumberManager (Docs, Source).

+
+
+
function registerToken(
+    contract IICleanable _cleanableToken
+) external;
+
+

Register a token contract whose history cleanup index is to be managed. +The registered contracts must allow calling setCleanupBlockNumber.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_cleanableTokencontract IICleanableThe address of the contract to be managed.
+
+
+
+

setCleanUpBlockNumber#

+
+

Defined in CleanupBlockNumberManager (Docs, Source).

+
+
+
function setCleanUpBlockNumber(
+    uint256 _blockNumber
+) external;
+
+

Sets clean up block number on managed cleanable tokens.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockNumberuint256cleanup block number
+
+
+
+

switchToProductionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function switchToProductionMode(
+) external;
+
+

Enter the production mode after all the initial governance settings have been set. +This enables timelocks and the governance can be obtained afterward by calling +governanceSettings.getGovernanceAddress(). +Emits GovernedProductionModeEntered.

+
+
+
+

unregisterToken#

+
+

Defined in CleanupBlockNumberManager (Docs, Source).

+
+
+
function unregisterToken(
+    contract IICleanable _cleanableToken
+) external;
+
+

Unregister a token contract from history cleanup index management.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_cleanableTokencontract IICleanableThe address of the contract to unregister.
+
+
+
+

updateContractAddresses#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
function updateContractAddresses(
+    bytes32[] _contractNameHashes,
+    address[] _contractAddresses
+) external;
+
+

External method called from AddressUpdater only.

+
+
+
+
+

Modifiers#

+
+

onlyAddressUpdater#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
modifier onlyAddressUpdater()
+
+

Only the AdressUpdater contract can call this method. +Its address is set at construction time but it can also update itself.

+
+
+
+

onlyGovernance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
modifier onlyGovernance()
+
+
+
+
+

onlyImmediateGovernance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
modifier onlyImmediateGovernance()
+
+
+
+
+

onlyTrigger#

+
+

Defined in CleanupBlockNumberManager (Docs, Source).

+
+
+
modifier onlyTrigger()
+
+

Only the trigger contract can call this method. +This contract is set at construction time and updated through AddressUpdatable.

+
+
+
+
+

Variables#

+
+

governanceSettings#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    contract IGovernanceSettings governanceSettings
+
+

Governance Settings.

+
+
+
+

productionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    bool productionMode
+
+

When true, governance is enabled and cannot be disabled. See switchToProductionMode.

+
+
+
+

registeredTokens#

+
+

Defined in CleanupBlockNumberManager (Docs, Source).

+
+
+
    contract IICleanable[] registeredTokens
+
+

Current list of token contracts being managed.

+
+
+
+

timelockedCalls#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    mapping(bytes4 => struct GovernedBase.TimelockedCall) timelockedCalls
+
+

List of pending timelocked governance calls.

+
+
+
+

triggerContract#

+
+

Defined in CleanupBlockNumberManager (Docs, Source).

+
+
+
    address triggerContract
+
+

Address of the contract that can trigger a cleanup.

+
+
+
+

triggerContractName#

+
+

Defined in CleanupBlockNumberManager (Docs, Source).

+
+
+
    string triggerContractName
+
+

Name of the contract that can trigger a cleanup. +Needed to update the trigger contract address through the AddressUpdater.

+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/CloneFactory/index.html b/apis/smart-contracts/CloneFactory/index.html new file mode 100644 index 000000000..e9d2eeda3 --- /dev/null +++ b/apis/smart-contracts/CloneFactory/index.html @@ -0,0 +1,3884 @@ + + + + + + + + + + + + + + + + + + CloneFactory - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

CloneFactory#

+
+

Source

+
+
+

Simple clone contract factory.

+

This code (intended to be called from an implementor factory contract) will allow you to install a master copy of a +contract, then easily (cheaply) create clones with separate state. +The deployed bytecode just delegates all calls to the master contract address.

+

Source attribution.

+
+
+

Functions#

+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/Delegatable/index.html b/apis/smart-contracts/Delegatable/index.html new file mode 100644 index 000000000..5503dad4d --- /dev/null +++ b/apis/smart-contracts/Delegatable/index.html @@ -0,0 +1,4658 @@ + + + + + + + + + + + + + + + + + + Delegatable - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

Delegatable#

+
+

Source | Inherits from IVPContractEvents

+
+
+

Delegatable ERC20 behavior.

+

Adds delegation capabilities to tokens. This contract orchestrates interaction between +managing a delegation and the vote power allocations that result.

+
+
+

Enums#

+
+

DelegationMode#

+
+

Defined in Delegatable (Docs, Source).

+
+
+
enum DelegationMode {
+  NOTSET,
+  PERCENTAGE,
+  AMOUNT
+}
+
+

Delegation mode of an account. Once set, it cannot be changed.

+
    +
  • NOTSET: Delegation mode not set yet.
  • +
  • PERCENTAGE: Delegation by percentage.
  • +
  • AMOUNT: Delegation by amount (explicit).
  • +
+
+
+
+

Events#

+
+

CreatedVotePowerCache#

+
+

Defined in Delegatable (Docs, Source).

+
+
+
event CreatedVotePowerCache(
+    address _owner,
+    uint256 _blockNumber
+)
+
+

Emitted when a vote power cache entry is created. +Allows history cleaners to track vote power cache cleanup opportunities off-chain.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address whose vote power has just been cached.
_blockNumberuint256The block number at which the vote power has been cached.
+
+
+
+

Delegate#

+
+

Defined in IVPContractEvents (Docs, Source).

+
+
+
event Delegate(
+    address from,
+    address to,
+    uint256 priorVotePower,
+    uint256 newVotePower
+)
+
+

Emitted when the amount of vote power delegated from one account to another changes.

+

Note: This event is always emitted from VPToken's writeVotePowerContract.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
fromaddressThe account that has changed the amount of vote power it is delegating.
toaddressThe account whose received vote power has changed.
priorVotePoweruint256The vote power originally delegated.
newVotePoweruint256The new vote power that triggered this event. It can be 0 if the delegation is completely canceled.
+
+
+
+

Revoke#

+
+

Defined in IVPContractEvents (Docs, Source).

+
+
+
event Revoke(
+    address delegator,
+    address delegatee,
+    uint256 votePower,
+    uint256 blockNumber
+)
+
+

Emitted when an account revokes its vote power delegation to another account +for a single current or past block (typically the current vote block).

+

Note: This event is always emitted from VPToken's writeVotePowerContract or readVotePowerContract.

+

See revokeDelegationAt in IVPToken.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
delegatoraddressThe account that revoked the delegation.
delegateeaddressThe account that has been revoked.
votePoweruint256The revoked vote power.
blockNumberuint256The block number at which the delegation has been revoked.
+
+
+
+
+

Functions#

+
+

explicitDelegationHistoryCleanup#

+
+

Defined in Delegatable (Docs, Source).

+
+
+
function explicitDelegationHistoryCleanup(
+    address _from,
+    address _to,
+    uint256 _count
+) external returns (
+    uint256);
+
+

Delete explicit delegation checkpoints that expired (i.e. are before cleanupBlockNumber). +Method can only be called from the cleanerContract (which may be a proxy to external cleaners).

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressDelegator address.
_toaddressDelegatee address.
_countuint256Maximum number of checkpoints to delete.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Number of checkpoints deleted.
+
+
+
+

percentageDelegationHistoryCleanup#

+
+

Defined in Delegatable (Docs, Source).

+
+
+
function percentageDelegationHistoryCleanup(
+    address _owner,
+    uint256 _count
+) external returns (
+    uint256);
+
+

Delete percentage delegation checkpoints that expired (i.e. are before cleanupBlockNumber). +Method can only be called from the cleanerContract (which may be a proxy to external cleaners).

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressBalance owner account address.
_countuint256Maximum number of checkpoints to delete.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Number of deleted checkpoints.
+
+
+
+

revocationCleanup#

+
+

Defined in Delegatable (Docs, Source).

+
+
+
function revocationCleanup(
+    address _from,
+    address _to,
+    uint256 _blockNumber
+) external returns (
+    uint256);
+
+

Delete revocation entry that expired (i.e. is before cleanupBlockNumber). +Method can only be called from the cleanerContract (which may be a proxy to external cleaners).

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressDelegator address.
_toaddressDelegatee address.
_blockNumberuint256Block number for which total supply value was cached.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Number of revocation entries deleted (always 0 or 1).
+
+
+
+

votePowerCacheCleanup#

+
+

Defined in Delegatable (Docs, Source).

+
+
+
function votePowerCacheCleanup(
+    address _owner,
+    uint256 _blockNumber
+) external returns (
+    uint256);
+
+

Delete vote power cache entry that expired (i.e. is before cleanupBlockNumber). +Method can only be called from the cleanerContract (which may be a proxy to external cleaners).

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressVote power owner account address.
_blockNumberuint256Block number for which total supply value was cached.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Number of deleted cache entries (always 0 or 1).
+
+
+
+

votePowerHistoryCleanup#

+
+

Defined in Delegatable (Docs, Source).

+
+
+
function votePowerHistoryCleanup(
+    address _owner,
+    uint256 _count
+) external returns (
+    uint256);
+
+

Delete vote power checkpoints that expired (i.e. are before cleanupBlockNumber). +Method can only be called from the cleanerContract (which may be a proxy to external cleaners).

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressVote power owner account address.
_countuint256Maximum number of checkpoints to delete.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Number of deleted checkpoints.
+
+
+
+
+

Modifiers#

+
+

notBeforeCleanupBlock#

+
+

Defined in Delegatable (Docs, Source).

+
+
+
modifier notBeforeCleanupBlock(    uint256 _blockNumber)
+
+

Reading from history is not allowed before cleanupBlockNumber, since data before that +might have been deleted and is thus unreliable.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockNumberuint256The block number being checked for validity.
+
+
+
+

onlyCleaner#

+
+

Defined in Delegatable (Docs, Source).

+
+
+
modifier onlyCleaner()
+
+

History cleaning methods can be called only from cleanerContract.

+
+
+
+
+

Variables#

+
+

cleanerContract#

+
+

Defined in Delegatable (Docs, Source).

+
+
+
    address cleanerContract
+
+

Address of the contract that is allowed to call methods for history cleaning.

+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/FlareContractRegistry/index.html b/apis/smart-contracts/FlareContractRegistry/index.html new file mode 100644 index 000000000..f6456953f --- /dev/null +++ b/apis/smart-contracts/FlareContractRegistry/index.html @@ -0,0 +1,4279 @@ + + + + + + + + + + + + + + + + + + FlareContractRegistry - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+ +
+
+ + +
+
+ + + + + + + + + + + + +

FlareContractRegistry#

+ +
+

The Flare contract registry.

+

Entry point for all external dapps that need the latest contract addresses deployed by Flare.

+
+
+

Functions#

+
+

constructor#

+
+

Defined in FlareContractRegistry (Docs, Source).

+
+
+
constructor(
+    address _addressUpdater
+) public;
+
+
+
+
+

getAddressUpdater#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
function getAddressUpdater(
+) public view returns (
+    address _addressUpdater);
+
+

Returns the configured address updater.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_addressUpdateraddressThe AddresUpdater contract that can update our contract address list, as a response to a governance call.
+
+
+
+

getAllContracts#

+
+

Defined in FlareContractRegistry (Docs, Source).

+
+
+
function getAllContracts(
+) external view returns (
+    string[] _names,
+    address[] _addresses);
+
+

Returns all contract names and their corresponding addresses.

+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_namesstring[]Array of contract names.
_addressesaddress[]Array of corresponding contract addresses.
+
+
+
+

getContractAddressByHash#

+
+

Defined in FlareContractRegistry (Docs, Source).

+
+
+
function getContractAddressByHash(
+    bytes32 _nameHash
+) external view returns (
+    address);
+
+

Returns the address of a given contract hash.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_nameHashbytes32Hash of the contract name as: keccak256(abi.encode(name)).
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]addressAddress of the contract, or address(0) if not found.
+
+
+
+

getContractAddressByName#

+
+

Defined in FlareContractRegistry (Docs, Source).

+
+
+
function getContractAddressByName(
+    string _name
+) external view returns (
+    address);
+
+

Returns the address of a given contract name.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_namestringName of the contract.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]addressAddress of the contract, or address(0) if not found.
+
+
+
+

getContractAddressesByHash#

+
+

Defined in FlareContractRegistry (Docs, Source).

+
+
+
function getContractAddressesByHash(
+    bytes32[] _nameHashes
+) external view returns (
+    address[]);
+
+

Returns the addresses of a list of contract hashes.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_nameHashesbytes32[]Array of contract name hashes as: keccak256(abi.encode(name)).
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]address[]Array of addresses of the contracts. Any of them might be address(0) if not found.
+
+
+
+

getContractAddressesByName#

+
+

Defined in FlareContractRegistry (Docs, Source).

+
+
+
function getContractAddressesByName(
+    string[] _names
+) external view returns (
+    address[]);
+
+

Returns the addresses of a list of contract names.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_namesstring[]Array of contract names.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]address[]Array of addresses of the contracts. Any of them might be address(0) if not found.
+
+
+
+

updateContractAddresses#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
function updateContractAddresses(
+    bytes32[] _contractNameHashes,
+    address[] _contractAddresses
+) external;
+
+

External method called from AddressUpdater only.

+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/FlareDaemon/index.html b/apis/smart-contracts/FlareDaemon/index.html new file mode 100644 index 000000000..0836c39be --- /dev/null +++ b/apis/smart-contracts/FlareDaemon/index.html @@ -0,0 +1,5710 @@ + + + + + + + + + + + + + + + + + + FlareDaemon - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

FlareDaemon#

+ +
+

Flare Daemon contract.

+

This contract exists to coordinate regular daemon-like polling of contracts +that are registered to receive said polling. The trigger method is called by the +validator right at the end of block state transition.

+
+
+

Events#

+
+

ContractDaemonizeErrored#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
event ContractDaemonizeErrored(
+    address theContract,
+    uint256 atBlock,
+    string theMessage,
+    uint256 gasConsumed
+)
+
+
+
+
+

ContractDaemonized#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
event ContractDaemonized(
+    address theContract,
+    uint256 gasConsumed
+)
+
+
+
+
+

ContractHeldOff#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
event ContractHeldOff(
+    address theContract,
+    uint256 blockHoldoffsRemaining
+)
+
+
+
+
+

ContractsSkippedOutOfGas#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
event ContractsSkippedOutOfGas(
+    uint256 numberOfSkippedConstracts
+)
+
+
+
+
+

GovernanceCallTimelocked#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event GovernanceCallTimelocked(
+    bytes4 selector,
+    uint256 allowedAfterTimestamp,
+    bytes encodedCall
+)
+
+

Emitted when a new governance call has been recorded and is now waiting for the time lock to expire.

+
+
+
+

GovernanceInitialised#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event GovernanceInitialised(
+    address initialGovernance
+)
+
+

Emitted when the governance address is initialized. +This address will be used until production mode is entered (see GovernedProductionModeEntered). +At that point the governance address is taken from GovernanceSettings.

+
+
+
+

GovernedProductionModeEntered#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event GovernedProductionModeEntered(
+    address governanceSettings
+)
+
+

Emitted when governance is enabled and the governance address cannot be changed anymore +(only through a network fork).

+
+
+
+

InflationSet#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
event InflationSet(
+    contract IInflationGenesis theNewContract,
+    contract IInflationGenesis theOldContract
+)
+
+
+
+
+

MintingReceived#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
event MintingReceived(
+    uint256 amountWei
+)
+
+
+
+
+

MintingRequestReceived#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
event MintingRequestReceived(
+    uint256 amountWei
+)
+
+
+
+
+

MintingRequestTriggered#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
event MintingRequestTriggered(
+    uint256 amountWei
+)
+
+
+
+
+

MintingWithdrawn#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
event MintingWithdrawn(
+    uint256 amountWei
+)
+
+
+
+
+

RegistrationUpdated#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
event RegistrationUpdated(
+    contract IFlareDaemonize theContract,
+    bool add
+)
+
+
+
+
+

SelfDestructReceived#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
event SelfDestructReceived(
+    uint256 amountWei
+)
+
+
+
+
+

TimelockedGovernanceCallCanceled#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event TimelockedGovernanceCallCanceled(
+    bytes4 selector,
+    uint256 timestamp
+)
+
+

Emitted when a timelocked governance call is canceled before execution.

+
+
+
+

TimelockedGovernanceCallExecuted#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event TimelockedGovernanceCallExecuted(
+    bytes4 selector,
+    uint256 timestamp
+)
+
+

Emitted when a timelocked governance call is executed.

+
+
+
+
+

Functions#

+
+

cancelGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function cancelGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Cancel a timelocked governance call before it has been executed.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector.
+
+
+
+

constructor#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
constructor(
+) public;
+
+

This constructor should contain no code as this contract is pre-loaded into the genesis block. + The super constructor is called for testing convenience.

+
+
+
+

executeGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function executeGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Execute the timelocked governance calls once the timelock period expires.

+

Only executor can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector (only one timelocked call per method is stored).
+
+
+
+

getAddressUpdater#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
function getAddressUpdater(
+) public view returns (
+    address _addressUpdater);
+
+

Returns the configured address updater.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_addressUpdateraddressThe AddresUpdater contract that can update our contract address list, as a response to a governance call.
+
+
+
+

getDaemonizedContractsData#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
function getDaemonizedContractsData(
+) external view returns (
+    contract IFlareDaemonize[] _daemonizeContracts,
+    uint256[] _gasLimits,
+    uint256[] _blockHoldoffsRemaining);
+
+
+
+
+

getNextMintRequestAllowedTs#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
function getNextMintRequestAllowedTs(
+) external view returns (
+    uint256);
+
+
+
+
+

governance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function governance(
+) public view returns (
+    address);
+
+

Returns the current effective governance address.

+
+
+
+

initialise#

+
+

Defined in GovernedAtGenesis (Docs, Source).

+
+
+
function initialise(
+    address _governance
+) public pure;
+
+

Disallow initialise to be called.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_governanceaddressThe governance address for initial claiming.
+
+
+
+

initialiseFixedAddress#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
function initialiseFixedAddress(
+) public returns (
+    address);
+
+

Set the governance address to a hard-coded known address.

+

This should be done at contract deployment time.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]addressThe governance address.
+
+
+
+

registerToDaemonize#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
function registerToDaemonize(
+    struct FlareDaemon.Registration[] _registrations
+) external;
+
+

Register contracts to be polled by the daemon process.

+

A gas limit of zero will set no limit for the contract but the validator has an overall + limit for the trigger method. +If any registrations already exist, they will be unregistered. +Contracts will be daemonized in the order in which presented via the _registrations array.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_registrationsstruct FlareDaemon.Registration[]An array of Registration structures of IFlareDaemonize contracts to daemonize and gas limits for each contract.
+
+
+
+

requestMinting#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
function requestMinting(
+    uint256 _amountWei
+) external;
+
+

Queue up a minting request to send to the validator at next trigger.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_amountWeiuint256The amount to mint.
+
+
+
+

setAddressUpdater#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
function setAddressUpdater(
+    address _addressUpdater
+) external;
+
+

Sets the address udpater contract.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_addressUpdateraddressThe address updater contract.
+
+
+
+

setBlockHoldoff#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
function setBlockHoldoff(
+    uint256 _blockHoldoff
+) external;
+
+

Set number of blocks that must elapse before a daemonized contract exceeding gas limit can have + its daemonize() method called again.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockHoldoffuint256The number of blocks to holdoff.
+
+
+
+

setMaxMintingRequest#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
function setMaxMintingRequest(
+    uint256 _maxMintingRequestWei
+) external;
+
+

Set limit on how much can be minted per request. +this number can't be udated too often

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_maxMintingRequestWeiuint256The request maximum in wei.
+
+
+
+

showDaemonizedErrors#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
function showDaemonizedErrors(
+    uint256 startIndex,
+    uint256 numErrorTypesToShow
+) public view returns (
+    uint256[] _lastErrorBlock,
+    uint256[] _numErrors,
+    string[] _errorString,
+    address[] _erroringContract,
+    uint256 _totalDaemonizedErrors);
+
+
+
+
+

showLastDaemonizedError#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
function showLastDaemonizedError(
+) external view returns (
+    uint256[] _lastErrorBlock,
+    uint256[] _numErrors,
+    string[] _errorString,
+    address[] _erroringContract,
+    uint256 _totalDaemonizedErrors);
+
+
+
+
+

switchToProductionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function switchToProductionMode(
+) external;
+
+

Enter the production mode after all the initial governance settings have been set. +This enables timelocks and the governance can be obtained afterward by calling +governanceSettings.getGovernanceAddress(). +Emits GovernedProductionModeEntered.

+
+
+
+

updateContractAddresses#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
function updateContractAddresses(
+    bytes32[] _contractNameHashes,
+    address[] _contractAddresses
+) external;
+
+

External method called from AddressUpdater only.

+
+
+
+
+

Modifiers#

+
+

inflationSet#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
modifier inflationSet()
+
+

As there is not a constructor, this modifier exists to make sure the inflation + contract is set for methods that require it.

+
+
+
+

onlyAddressUpdater#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
modifier onlyAddressUpdater()
+
+

Only the AdressUpdater contract can call this method. +Its address is set at construction time but it can also update itself.

+
+
+
+

onlyGovernance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
modifier onlyGovernance()
+
+
+
+
+

onlyImmediateGovernance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
modifier onlyImmediateGovernance()
+
+
+
+
+

onlyInflation#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
modifier onlyInflation(    address _inflation)
+
+

Access control to protect methods to allow only minters to call select methods + (like transferring balance out).

+
+
+
+

onlySystemTrigger#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
modifier onlySystemTrigger()
+
+

Access control to protect trigger method. +Please note that the sender address is the same as deployed FlareDaemon address in this case.

+
+
+
+
+

Structures#

+
+

DaemonizedError#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
struct DaemonizedError {
+  uint192 lastErrorBlock;
+  uint64 numErrors;
+  address fromContract;
+  uint64 errorTypeIndex;
+  string errorMessage;
+}
+
+
+
+

LastErrorData#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
struct LastErrorData {
+  uint192 totalDaemonizedErrors;
+  uint64 lastErrorTypeIndex;
+}
+
+
+
+

Registration#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
struct Registration {
+  contract IFlareDaemonize daemonizedContract;
+  uint256 gasLimit;
+}
+
+
+
+

TimelockedCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
struct TimelockedCall {
+  uint256 allowedAfterTimestamp;
+  bytes encodedCall;
+}
+
+
+
+
+

Variables#

+
+

blockHoldoff#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
    uint256 blockHoldoff
+
+
+
+
+

errorData#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
    struct FlareDaemon.LastErrorData errorData
+
+
+
+
+

governanceSettings#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    contract IGovernanceSettings governanceSettings
+
+

Governance Settings.

+
+
+
+

inflation#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
    contract IInflationGenesis inflation
+
+
+
+
+

lastMintRequestTs#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
    uint256 lastMintRequestTs
+
+
+
+
+

lastUpdateMaxMintRequestTs#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
    uint256 lastUpdateMaxMintRequestTs
+
+
+
+
+

maxMintingRequestWei#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
    uint256 maxMintingRequestWei
+
+
+
+
+

productionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    bool productionMode
+
+

When true, governance is enabled and cannot be disabled. See switchToProductionMode.

+
+
+
+

systemLastTriggeredAt#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
    uint256 systemLastTriggeredAt
+
+
+
+
+

timelockedCalls#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    mapping(bytes4 => struct GovernedBase.TimelockedCall) timelockedCalls
+
+

List of pending timelocked governance calls.

+
+
+
+

totalMintingReceivedWei#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
    uint256 totalMintingReceivedWei
+
+
+
+
+

totalMintingRequestedWei#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
    uint256 totalMintingRequestedWei
+
+
+
+
+

totalMintingWithdrawnWei#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
    uint256 totalMintingWithdrawnWei
+
+
+
+
+

totalSelfDestructReceivedWei#

+
+

Defined in FlareDaemon (Docs, Source).

+
+
+
    uint256 totalSelfDestructReceivedWei
+
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/Ftso/index.html b/apis/smart-contracts/Ftso/index.html new file mode 100644 index 000000000..f11e45809 --- /dev/null +++ b/apis/smart-contracts/Ftso/index.html @@ -0,0 +1,6182 @@ + + + + + + + + + + + + + + + + + + Ftso - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

Ftso#

+
+

Source | Inherits from IIFtso

+
+
+

Flare Time Series Oracle contract.

+

An instance of this contract is created for each tracked asset, and typically +accessed through the FtsoRegistry. +Data providers do not access the Ftso instances directly either, and use the +PriceSubmitter contract instead.

+
+
+

Functions#

+
+

activateFtso#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function activateFtso(
+    uint256 _firstEpochStartTs,
+    uint256 _submitPeriodSeconds,
+    uint256 _revealPeriodSeconds
+) external;
+
+

Initializes FTSO immutable settings and activates the contract.

+

Can only be called by the ftsoManager.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_firstEpochStartTsuint256Timestamp of the first epoch in seconds from UNIX epoch.
_submitPeriodSecondsuint256Duration of epoch submission window in seconds.
_revealPeriodSecondsuint256Duration of epoch reveal window in seconds.
+
+
+
+

active#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function active(
+) external view returns (
+    bool);
+
+

Returns whether FTSO is active or not.

+
+
+
+

configureEpochs#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function configureEpochs(
+    uint256 _maxVotePowerNatThresholdFraction,
+    uint256 _maxVotePowerAssetThresholdFraction,
+    uint256 _lowAssetUSDThreshold,
+    uint256 _highAssetUSDThreshold,
+    uint256 _highAssetTurnoutThresholdBIPS,
+    uint256 _lowNatTurnoutThresholdBIPS,
+    uint256 _elasticBandRewardBIPS,
+    uint256 _elasticBandWidthPPM,
+    address[] _trustedAddresses
+) external;
+
+

Sets configurable settings related to epochs.

+

Can only be called by the ftsoManager. +Should never revert if called from ftsoManager.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_maxVotePowerNatThresholdFractionuint256High threshold for native token vote power per voter.
_maxVotePowerAssetThresholdFractionuint256High threshold for asset vote power per voter.
_lowAssetUSDThresholduint256Threshold for low asset vote power (in scaled USD).
_highAssetUSDThresholduint256Threshold for high asset vote power (in scaled USD).
_highAssetTurnoutThresholdBIPSuint256Threshold for high asset turnout (in BIPS).
_lowNatTurnoutThresholdBIPSuint256Threshold for low nat turnout (in BIPS).
_elasticBandRewardBIPSuint256Percentage of the rewards (in BIPS) that go to the secondary reward band. The rest go to the primary reward band.
_elasticBandWidthPPMuint256Width of the secondary reward band, in parts-per-milion of the median.
_trustedAddressesaddress[]Trusted voters that will be used if low voter turnout is detected.
+
+
+
+

constructor#

+
+

Defined in Ftso (Docs, Source).

+
+
+
constructor(
+    string _symbol,
+    uint256 _decimals,
+    contract IPriceSubmitter _priceSubmitter,
+    contract IIVPToken _wNat,
+    address _ftsoManager,
+    uint256 _firstEpochStartTs,
+    uint256 _submitPeriodSeconds,
+    uint256 _revealPeriodSeconds,
+    uint128 _initialPriceUSD,
+    uint256 _priceDeviationThresholdBIPS,
+    uint256 _cyclicBufferSize
+) public;
+
+
+
+
+

deactivateFtso#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function deactivateFtso(
+) external;
+
+

Deactivates the contract.

+

Can only be called by the ftsoManager.

+
+
+
+

epochsConfiguration#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function epochsConfiguration(
+) external view returns (
+    uint256 _maxVotePowerNatThresholdFraction,
+    uint256 _maxVotePowerAssetThresholdFraction,
+    uint256 _lowAssetUSDThreshold,
+    uint256 _highAssetUSDThreshold,
+    uint256 _highAssetTurnoutThresholdBIPS,
+    uint256 _lowNatTurnoutThresholdBIPS,
+    uint256 _elasticBandRewardBIPS,
+    uint256 _elasticBandWidthPPM,
+    address[] _trustedAddresses);
+
+

Returns current configuration of epoch state.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_maxVotePowerNatThresholdFractionuint256High threshold for native token vote power per voter.
_maxVotePowerAssetThresholdFractionuint256High threshold for asset vote power per voter.
_lowAssetUSDThresholduint256Threshold for low asset vote power (in scaled USD).
_highAssetUSDThresholduint256Threshold for high asset vote power (in scaled USD).
_highAssetTurnoutThresholdBIPSuint256Threshold for high asset turnout (in BIPS).
_lowNatTurnoutThresholdBIPSuint256Threshold for low nat turnout (in BIPS).
_elasticBandRewardBIPSuint256Percentage of the rewards (in BIPS) that go to the secondary reward band. The rest go to the primary reward band.
_elasticBandWidthPPMuint256Width of the secondary reward band, in parts-per-milion of the median.
_trustedAddressesaddress[]Trusted voters that will be used if low voter turnout is detected.
+
+
+
+

fallbackFinalizePriceEpoch#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function fallbackFinalizePriceEpoch(
+    uint256 _epochId
+) external;
+
+

Forces finalization of a price epoch, calculating the median price from trusted addresses only.

+

Used as a fallback method, for example, due to an unexpected error during normal epoch finalization or +because the ftsoManager enabled the fallback mode.

+

Can only be called by the ftsoManager.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_epochIduint256ID of the epoch to finalize.
+
+
+
+

finalizePriceEpoch#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function finalizePriceEpoch(
+    uint256 _epochId,
+    bool _returnRewardData
+) external returns (
+    address[] _eligibleAddresses,
+    uint256[] _natWeights,
+    uint256 _natWeightsSum);
+
+

Computes epoch price based on gathered votes.

+
    +
  • If the price reveal window for the epoch has ended, finalize the epoch.
  • +
  • Iterate list of price submissions.
  • +
  • Find weighted median.
  • +
  • Find adjacent 50% of price submissions.
  • +
  • Allocate rewards for price submissions.
  • +
+

Can only be called by the ftsoManager, and only at the correct time.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_epochIduint256ID of the epoch to finalize.
_returnRewardDataboolParameter that determines if the reward data is returned.
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_eligibleAddressesaddress[]List of addresses eligible for reward.
_natWeightsuint256[]List of native token weights corresponding to the eligible addresses.
_natWeightsSumuint256
+
+
+
+

forceFinalizePriceEpoch#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function forceFinalizePriceEpoch(
+    uint256 _epochId
+) external;
+
+

Forces finalization of a price epoch by copying the price from the previous epoch.

+

Used as a fallback method if fallbackFinalizePriceEpoch fails due to an exception.

+

Can only be called by the ftsoManager.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_epochIduint256ID of the epoch to finalize.
+
+
+
+

ftsoManager#

+
+

Defined in IIFtso (Docs, Source).

+
+
+
function ftsoManager(
+) external view returns (
+    address);
+
+

Returns the FTSO manager's address.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]addressAddress of the FTSO manager contract.
+
+
+
+

getAsset#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function getAsset(
+) external view returns (
+    contract IIVPToken);
+
+

Returns the FTSO asset.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]contract IIVPTokenAddress of the IIVPToken tracked by this FTSO. null in case of multi-asset FTSO.
+
+
+
+

getAssetFtsos#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function getAssetFtsos(
+) external view returns (
+    contract IIFtso[]);
+
+

Returns the asset FTSOs.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]contract IIFtso[]Array of IIFtso contract addresses. null in case of single-asset FTSO.
+
+
+
+

getCurrentEpochId#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function getCurrentEpochId(
+) public view returns (
+    uint256);
+
+

Returns the current epoch ID.

+

It never reverts.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Currently running epoch ID. IDs are consecutive numbers starting from zero.
+
+
+
+

getCurrentPrice#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function getCurrentPrice(
+) external view returns (
+    uint256 _price,
+    uint256 _timestamp);
+
+

Returns the current asset price.

+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Price in USD multiplied by 10^ASSET_PRICE_USD_DECIMALS.
_timestampuint256Time when price was updated for the last time, in seconds from UNIX epoch.
+
+
+
+

getCurrentPriceDetails#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function getCurrentPriceDetails(
+) external view returns (
+    uint256 _price,
+    uint256 _priceTimestamp,
+    enum IFtso.PriceFinalizationType _priceFinalizationType,
+    uint256 _lastPriceEpochFinalizationTimestamp,
+    enum IFtso.PriceFinalizationType _lastPriceEpochFinalizationType);
+
+

Returns asset's current price details. +All timestamps are in seconds from UNIX epoch.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Price in USD multiplied by 10^ASSET_PRICE_USD_DECIMALS.
_priceTimestampuint256Time when price was updated for the last time.
_priceFinalizationTypeenum IFtso.PriceFinalizationTypeFinalization type when price was updated for the last time.
_lastPriceEpochFinalizationTimestampuint256Time when last price epoch was finalized.
_lastPriceEpochFinalizationTypeenum IFtso.PriceFinalizationTypeFinalization type of last finalized price epoch.
+
+
+
+

getCurrentPriceFromTrustedProviders#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function getCurrentPriceFromTrustedProviders(
+) external view returns (
+    uint256 _price,
+    uint256 _timestamp);
+
+

Returns current asset price calculated only using input from trusted providers.

+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Price in USD multiplied by 10^ASSET_PRICE_USD_DECIMALS.
_timestampuint256Time when price was updated for the last time, in seconds from UNIX epoch.
+
+
+
+

getCurrentPriceWithDecimals#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function getCurrentPriceWithDecimals(
+) external view returns (
+    uint256 _price,
+    uint256 _timestamp,
+    uint256 _assetPriceUsdDecimals);
+
+

Returns current asset price and number of decimals.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Price in USD multiplied by 10^_assetPriceUsdDecimals.
_timestampuint256Time when price was updated for the last time, in seconds from UNIX epoch.
_assetPriceUsdDecimalsuint256Number of decimals used to return the USD price.
+
+
+
+

getCurrentPriceWithDecimalsFromTrustedProviders#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function getCurrentPriceWithDecimalsFromTrustedProviders(
+) external view returns (
+    uint256 _price,
+    uint256 _timestamp,
+    uint256 _assetPriceUsdDecimals);
+
+

Returns current asset price calculated only using input from trusted providers and number of decimals.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Price in USD multiplied by 10^ASSET_PRICE_USD_DECIMALS.
_timestampuint256Time when price was updated for the last time, in seconds from UNIX epoch.
_assetPriceUsdDecimalsuint256Number of decimals used to return the USD price.
+
+
+
+

getCurrentRandom#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function getCurrentRandom(
+) external view returns (
+    uint256);
+
+

Returns the random number for the previous price epoch, obtained from the random numbers +provided by all data providers along with their data submissions.

+

It never reverts.

+
+
+
+

getEpochId#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function getEpochId(
+    uint256 _timestamp
+) external view returns (
+    uint256);
+
+

Returns the ID of the epoch that was opened for price submission at the specified timestamp.

+

It never reverts.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_timestampuint256Queried timestamp in seconds from UNIX epoch.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Epoch ID corresponding to that timestamp. IDs are consecutive numbers starting from zero.
+
+
+
+

getEpochPrice#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function getEpochPrice(
+    uint256 _epochId
+) external view returns (
+    uint256);
+
+

Returns agreed asset price in the specified epoch.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_epochIduint256ID of the epoch. Only the last 200 epochs can be queried. Out-of-bounds queries revert.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Price in USD multiplied by 10^ASSET_PRICE_USD_DECIMALS.
+
+
+
+

getEpochPriceForVoter#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function getEpochPriceForVoter(
+    uint256 _epochId,
+    address _voter
+) external view returns (
+    uint256);
+
+

Returns asset price submitted by a voter in the specified epoch.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_epochIduint256ID of the epoch being queried. Only the last 200 epochs can be queried. Out-of-bounds queries revert.
_voteraddressAddress of the voter being queried.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Price in USD multiplied by 10^ASSET_PRICE_USD_DECIMALS.
+
+
+
+

getPriceEpochConfiguration#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function getPriceEpochConfiguration(
+) external view returns (
+    uint256 _firstEpochStartTs,
+    uint256 _submitPeriodSeconds,
+    uint256 _revealPeriodSeconds);
+
+

Returns current epoch's configuration.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_firstEpochStartTsuint256First epoch start timestamp in seconds from UNIX epoch.
_submitPeriodSecondsuint256Submit period in seconds.
_revealPeriodSecondsuint256Reveal period in seconds.
+
+
+
+

getPriceEpochData#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function getPriceEpochData(
+) external view returns (
+    uint256 _epochId,
+    uint256 _epochSubmitEndTime,
+    uint256 _epochRevealEndTime,
+    uint256 _votePowerBlock,
+    bool _fallbackMode);
+
+

Returns current epoch data. +Intervals are open on the right: End times are not included.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_epochIduint256Current epoch ID.
_epochSubmitEndTimeuint256End time of the price submission window in seconds from UNIX epoch.
_epochRevealEndTimeuint256End time of the price reveal window in seconds from UNIX epoch.
_votePowerBlockuint256Vote power block for the current epoch.
_fallbackModeboolWhether the current epoch is in fallback mode. Only votes from trusted addresses are used in this mode.
+
+
+
+

getRandom#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function getRandom(
+    uint256 _epochId
+) external view returns (
+    uint256);
+
+

Returns the random number used in a specific past epoch, obtained from the random numbers +provided by all data providers along with their data submissions.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_epochIduint256ID of the queried epoch. Current epoch cannot be queried, and the previous epoch is constantly updated as data providers reveal their prices and random numbers. Only the last 50 epochs can be queried and there is no bounds checking for this parameter. Out-of-bounds queries return undefined values.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The random number used in that epoch.
+
+
+
+

getVoteWeightingParameters#

+
+

Defined in IIFtso (Docs, Source).

+
+
+
function getVoteWeightingParameters(
+) external view returns (
+    contract IIVPToken[] _assets,
+    uint256[] _assetMultipliers,
+    uint256 _totalVotePowerNat,
+    uint256 _totalVotePowerAsset,
+    uint256 _assetWeightRatio,
+    uint256 _votePowerBlock);
+
+

Returns parameters necessary for replicating vote weighting (used in VoterWhitelister).

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_assetscontract IIVPToken[]The list of assets that are accounted in vote.
_assetMultipliersuint256[]Weight multiplier of each asset in (multiasset) FTSO.
_totalVotePowerNatuint256Total native token vote power at block.
_totalVotePowerAssetuint256Total combined asset vote power at block.
_assetWeightRatiouint256Ratio of combined asset vote power vs. native token vp (in BIPS).
_votePowerBlockuint256Vote power block for the epoch.
+
+
+
+

initializeCurrentEpochStateForReveal#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function initializeCurrentEpochStateForReveal(
+    uint256 _circulatingSupplyNat,
+    bool _fallbackMode
+) external;
+
+

Initializes current epoch instance for reveal.

+

Can only be called by the ftsoManager.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_circulatingSupplyNatuint256Epoch native token circulating supply.
_fallbackModeboolWhether the current epoch is in fallback mode.
+
+
+
+

revealPriceSubmitter#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function revealPriceSubmitter(
+    address _voter,
+    uint256 _epochId,
+    uint256 _price,
+    uint256 _voterWNatVP
+) external;
+
+

Reveals the price submitted by a voter on a specific epoch. +The hash of _price and _random must be equal to the submitted hash

+

Emits a PriceRevealed event. +Can only be called by the priceSubmitter.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_voteraddressVoter address.
_epochIduint256ID of the epoch in which the price hash was submitted.
_priceuint256Submitted price.
_voterWNatVPuint256Voter's vote power in WNat units.
+
+
+
+

setAsset#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function setAsset(
+    contract IIVPToken _asset
+) external;
+
+

Sets asset for FTSO to operate as single-asset oracle.

+

Can only be called by the ftsoManager.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_assetcontract IIVPTokenAddress of the IIVPToken contract that will be the asset tracked by this FTSO.
+
+
+
+

setAssetFtsos#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function setAssetFtsos(
+    contract IIFtso[] _assetFtsos
+) external;
+
+

Sets an array of FTSOs for FTSO to operate as multi-asset oracle. +FTSOs implicitly determine the FTSO assets.

+

Can only be called by the ftsoManager.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_assetFtsoscontract IIFtso[]Array of FTSOs.
+
+
+
+

setVotePowerBlock#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function setVotePowerBlock(
+    uint256 _votePowerBlock
+) external;
+
+

Sets the current vote power block. +Current vote power block will update per reward epoch. +The FTSO doesn't have notion of reward epochs.

+

Can only be called by the ftsoManager.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_votePowerBlockuint256
+
+
+
+

symbol#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function symbol(
+) external view returns (
+    string);
+
+

Returns the FTSO symbol.

+
+
+
+

updateInitialPrice#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function updateInitialPrice(
+    uint256 _initialPriceUSD,
+    uint256 _initialPriceTimestamp
+) external;
+
+

Updates initial asset price when the contract is not active yet.

+

Can only be called by the ftsoManager.

+
+
+
+

wNat#

+
+

Defined in IIFtso (Docs, Source).

+
+
+
function wNat(
+) external view returns (
+    contract IIVPToken);
+
+

Address of the WNat contract.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]contract IIVPTokenAddress of the WNat contract.
+
+
+
+

wNatVotePowerCached#

+
+

Defined in Ftso (Docs, Source).

+
+
+
function wNatVotePowerCached(
+    address _owner,
+    uint256 _epochId
+) public returns (
+    uint256);
+
+

Get and cache the vote power of a voter on a specific epoch, in WNat units.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddress
_epochIduint256ID of the epoch in which the price hash was submitted.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Voter's vote power in WNat units.
+
+
+
+
+

Modifiers#

+
+

onlyFtsoManager#

+
+

Defined in Ftso (Docs, Source).

+
+
+
modifier onlyFtsoManager()
+
+

Only the ftsoManager can call this method.

+
+
+
+

onlyPriceSubmitter#

+
+

Defined in Ftso (Docs, Source).

+
+
+
modifier onlyPriceSubmitter()
+
+

Only the priceSubmitter can call this method.

+
+
+
+

whenActive#

+
+

Defined in Ftso (Docs, Source).

+
+
+
modifier whenActive()
+
+

This method can only be called when the FTSO is active.

+
+
+
+
+

Structures#

+
+

RewardData#

+
+

Defined in Ftso (Docs, Source).

+
+
+
struct RewardData {
+  uint256[] weightIQR;
+  uint256[] weightElasticBand;
+  uint256 weightsIQRSum;
+  uint256 weightsElasticBandSum;
+  uint256 numberOfVotes;
+  uint256 elasticBandRewardBIPS;
+}
+
+
+
+
+

Variables#

+
+

ASSET_PRICE_USD_DECIMALS#

+
+

Defined in Ftso (Docs, Source).

+
+
+
    uint256 ASSET_PRICE_USD_DECIMALS
+
+

Number of decimal places in an asset's USD price. +Actual USD price is the integer value divided by 10^ASSET_PRICE_USD_DECIMALS

+
+
+
+

active#

+
+

Defined in Ftso (Docs, Source).

+
+
+
    bool active
+
+

Activation status of this FTSO.

+
+
+
+

assetFtsos#

+
+

Defined in Ftso (Docs, Source).

+
+
+
    contract IIFtso[] assetFtsos
+
+

Array of addresses of other Ftso contracts tracked by this multi-asset FTSO.

+
+
+
+

assets#

+
+

Defined in Ftso (Docs, Source).

+
+
+
    contract IIVPToken[] assets
+
+

Array of addresses of the tracked assets.

+
+
+
+

ftsoManager#

+
+

Defined in Ftso (Docs, Source).

+
+
+
    address ftsoManager
+
+

Address of the FtsoManager contract.

+
+
+
+

priceDeviationThresholdBIPS#

+
+

Defined in Ftso (Docs, Source).

+
+
+
    uint256 priceDeviationThresholdBIPS
+
+

Threshold for price deviation between consecutive epochs.

+
+
+
+

priceEpochCyclicBufferSize#

+
+

Defined in Ftso (Docs, Source).

+
+
+
    uint256 priceEpochCyclicBufferSize
+
+

Amount of stored prices for past epochs, set at construction time.

+
+
+
+

priceSubmitter#

+
+

Defined in Ftso (Docs, Source).

+
+
+
    contract IPriceSubmitter priceSubmitter
+
+

Address of the PriceSubmitter contract.

+
+
+
+

symbol#

+
+

Defined in Ftso (Docs, Source).

+
+
+
    string symbol
+
+

Asset symbol that identifies this FTSO.

+
+
+
+

wNat#

+
+

Defined in Ftso (Docs, Source).

+
+
+
    contract IIVPToken wNat
+
+

Address of the wrapped native token (WNat) contract.

+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/FtsoManager/index.html b/apis/smart-contracts/FtsoManager/index.html new file mode 100644 index 000000000..89d8318df --- /dev/null +++ b/apis/smart-contracts/FtsoManager/index.html @@ -0,0 +1,7125 @@ + + + + + + + + + + + + + + + + + + FtsoManager - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

FtsoManager#

+ +
+

FTSO Manager contract.

+

It is in charge of:

+
    +
  • Defining reward epochs (few days).
  • +
  • Choosing a single block each reward epoch that represents vote power of this epoch.
  • +
  • Keeping track of all FTSO contracts.
  • +
  • Every price epoch (few minutes):
      +
    • Randomly choose one FTSO for rewarding calculations.
    • +
    • Trigger finalize price reveal epoch.
    • +
    • Determine addresses and reward weights and triggers reward distribution.
    • +
    +
  • +
+
+
+

Functions#

+
+

activate#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function activate(
+) external;
+
+

Activates FTSO manager (daemonize will run jobs).

+

Only governance can call this method.

+
+
+
+

active#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
function active(
+) external view returns (
+    bool);
+
+

Returns whether the FTSO Manager is active or not.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]boolbool Active status.
+
+
+
+

addFtso#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function addFtso(
+    contract IIFtso _ftso
+) external;
+
+

Adds FTSO to the list of managed FTSOs, to support a new price pair. +All FTSOs in a multi-asset FTSO must be managed by the same FTSO manager.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsocontract IIFtsoFTSO contract address to add.
+
+
+
+

addFtsosBulk#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function addFtsosBulk(
+    contract IIFtso[] _ftsos
+) external;
+
+

Adds a list of FTSOs to the list of managed FTSOs, to support new price pairs. +All FTSOs in a multi-asset FTSO must be managed by the same FTSO manager.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsoscontract IIFtso[]Array of FTSO contract addresses to add.
+
+
+
+

cancelGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function cancelGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Cancel a timelocked governance call before it has been executed.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector.
+
+
+
+

constructor#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
constructor(
+    address _governance,
+    contract FlareDaemon _flareDaemon,
+    address _addressUpdater,
+    contract IIFtsoManagerV1 _oldFtsoManager,
+    uint256 _firstPriceEpochStartTs,
+    uint256 _priceEpochDurationSeconds,
+    uint256 _revealEpochDurationSeconds,
+    uint256 _firstRewardEpochStartTs,
+    uint256 _rewardEpochDurationSeconds,
+    uint256 _votePowerIntervalFraction
+) public;
+
+
+
+
+

constructor#

+
+

Defined in GovernedAndFlareDaemonized (Docs, Source).

+
+
+
constructor(
+    address _governance,
+    contract FlareDaemon _flareDaemon
+) public;
+
+
+
+
+

constructor#

+
+

Defined in Governed (Docs, Source).

+
+
+
constructor(
+    address _governance
+) public;
+
+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_governanceaddressGovernance contract. Must not be zero.
+
+
+
+

currentRewardEpochEnds#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
function currentRewardEpochEnds(
+) external view returns (
+    uint256);
+
+

Returns when the current reward epoch finishes.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256uint256 Time in seconds since the UNIX epoch when the current reward epoch will finish.
+
+
+
+

daemonize#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function daemonize(
+) external returns (
+    bool);
+
+

Implement this function to receive a trigger from the FlareDaemon. +The trigger method is called by the validator right at the end of block state transition.

+

Only flareDaemon can call this method.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]boolbool Whether the contract is still active after the call. Currently unused.
+
+
+
+

deactivateFtsos#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function deactivateFtsos(
+    contract IIFtso[] _ftsos
+) external;
+
+

Deactivates FTSOs that are no longer used on FTSO registry. +Only governance can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsoscontract IIFtso[]Array of FTSO contract addresses to deactivate.
+
+
+
+

executeGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function executeGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Execute the timelocked governance calls once the timelock period expires.

+

Only executor can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector (only one timelocked call per method is stored).
+
+
+
+

ftsoRegistry#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function ftsoRegistry(
+) external view returns (
+    contract IIFtsoRegistry);
+
+

Returns the FtsoRegistry contract address.

+
+
+
+

getAddressUpdater#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
function getAddressUpdater(
+) public view returns (
+    address _addressUpdater);
+
+

Returns the configured address updater.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_addressUpdateraddressThe AddresUpdater contract that can update our contract address list, as a response to a governance call.
+
+
+
+

getContractName#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function getContractName(
+) external pure returns (
+    string);
+
+

Implement this function to allow updating daemonized contracts through the AddressUpdater.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]stringstring Contract name.
+
+
+
+

getCurrentPriceEpochData#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function getCurrentPriceEpochData(
+) external view returns (
+    uint256 _priceEpochId,
+    uint256 _priceEpochStartTimestamp,
+    uint256 _priceEpochEndTimestamp,
+    uint256 _priceEpochRevealEndTimestamp,
+    uint256 _currentTimestamp);
+
+

Returns timing information for the current price epoch. +All intervals are half-closed: end time is not included. +All timestamps are in seconds since UNIX epoch.

+

See the FTSO page +for information about the different submission phases.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceEpochIduint256Price epoch ID.
_priceEpochStartTimestampuint256Beginning of the commit phase.
_priceEpochEndTimestampuint256End of the commit phase.
_priceEpochRevealEndTimestampuint256End of the reveal phase.
_currentTimestampuint256Current time.
+
+
+
+

getCurrentPriceEpochId#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function getCurrentPriceEpochId(
+) external view returns (
+    uint256 _priceEpochId);
+
+

Returns current price epoch ID.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceEpochIduint256Currently running epoch ID. IDs are consecutive numbers starting from zero.
+
+
+
+

getCurrentRewardEpoch#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function getCurrentRewardEpoch(
+) external view returns (
+    uint256);
+
+

Returns current reward epoch ID (the one currently running).

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Reward epoch ID. A monotonically increasing integer.
+
+
+
+

getElasticBandWidthPPMFtso#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function getElasticBandWidthPPMFtso(
+    contract IIFtso _ftso
+) external view returns (
+    uint256);
+
+

Returns the secondary band's width in PPM (parts-per-million) of the median value, +for a given FTSO.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsocontract IIFtsoThe queried FTSO contract address.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256uint256 Secondary band width in PPM. To obtain the actual band width, divide this number by 10^6 and multiply by the price median value.
+
+
+
+

getFallbackMode#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function getFallbackMode(
+) external view returns (
+    bool _fallbackMode,
+    contract IIFtso[] _ftsos,
+    bool[] _ftsoInFallbackMode);
+
+

Returns whether the FTSO Manager is currently in fallback mode.

+

In this mode only submissions from trusted providers are used.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_fallbackModeboolTrue if fallback mode is enabled for the manager.
_ftsoscontract IIFtso[]Array of all currently active FTSO assets.
_ftsoInFallbackModebool[]Boolean array indicating which FTSO assets are in fallback mode. If the FTSO Manager is in fallback mode then ALL FTSOs are in fallback mode.
+
+
+
+

getFtsos#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function getFtsos(
+) external view returns (
+    contract IIFtso[] _ftsos);
+
+

Returns the list of currently active FTSOs.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_ftsoscontract IIFtso[]Array of contract addresses for the FTSOs.
+
+
+
+

getGovernanceParameters#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function getGovernanceParameters(
+) external view returns (
+    uint256 _maxVotePowerNatThresholdFraction,
+    uint256 _maxVotePowerAssetThresholdFraction,
+    uint256 _lowAssetUSDThreshold,
+    uint256 _highAssetUSDThreshold,
+    uint256 _highAssetTurnoutThresholdBIPS,
+    uint256 _lowNatTurnoutThresholdBIPS,
+    uint256 _elasticBandRewardBIPS,
+    uint256 _rewardExpiryOffsetSeconds,
+    address[] _trustedAddresses,
+    bool _initialized,
+    bool _changed);
+
+

Returns governance parameters for FTSOs.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_maxVotePowerNatThresholdFractionuint256High threshold for native token vote power per voter.
_maxVotePowerAssetThresholdFractionuint256High threshold for asset vote power per voter
_lowAssetUSDThresholduint256Threshold for low asset vote power (in scaled USD).
_highAssetUSDThresholduint256Threshold for high asset vote power (in scaled USD).
_highAssetTurnoutThresholdBIPSuint256Threshold for high asset turnout (in BIPS).
_lowNatTurnoutThresholdBIPSuint256Threshold for low nat turnout (in BIPS).
_elasticBandRewardBIPSuint256Secondary reward band, where _elasticBandRewardBIPS goes to the secondary band and 10000 - _elasticBandRewardBIPS to the primary (IQR) band.
_rewardExpiryOffsetSecondsuint256Reward epochs closed earlier than block.timestamp - _rewardExpiryOffsetSeconds expire.
_trustedAddressesaddress[]Trusted addresses will be used as a fallback mechanism for setting the price.
_initializedbool
_changedbool
+
+
+
+

getLastUnprocessedPriceEpochData#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function getLastUnprocessedPriceEpochData(
+) external view returns (
+    uint256 _lastUnprocessedPriceEpoch,
+    uint256 _lastUnprocessedPriceEpochRevealEnds,
+    bool _lastUnprocessedPriceEpochInitialized);
+
+

Returns information regarding the currently unprocessed price epoch. +This epoch is not necessarily the last one, in case the network halts for some +time due to validator node problems, for example.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_lastUnprocessedPriceEpochuint256ID of the price epoch that is currently waiting finalization.
_lastUnprocessedPriceEpochRevealEndsuint256When that price epoch can be finalized, in seconds since UNIX epoch.
_lastUnprocessedPriceEpochInitializedboolWhether this price epoch has been already initialized and therefore it must be finalized before the corresponding reward epoch can be finalized.
+
+
+
+

getPriceEpochConfiguration#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function getPriceEpochConfiguration(
+) external view returns (
+    uint256 _firstPriceEpochStartTs,
+    uint256 _priceEpochDurationSeconds,
+    uint256 _revealEpochDurationSeconds);
+
+

Returns the current values for price epoch timing configuration.

+

See the FTSO page +for information about the different submission phases.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_firstPriceEpochStartTsuint256Timestamp, in seconds since UNIX epoch, of the first price epoch.
_priceEpochDurationSecondsuint256Duration in seconds of the commit phase.
_revealEpochDurationSecondsuint256Duration in seconds of the reveal phase.
+
+
+
+

getPriceSubmitter#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function getPriceSubmitter(
+) external view returns (
+    contract IIPriceSubmitter);
+
+

Returns the PriceSubmitter contract.

+
+
+
+

getRewardEpochConfiguration#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function getRewardEpochConfiguration(
+) external view returns (
+    uint256 _firstRewardEpochStartTs,
+    uint256 _rewardEpochDurationSeconds);
+
+

Returns the current values for reward epoch timing configuration.

+

See the Reward epochs box.

+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_firstRewardEpochStartTsuint256Timestamp, in seconds since UNIX epoch, of the first reward epoch.
_rewardEpochDurationSecondsuint256Duration in seconds of the reward epochs.
+
+
+
+

getRewardEpochData#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function getRewardEpochData(
+    uint256 _rewardEpochId
+) public view returns (
+    struct IIFtsoManager.RewardEpochData);
+
+

Returns data regarding a specific reward epoch ID.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardEpochIduint256Epoch ID.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]struct IIFtsoManager.RewardEpochDataRewardEpochData Its associated data.
+
+
+
+

getRewardEpochToExpireNext#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function getRewardEpochToExpireNext(
+) external view returns (
+    uint256);
+
+

Return reward epoch that will expire next, when a new reward epoch is initialized.

+

Reward epochs older than 90 days expire, and any unclaimed rewards in them become +inaccessible.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256uint256 Reward epoch ID.
+
+
+
+

getRewardEpochVotePowerBlock#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function getRewardEpochVotePowerBlock(
+    uint256 _rewardEpoch
+) external view returns (
+    uint256 _votepowerBlock);
+
+

Returns the vote power block +that was used for a past reward epoch.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardEpochuint256The queried reward epoch ID.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_votepowerBlockuint256uint256 The block number of that reward epoch's vote power block.
+
+
+
+

getRewardExpiryOffsetSeconds#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function getRewardExpiryOffsetSeconds(
+) external view returns (
+    uint256);
+
+

Returns the currently configured reward expiration time.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256uint256 Unclaimed rewards accrued in reward epochs more than this amount of seconds in the past expire and become inaccessible.
+
+
+
+

getUpdateGovernanceParametersTs#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function getUpdateGovernanceParametersTs(
+) external view returns (
+    uint256);
+
+

Returns the timestamp, in seconds since UNIX epoch, when the scheduled new settings +will take effect.

+
+
+
+

getVotePowerIntervalFraction#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function getVotePowerIntervalFraction(
+) external view returns (
+    uint256);
+
+
+
+
+

governance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function governance(
+) public view returns (
+    address);
+
+

Returns the current effective governance address.

+
+
+
+

notInitializedFtsos#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function notInitializedFtsos(
+    contract IIFtso _ftso
+) external view returns (
+    bool);
+
+

Returns whether an FTSO has been initialized.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]boolbool Initialization state.
+
+
+
+

removeFtso#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function removeFtso(
+    contract IIFtso _ftso
+) external;
+
+

Removes an FTSO from the list of managed FTSOs. +Reverts if FTSO is used in a multi-asset FTSO. +Deactivates the _ftso.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsocontract IIFtsoFTSO contract address to remove.
+
+
+
+

replaceFtso#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function replaceFtso(
+    contract IIFtso _ftsoToAdd,
+    bool _copyCurrentPrice,
+    bool _copyAssetOrAssetFtsos
+) external;
+
+

Replaces one FTSO with another with the same symbol. +All FTSOs in a multi-asset FTSO must be managed by the same FTSO manager. +Deactivates the old FTSO.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsoToAddcontract IIFtsoFTSO contract address to add. An existing FTSO with the same symbol will be removed.
_copyCurrentPricebool
_copyAssetOrAssetFtsosbool
+
+
+
+

replaceFtsosBulk#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function replaceFtsosBulk(
+    contract IIFtso[] _ftsosToAdd,
+    bool _copyCurrentPrice,
+    bool _copyAssetOrAssetFtsos
+) external;
+
+

Replaces a list of FTSOs with other FTSOs with the same symbol. +All FTSOs in a multi-asset FTSO must be managed by the same FTSO manager. +Deactivates the old FTSOs.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsosToAddcontract IIFtso[]Array of FTSO contract addresses to add. Every existing FTSO with the same symbols will be removed.
_copyCurrentPricebool
_copyAssetOrAssetFtsosbool
+
+
+
+

rewardEpochDurationSeconds#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
function rewardEpochDurationSeconds(
+) external view returns (
+    uint256);
+
+

Currently configured reward epoch duration.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256uint256 Reward epoch duration, in seconds.
+
+
+
+

rewardEpochs#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function rewardEpochs(
+    uint256 _rewardEpochId
+) external view returns (
+    uint256 _votepowerBlock,
+    uint256 _startBlock,
+    uint256 _startTimestamp);
+
+

Returns information about a reward epoch.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardEpochIduint256The epoch ID to query.
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_votepowerBlockuint256The vote power block of the epoch.
_startBlockuint256The first block of the epoch.
_startTimestampuint256Timestamp of the epoch start, in seconds since UNIX epoch.
+
+
+
+

rewardEpochsStartTs#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
function rewardEpochsStartTs(
+) external view returns (
+    uint256);
+
+

Time when the current reward epoch started.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256uint256 Timestamp, in seconds since UNIX epoch.
+
+
+
+

setElasticBandWidthPPMFtsos#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function setElasticBandWidthPPMFtsos(
+    uint256 _updateTs,
+    contract IIFtso[] _ftsos,
+    uint256[] _widths
+) external;
+
+

Sets elastic band widths in PPM (parts-per-million) for given FTSOs. +Only governance can call this method.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_updateTsuint256Timestamp when the changes will take effect, in seconds from UNIX epoch.
_ftsoscontract IIFtso[]Array of FTSO contract addresses to update.
_widthsuint256[]Array of secondary band widths in PPM. To obtain the actual band width, this number is divided by 10^6 and multiplied by the price median value.
+
+
+
+

setFallbackMode#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function setFallbackMode(
+    bool _fallbackMode
+) external;
+
+

Sets whether the FTSO Manager is currently in fallback mode. +In this mode only submissions from trusted providers are used.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_fallbackModeboolTrue if fallback mode is enabled.
+
+
+
+

setFtsoAsset#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function setFtsoAsset(
+    contract IIFtso _ftso,
+    contract IIVPToken _asset
+) external;
+
+

Sets the asset tracked by an FTSO.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsocontract IIFtsoThe FTSO contract address.
_assetcontract IIVPTokenThe VPToken contract address of the asset to track.
+
+
+
+

setFtsoAssetFtsos#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function setFtsoAssetFtsos(
+    contract IIFtso _ftso,
+    contract IIFtso[] _assetFtsos
+) external;
+
+

Sets an array of FTSOs to be tracked by a multi-asset FTSO. +FTSOs implicitly determine the FTSO assets.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsocontract IIFtsoThe multi-asset FTSO contract address.
_assetFtsoscontract IIFtso[]Array of FTSOs to be tracked.
+
+
+
+

setFtsoFallbackMode#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function setFtsoFallbackMode(
+    contract IIFtso _ftso,
+    bool _fallbackMode
+) external;
+
+

Sets whether an FTSO is currently in fallback mode. +In this mode only submissions from trusted providers are used.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsocontract IIFtsoThe FTSO contract address.
_fallbackModeboolFallback mode.
+
+
+
+

setGovernanceParameters#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function setGovernanceParameters(
+    uint256 _updateTs,
+    uint256 _maxVotePowerNatThresholdFraction,
+    uint256 _maxVotePowerAssetThresholdFraction,
+    uint256 _lowAssetUSDThreshold,
+    uint256 _highAssetUSDThreshold,
+    uint256 _highAssetTurnoutThresholdBIPS,
+    uint256 _lowNatTurnoutThresholdBIPS,
+    uint256 _elasticBandRewardBIPS,
+    uint256 _rewardExpiryOffsetSeconds,
+    address[] _trustedAddresses
+) external;
+
+

Sets governance parameters for FTSOs

+

Only governance can call this method.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_updateTsuint256Time, in seconds since UNIX epoch, when updated settings should be pushed to FTSOs.
_maxVotePowerNatThresholdFractionuint256High threshold for native token vote power per voter.
_maxVotePowerAssetThresholdFractionuint256High threshold for asset vote power per voter
_lowAssetUSDThresholduint256Threshold for low asset vote power (in scaled USD).
_highAssetUSDThresholduint256Threshold for high asset vote power (in scaled USD).
_highAssetTurnoutThresholdBIPSuint256Threshold for high asset turnout (in BIPS).
_lowNatTurnoutThresholdBIPSuint256Threshold for low nat turnout (in BIPS).
_elasticBandRewardBIPSuint256Secondary reward band, where _elasticBandRewardBIPS goes to the secondary band and 10000 - _elasticBandRewardBIPS to the primary (IQR) band.
_rewardExpiryOffsetSecondsuint256Reward epochs closed earlier than block.timestamp - _rewardExpiryOffsetSeconds expire.
_trustedAddressesaddress[]Trusted addresses will be used as a fallback mechanism for setting the price.
+
+
+
+

setInitialRewardData#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function setInitialRewardData(
+    uint256 _nextRewardEpochToExpire,
+    uint256 _rewardEpochsLength,
+    uint256 _currentRewardEpochEnds
+) external;
+
+

Set reward data to values from old ftso manager. +Can only be called before activation.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_nextRewardEpochToExpireuint256See getRewardEpochToExpireNext.
_rewardEpochsLengthuint256See getRewardEpochConfiguration.
_currentRewardEpochEndsuint256See getCurrentRewardEpoch.
+
+
+
+

setRewardEpochDurationSeconds#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function setRewardEpochDurationSeconds(
+    uint256 _rewardEpochDurationSeconds
+) external;
+
+

Sets the reward epoch duration. +Only governance can call this method.

+

If the reward epoch is very short and the expiry offset is very long, the list of reward epochs +to be checked becomes very long. Therefore reward epoch time has to be capped to expiry offset.

+
+
+
+

setUpdateOnRewardEpochSwitchover#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function setUpdateOnRewardEpochSwitchover(
+    contract IUpdateValidators _updateValidators
+) external;
+
+

Unused.

+
+
+
+

setUseGoodRandom#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function setUseGoodRandom(
+    bool _useGoodRandom,
+    uint256 _maxWaitForGoodRandomSeconds
+) external;
+
+

Allow governance to switch to good random numbers only. +Only governance can call this method.

+

See IFtsoManager.UseGoodRandomSet.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_useGoodRandomboolWhether good random numbers should be used or not.
_maxWaitForGoodRandomSecondsuint256Max time in seconds to wait for the good random. If there is none after given time, reward epoch finalization should proceed anyway.
+
+
+
+

setVotePowerIntervalFraction#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function setVotePowerIntervalFraction(
+    uint256 _votePowerIntervalFraction
+) external;
+
+
+
+
+

showLastRevertedError#

+
+

Defined in RevertErrorTracking (Docs, Source).

+
+
+
function showLastRevertedError(
+) external view returns (
+    uint256[] _lastErrorBlock,
+    uint256[] _numErrors,
+    string[] _errorString,
+    address[] _erroringContract,
+    uint256 _totalRevertedErrors);
+
+

Returns latest error information. All arrays will contain only one entry.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_lastErrorBlockuint256[]Array of block numbers where the errors occurred.
_numErrorsuint256[]Array of number of times same error with same contract address has been reverted.
_errorStringstring[]Array of revert error messages.
_erroringContractaddress[]Array of addresses of the reverting contracts.
_totalRevertedErrorsuint256Total number of revert errors across all contracts.
+
+
+
+

showRevertedErrors#

+
+

Defined in RevertErrorTracking (Docs, Source).

+
+
+
function showRevertedErrors(
+    uint256 startIndex,
+    uint256 numErrorTypesToShow
+) public view returns (
+    uint256[] _lastErrorBlock,
+    uint256[] _numErrors,
+    string[] _errorString,
+    address[] _erroringContract,
+    uint256 _totalRevertedErrors);
+
+

Returns latest errors.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
startIndexuint256Starting index in the error list array.
numErrorTypesToShowuint256Number of errors to show. The total amount can be found in errorData.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_lastErrorBlockuint256[]Array of block numbers where the errors occurred.
_numErrorsuint256[]Array of number of times same error with same contract address has been reverted.
_errorStringstring[]Array of revert error messages.
_erroringContractaddress[]Array of addresses of the reverting contracts.
_totalRevertedErrorsuint256Total number of revert errors across all contracts.
+
+
+
+

switchToFallbackMode#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function switchToFallbackMode(
+) external returns (
+    bool);
+
+

This function will be called after an error is caught in daemonize. +It will switch the contract to a simpler fallback mode, which hopefully works when full mode doesn't. +Not every contract needs to support fallback mode (FtsoManager does), so this method may be empty. +Switching back to normal mode is left to the contract (typically a governed method call). +This function may be called due to low-gas error, so it shouldn't use more than ~30.000 gas.

+

Only flareDaemon can call this method.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]boolTrue if switched to fallback mode, false if already in fallback mode or if fallback mode is not supported.
+
+
+
+

switchToProductionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function switchToProductionMode(
+) external;
+
+

Enter the production mode after all the initial governance settings have been set. +This enables timelocks and the governance can be obtained afterward by calling +governanceSettings.getGovernanceAddress(). +Emits GovernedProductionModeEntered.

+
+
+
+

updateContractAddresses#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
function updateContractAddresses(
+    bytes32[] _contractNameHashes,
+    address[] _contractAddresses
+) external;
+
+

External method called from AddressUpdater only.

+
+
+
+

voterWhitelister#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
function voterWhitelister(
+) external view returns (
+    contract IIVoterWhitelister);
+
+

Returns the VoterWhitelister contract address.

+
+
+
+
+

Variables#

+
+

MAX_TRUSTED_ADDRESSES_LENGTH#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
    uint256 MAX_TRUSTED_ADDRESSES_LENGTH
+
+

Maximum number of trusted addresses allowed.

+
+
+
+

active#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
    bool active
+
+

Whether the FTSO Manager is active or not.

+
+
+
+

cleanupBlockNumberManager#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
    contract CleanupBlockNumberManager cleanupBlockNumberManager
+
+

Address of the CleanupBlockNumberManager contract.

+
+
+
+

currentRewardEpochEnds#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
    uint256 currentRewardEpochEnds
+
+

Timestamp when the current reward epoch finishes, in seconds since UNIX epoch.

+
+
+
+

errorData#

+
+

Defined in RevertErrorTracking (Docs, Source).

+
+
+
    struct RevertErrorTracking.LastErrorData errorData
+
+

Most recent error information.

+
+
+
+

flareDaemon#

+
+

Defined in GovernedAndFlareDaemonized (Docs, Source).

+
+
+
    contract FlareDaemon flareDaemon
+
+

The FlareDaemon contract, set at construction time.

+
+
+
+

governanceSettings#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    contract IGovernanceSettings governanceSettings
+
+

Governance Settings.

+
+
+
+

lastRewardedFtsoAddress#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
    address lastRewardedFtsoAddress
+
+

Address of the FTSO contract that was last chosen for reward calculations.

+
+
+
+

maxWaitForGoodRandomSeconds#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
    uint256 maxWaitForGoodRandomSeconds
+
+

Used only when useGoodRandom flag is set.

+
+
+
+

oldFtsoManager#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
    contract IIFtsoManagerV1 oldFtsoManager
+
+

Previous FTSO Manager, in case of a redeployment.

+
+
+
+

priceSubmitter#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
    contract IIPriceSubmitter priceSubmitter
+
+

Address of the PriceSubmitter contract.

+
+
+
+

productionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    bool productionMode
+
+

When true, governance is enabled and cannot be disabled. See switchToProductionMode.

+
+
+
+

rewardEpochDurationSeconds#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
    uint256 rewardEpochDurationSeconds
+
+

Duration of reward epochs, in seconds.

+
+
+
+

rewardEpochsStartTs#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
    uint256 rewardEpochsStartTs
+
+

Timestamp when the first reward epoch started, in seconds since UNIX epoch.

+
+
+
+

rewardManager#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
    contract IIFtsoRewardManager rewardManager
+
+

Address of the RewardManager contract.

+
+
+
+

supply#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
    contract IISupply supply
+
+
+
+
+

timelockedCalls#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    mapping(bytes4 => struct GovernedBase.TimelockedCall) timelockedCalls
+
+

List of pending timelocked governance calls.

+
+
+
+

updateOnRewardEpochSwitchover#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
    contract IUpdateValidators updateOnRewardEpochSwitchover
+
+

Unused.

+
+
+
+

useGoodRandom#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
    bool useGoodRandom
+
+

Whether use of good random numbers is enforced. See IFtsoManager.UseGoodRandomSet.

+
+
+
+

waitingForGoodRandomSinceTs#

+
+

Defined in FtsoManager (Docs, Source).

+
+
+
    uint256 waitingForGoodRandomSinceTs
+
+

Used only when useGoodRandom flag is set.

+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/FtsoRegistry/index.html b/apis/smart-contracts/FtsoRegistry/index.html new file mode 100644 index 000000000..0e89cf72a --- /dev/null +++ b/apis/smart-contracts/FtsoRegistry/index.html @@ -0,0 +1,5719 @@ + + + + + + + + + + + + + + + + + + FtsoRegistry - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + +

FtsoRegistry#

+ +
+

Handles registration of assets to the FTSO system.

+
+
+

Functions#

+
+

addFtso#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
function addFtso(
+    contract IIFtso _ftsoContract
+) external returns (
+    uint256 _assetIndex);
+
+

Add a new FTSO contract to the registry.

+

Only the ftsoManager can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsoContractcontract IIFtsoNew target FTSO contract.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_assetIndexuint256The FTSO index assigned to the new asset.
+
+
+
+

cancelGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function cancelGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Cancel a timelocked governance call before it has been executed.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector.
+
+
+
+

constructor#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
constructor(
+) public;
+
+
+
+
+

executeGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function executeGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Execute the timelocked governance calls once the timelock period expires.

+

Only executor can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector (only one timelocked call per method is stored).
+
+
+
+

getAddressUpdater#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
function getAddressUpdater(
+) public view returns (
+    address _addressUpdater);
+
+

Returns the configured address updater.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_addressUpdateraddressThe AddresUpdater contract that can update our contract address list, as a response to a governance call.
+
+
+
+

getAllCurrentPrices#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
function getAllCurrentPrices(
+) external view returns (
+    struct IFtsoRegistry.PriceInfo[]);
+
+

Returns the current price of all supported assets.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]struct IFtsoRegistry.PriceInfo[]Array of PriceInfo structures.
+
+
+
+

getAllFtsos#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
function getAllFtsos(
+) external view returns (
+    contract IIFtso[] _ftsos);
+
+

Return all currently supported FTSO contracts.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_ftsoscontract IIFtso[]Array of FTSO contract addresses.
+
+
+
+

getCurrentPrice#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
function getCurrentPrice(
+    uint256 _assetIndex
+) external view returns (
+    uint256 _price,
+    uint256 _timestamp);
+
+

Public view function to get the current price of a given active FTSO index. +Reverts if the index is not supported.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_assetIndexuint256
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Current price of the asset in USD multiplied by 10^ASSET_PRICE_USD_DECIMALS.
_timestampuint256Timestamp for when this price was updated, in seconds since UNIX epoch.
+
+
+
+

getCurrentPrice#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
function getCurrentPrice(
+    string _symbol
+) external view returns (
+    uint256 _price,
+    uint256 _timestamp);
+
+

Public view function to get the current price of a given active asset symbol. +Reverts if the symbol is not supported.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_symbolstringSymbol to query.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Current price of the asset in USD multiplied by 10^ASSET_PRICE_USD_DECIMALS.
_timestampuint256Timestamp for when this price was updated, in seconds since UNIX epoch.
+
+
+
+

getCurrentPriceWithDecimals#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
function getCurrentPriceWithDecimals(
+    uint256 _assetIndex
+) external view returns (
+    uint256 _price,
+    uint256 _timestamp,
+    uint256 _assetPriceUsdDecimals);
+
+

Public view function to get the current price and decimals of a given active FTSO index. +Reverts if the index is not supported.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_assetIndexuint256Index to query.
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Current price of the asset in USD multiplied by 10^_assetPriceUsdDecimals.
_timestampuint256Timestamp for when this price was updated, in seconds since UNIX epoch.
_assetPriceUsdDecimalsuint256Number of decimals used to return the _price.
+
+
+
+

getCurrentPriceWithDecimals#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
function getCurrentPriceWithDecimals(
+    string _symbol
+) external view returns (
+    uint256 _price,
+    uint256 _timestamp,
+    uint256 _assetPriceUsdDecimals);
+
+

Public view function to get the current price and decimals of a given active asset symbol. +Reverts if the symbol is not supported.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_symbolstringSymbol to query.
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Current price of the asset in USD multiplied by 10^_assetPriceUsdDecimals.
_timestampuint256Timestamp for when this price was updated, in seconds since UNIX epoch.
_assetPriceUsdDecimalsuint256Number of decimals used to return the _price.
+
+
+
+

getCurrentPricesByIndices#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
function getCurrentPricesByIndices(
+    uint256[] _indices
+) external view returns (
+    struct IFtsoRegistry.PriceInfo[]);
+
+

Returns the current price of a list of indices. +Reverts if any of the indices is not supported.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_indicesuint256[]Array of indices to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]struct IFtsoRegistry.PriceInfo[]Array of PriceInfo structures.
+
+
+
+

getCurrentPricesBySymbols#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
function getCurrentPricesBySymbols(
+    string[] _symbols
+) external view returns (
+    struct IFtsoRegistry.PriceInfo[]);
+
+

Returns the current price of a list of asset symbols. +Reverts if any of the symbols is not supported.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_symbolsstring[]Array of symbols to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]struct IFtsoRegistry.PriceInfo[]Array of PriceInfo structures.
+
+
+
+

getFtso#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
function getFtso(
+    uint256 _assetIndex
+) external view returns (
+    contract IIFtso _activeFtso);
+
+

Returns the address of the FTSO contract for a given index. +Reverts if unsupported index is passed.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_assetIndexuint256
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_activeFtsocontract IIFtso
+
+
+
+

getFtsoBySymbol#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
function getFtsoBySymbol(
+    string _symbol
+) external view returns (
+    contract IIFtso _activeFtso);
+
+

Returns the address of the FTSO contract for a given symbol. +Reverts if unsupported symbol is passed.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_symbolstringThe queried symbol.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_activeFtsocontract IIFtso
+
+
+
+

getFtsoHistory#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
function getFtsoHistory(
+    uint256 _assetIndex
+) external view returns (
+    contract IIFtso[5] _ftsoAddressHistory);
+
+

Get the history of FTSOs for given index. +If there are less then MAX_HISTORY_LENGTH the remaining addresses will be 0 addresses. +Reverts if index is not supported.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_assetIndexuint256Asset index to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_ftsoAddressHistorycontract IIFtso[5]History of FTSOs contract for provided index.
+
+
+
+

getFtsoIndex#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
function getFtsoIndex(
+    string _symbol
+) external view returns (
+    uint256 _assetIndex);
+
+

Returns the FTSO index corresponding to a given asset symbol. +Reverts if the symbol is not supported.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_symbolstringSymbol to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_assetIndexuint256The corresponding asset index.
+
+
+
+

getFtsoSymbol#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
function getFtsoSymbol(
+    uint256 _assetIndex
+) external view returns (
+    string _symbol);
+
+

Returns the asset symbol corresponding to a given FTSO index. +Reverts if the index is not supported.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_assetIndexuint256
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_symbolstringThe corresponding asset symbol.
+
+
+
+

getFtsos#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
function getFtsos(
+    uint256[] _assetIndices
+) external view returns (
+    contract IFtsoGenesis[] _ftsos);
+
+

Get the addresses of the active FTSOs at the given indices. +Reverts if any of the provided indices is non-existing or inactive.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_assetIndicesuint256[]
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_ftsoscontract IFtsoGenesis[]The array of FTSO addresses.
+
+
+
+

getSupportedFtsos#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
function getSupportedFtsos(
+) external view returns (
+    contract IIFtso[] _ftsos);
+
+

Get array of all FTSO contracts for all supported asset indices. +The index of FTSO in returned array does not necessarily correspond to the asset's index. +Due to deletion, some indices might be unsupported.

+

Use getSupportedIndicesAndFtsos to retrieve pairs of correct indices and FTSOs, +where possible "null" holes are readily apparent.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_ftsoscontract IIFtso[]Array of all supported FTSOs.
+
+
+
+

getSupportedIndices#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
function getSupportedIndices(
+) external view returns (
+    uint256[] _supportedIndices);
+
+

Returns the indices of the currently supported FTSOs. +Active FTSOs are ones that currently receive price feeds.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_supportedIndicesuint256[]Array of all active FTSO indices in increasing order.
+
+
+
+

getSupportedIndicesAndFtsos#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
function getSupportedIndicesAndFtsos(
+) external view returns (
+    uint256[] _supportedIndices,
+    contract IIFtso[] _ftsos);
+
+

Get all supported indices and corresponding FTSO addresses. +Active FTSOs are ones that currently receive price feeds.

+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_supportedIndicesuint256[]Array of all supported indices.
_ftsoscontract IIFtso[]Array of all supported FTSO addresses.
+
+
+
+

getSupportedIndicesAndSymbols#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
function getSupportedIndicesAndSymbols(
+) external view returns (
+    uint256[] _supportedIndices,
+    string[] _supportedSymbols);
+
+

Get all supported indices and corresponding symbols. +Active FTSOs are ones that currently receive price feeds.

+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_supportedIndicesuint256[]Array of all supported indices.
_supportedSymbolsstring[]Array of all supported symbols.
+
+
+
+

getSupportedIndicesSymbolsAndFtsos#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
function getSupportedIndicesSymbolsAndFtsos(
+) external view returns (
+    uint256[] _supportedIndices,
+    string[] _supportedSymbols,
+    contract IIFtso[] _ftsos);
+
+

Get all supported indices, symbols, and corresponding FTSO addresses. +Active FTSOs are ones that currently receive price feeds.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_supportedIndicesuint256[]Array of all supported indices.
_supportedSymbolsstring[]Array of all supported symbols.
_ftsoscontract IIFtso[]Array of all supported FTSO addresses.
+
+
+
+

getSupportedSymbols#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
function getSupportedSymbols(
+) external view returns (
+    string[] _supportedSymbols);
+
+

Returns the symbols of the currently supported FTSOs. +Active FTSOs are ones that currently receive price feeds.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_supportedSymbolsstring[]Array of all active FTSO symbols in increasing order.
+
+
+
+

getSupportedSymbolsAndFtsos#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
function getSupportedSymbolsAndFtsos(
+) external view returns (
+    string[] _supportedSymbols,
+    contract IIFtso[] _ftsos);
+
+

Get all supported symbols and corresponding FTSO addresses. +Active FTSOs are ones that currently receive price feeds.

+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_supportedSymbolsstring[]Array of all supported symbols.
_ftsoscontract IIFtso[]Array of all supported FTSO addresses.
+
+
+
+

governance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function governance(
+) public view returns (
+    address);
+
+

Returns the current effective governance address.

+
+
+
+

initialiseRegistry#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
function initialiseRegistry(
+    address _addressUpdater
+) external;
+
+
+
+
+

removeFtso#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
function removeFtso(
+    contract IIFtso _ftso
+) external;
+
+

Removes the FTSO and keeps part of the history. +Reverts if the provided address is not supported.

+

From now on, the index this asset was using is "reserved" and cannot be used again. +It will not be returned in any list of currently supported assets.

+

Only the ftsoManager can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsocontract IIFtsoAddress of the FTSO contract to remove.
+
+
+
+

switchToProductionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function switchToProductionMode(
+) external;
+
+

Enter the production mode after all the initial governance settings have been set. +This enables timelocks and the governance can be obtained afterward by calling +governanceSettings.getGovernanceAddress(). +Emits GovernedProductionModeEntered.

+
+
+
+

updateContractAddresses#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
function updateContractAddresses(
+    bytes32[] _contractNameHashes,
+    address[] _contractAddresses
+) external;
+
+

External method called from AddressUpdater only.

+
+
+
+
+

Modifiers#

+
+

onlyAddressUpdater#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
modifier onlyAddressUpdater()
+
+

Only the AdressUpdater contract can call this method. +Its address is set at construction time but it can also update itself.

+
+
+
+

onlyFtsoManager#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
modifier onlyFtsoManager()
+
+

Only the ftsoManager can call this method.

+
+
+
+

onlyGovernance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
modifier onlyGovernance()
+
+
+
+
+

onlyImmediateGovernance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
modifier onlyImmediateGovernance()
+
+
+
+
+
+

Variables#

+
+

ftsoManager#

+
+

Defined in FtsoRegistry (Docs, Source).

+
+
+
    contract IIFtsoManager ftsoManager
+
+

FtsoManager contract that can add and remove assets to the registry.

+
+
+
+

governanceSettings#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    contract IGovernanceSettings governanceSettings
+
+

Governance Settings.

+
+
+
+

productionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    bool productionMode
+
+

When true, governance is enabled and cannot be disabled. See switchToProductionMode.

+
+
+
+

timelockedCalls#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    mapping(bytes4 => struct GovernedBase.TimelockedCall) timelockedCalls
+
+

List of pending timelocked governance calls.

+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/FtsoRewardManager/index.html b/apis/smart-contracts/FtsoRewardManager/index.html new file mode 100644 index 000000000..8f7e7fc49 --- /dev/null +++ b/apis/smart-contracts/FtsoRewardManager/index.html @@ -0,0 +1,7055 @@ + + + + + + + + + + + + + + + + + + FtsoRewardManager - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

FtsoRewardManager#

+
+

Source | Inherits from IIFtsoRewardManager, Governed, ReentrancyGuard, AddressUpdatable

+
+
+

Handles reward distribution and claiming related to the FTSO system.

+

More specifically, this contract:

+
    +
  • Distributes rewards according to instructions from the FtsoManager.
  • +
  • Allows data providers, delegators and executors to claim rewards.
  • +
+
+
+

Functions#

+
+

accrueUnearnedRewards#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function accrueUnearnedRewards(
+    uint256 _epochId,
+    uint256 _priceEpochDurationSeconds,
+    uint256 _priceEpochEndTime
+) external;
+
+

Accrue unearned rewards for a given price epoch. +Typically done when the FTSO is in fallback mode or because of insufficient vote power. +Simply accrue them so they will not be distributed and will be burned later.

+

The amount of rewards that will be burned is calculated in the same way as in distributeRewards.

+

Only the FTSO Manager can call this method.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_epochIduint256
_priceEpochDurationSecondsuint256
_priceEpochEndTimeuint256
+
+
+
+

activate#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function activate(
+) external;
+
+

Activates reward manager (allows claiming rewards).

+

Only governance can call this method.

+
+
+
+

active#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function active(
+) external view returns (
+    bool);
+
+

Whether rewards can be claimed from this reward manager.

+
+
+
+

autoClaim#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function autoClaim(
+    address[] _rewardOwners,
+    uint256 _rewardEpoch
+) external;
+
+

Allows claiming rewards simultaneously for a list of reward owners and all unclaimed epochs before the +specified one.

+

This is meant as a convenience all-in-one reward claiming method to be used both by reward owners and +registered executors. +It performs a series of operations, besides claiming rewards:

+
    +
  • +

    If a reward owner has enabled its +Personal Delegation Account, rewards are also +claimed for the PDA and the total claimed amount is sent to that PDA. +Otherwise, the claimed amount is sent to the reward owner's account.

    +
  • +
  • +

    Claimed amount is automatically wrapped through the WNat contract.

    +
  • +
  • +

    If the caller is a registered executor with a non-zero fee, the fee is paid to the executor for each claimed +address.

    +
  • +
+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardOwnersaddress[]List of reward owners to claim for.
_rewardEpochuint256Last reward epoch ID to claim for. All previous epochs with pending rewards will be claimed too.
+
+
+
+

cancelGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function cancelGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Cancel a timelocked governance call before it has been executed.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector.
+
+
+
+

claim#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function claim(
+    address _rewardOwner,
+    address payable _recipient,
+    uint256 _rewardEpoch,
+    bool _wrap
+) external returns (
+    uint256 _rewardAmount);
+
+

Allows the caller to claim rewards for a reward owner. +The caller does not have to be the owner of the rewards, but must be approved by the owner to claim on his +behalf by using setClaimExecutors on the claimSetupManager.

+

This function is intended to be used to claim rewards in case of delegation by percentage. +Reverts if msg.sender is delegating by amount.

+

Anybody can call this method, but rewards can only be sent to the reward owner, therefore no funds can be +stolen. However, by limiting the authorized callers, the owner can control the timing of the calls.

+

When the reward owner is the caller, rewards can be sent to any recipient set by setAllowedClaimRecipients on +the claimSetupManager. +The reward owner's Personal Delegation Account +is always an authorized recipient.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardOwneraddressAddress of the reward owner.
_recipientaddress payableAddress to transfer claimed rewards to.
_rewardEpochuint256Last reward epoch to claim for. All previous epochs with pending rewards will be claimed too.
_wrapboolWhether claimed rewards should be wrapped through the WNat contract before transferring them to the _recipient. This parameter is offered as a convenience.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_rewardAmountuint256Total amount of claimed rewards (wei).
+
+
+
+

claimFromDataProviders#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function claimFromDataProviders(
+    address _rewardOwner,
+    address payable _recipient,
+    uint256[] _rewardEpochs,
+    address[] _dataProviders,
+    bool _wrap
+) external returns (
+    uint256 _rewardAmount);
+
+

Allows the caller to claim rewards for a reward owner from specific data providers. +The caller does not have to be the owner of the rewards, but must be approved by the owner to claim on his +behalf by using setClaimExecutors on the claimSetupManager.

+

This function is intended to be used to claim rewards in case of delegation by amount (explicit delegation). +Reverts if msg.sender is delegating by percentage.

+

Anybody can call this method, but rewards can only be sent to the reward owner, therefore no funds can be +stolen. However, by limiting the authorized callers, the owner can control the timing of the calls.

+

When the reward owner is the caller, rewards can be sent to any recipient set by setAllowedClaimRecipients on +the claimSetupManager. +The reward owner's Personal Delegation Account +is always an authorized recipient.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardOwneraddressAddress of the reward owner.
_recipientaddress payableAddress to transfer claimed rewards to.
_rewardEpochsuint256[]Array of reward epoch IDs to claim for.
_dataProvidersaddress[]Array of addresses of the data providers to claim the reward from.
_wrapboolWhether claimed rewards should be wrapped through the WNat contract before transferring them to the _recipient. This parameter is offered as a convenience.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_rewardAmountuint256Total amount of claimed rewards (wei).
+
+
+
+

claimReward#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function claimReward(
+    address payable _recipient,
+    uint256[] _rewardEpochs
+) external returns (
+    uint256 _rewardAmount);
+
+

Allows a percentage delegator to claim rewards. +This function is intended to be used to claim rewards in case of delegation by percentage.

+

This function is deprecated: use claim instead.

+

Reverts if msg.sender is delegating by amount. +Claims for all unclaimed reward epochs to the 'max(_rewardEpochs)'. +Retained for backward compatibility.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_recipientaddress payableAddress to transfer funds to.
_rewardEpochsuint256[]Array of reward epoch numbers to claim for.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_rewardAmountuint256Amount of total claimed rewards (wei).
+
+
+
+

claimRewardFromDataProviders#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function claimRewardFromDataProviders(
+    address payable _recipient,
+    uint256[] _rewardEpochs,
+    address[] _dataProviders
+) external returns (
+    uint256 _rewardAmount);
+
+

Allows the caller to claim rewards from specific data providers. +This function is intended to be used to claim rewards in case of delegation by amount.

+

This function is deprecated: use claimFromDataProviders instead.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_recipientaddress payableAddress to transfer funds to.
_rewardEpochsuint256[]Array of reward epoch numbers to claim for.
_dataProvidersaddress[]Array of addresses of the data providers to claim the reward from.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_rewardAmountuint256Total amount of claimed rewards (wei).
+
+
+
+

closeExpiredRewardEpoch#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function closeExpiredRewardEpoch(
+    uint256 _rewardEpoch
+) external;
+
+

Collects funds from expired reward epoch and calculates totals.

+

Triggered by ftsoManager on finalization of a reward epoch. +Operation is irreversible: when some reward epoch is closed according to current +settings, it cannot be reopened even if new parameters would +allow it, because nextRewardEpochToExpire in ftsoManager never decreases.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardEpochuint256
+
+
+
+

constructor#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
constructor(
+    address _governance,
+    address _addressUpdater,
+    address _oldFtsoRewardManager,
+    uint256 _feePercentageUpdateOffset,
+    uint256 _defaultFeePercentage
+) public;
+
+
+
+
+

constructor#

+
+

Defined in Governed (Docs, Source).

+
+
+
constructor(
+    address _governance
+) public;
+
+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_governanceaddressGovernance contract. Must not be zero.
+
+
+
+

deactivate#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function deactivate(
+) external;
+
+

Deactivates reward manager (prevents claiming rewards).

+

Only governance can call this method.

+
+
+
+

defaultFeePercentage#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function defaultFeePercentage(
+) external view returns (
+    uint256);
+
+

Returns the configured default fee percentage.

+
+
+
+

distributeRewards#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function distributeRewards(
+    address[] _addresses,
+    uint256[] _weights,
+    uint256 _totalWeight,
+    uint256 _epochId,
+    address _ftso,
+    uint256 _priceEpochDurationSeconds,
+    uint256 _currentRewardEpoch,
+    uint256 _priceEpochEndTime,
+    uint256 _votePowerBlock
+) external;
+
+

Distributes price epoch rewards to data provider accounts, according to input parameters. +Must be called with totalWeight > 0 and addresses.length > 0.

+

The amount of rewards for a given price epoch ID are calculated in FtsoRewardManager from +priceEpochDurationSeconds, priceEpochEndTime and inflation authorization data +(see _getTotalPriceEpochRewardWei in FtsoRewardManager. +Then each data provider address is given a portion of this amount according to corresponding weight +and total sum of weights.

+

Parameters epochId and ftso are only needed so they can be passed onto the emitted event.

+

Only the ftsoManager can call this method.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_addressesaddress[]
_weightsuint256[]
_totalWeightuint256
_epochIduint256
_ftsoaddress
_priceEpochDurationSecondsuint256
_currentRewardEpochuint256
_priceEpochEndTimeuint256
_votePowerBlockuint256
+
+
+
+

enableClaims#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function enableClaims(
+) external;
+
+

Enable claiming for current and all future reward epochs.

+

Only governance can call this method.

+
+
+
+

executeGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function executeGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Execute the timelocked governance calls once the timelock period expires.

+

Only executor can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector (only one timelocked call per method is stored).
+
+
+
+

feePercentageUpdateOffset#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function feePercentageUpdateOffset(
+) external view returns (
+    uint256);
+
+

Returns the amount of reward epoch that need to ellapse before a fee change takes effect.

+
+
+
+

firstClaimableRewardEpoch#

+
+

Defined in IIFtsoRewardManager (Docs, Source).

+
+
+
function firstClaimableRewardEpoch(
+) external view returns (
+    uint256);
+
+

Epochs before the token distribution event at Flare launch were not be claimable. +Use this method to know the first reward epoch that was claimable.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256uint256 The first reward epoch that can be claimed.
+
+
+
+

getAddressUpdater#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
function getAddressUpdater(
+) public view returns (
+    address _addressUpdater);
+
+

Returns the configured address updater.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_addressUpdateraddressThe AddresUpdater contract that can update our contract address list, as a response to a governance call.
+
+
+
+

getClaimedReward#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function getClaimedReward(
+    uint256 _rewardEpoch,
+    address _dataProvider,
+    address _claimer
+) external view returns (
+    bool _claimed,
+    uint256 _amount);
+
+

Returns information on the rewards accrued by a reward owner from a specific data provider at a specific +reward epoch.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardEpochuint256Reward epoch ID to query.
_dataProvideraddressAddress of the data provider to query.
_claimeraddressAddress of the reward owner to query.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_claimedboolWhether the reward has been claimed or not.
_amountuint256Accrued amount in wei.
+
+
+
+

getContractName#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function getContractName(
+) external pure returns (
+    string);
+
+

Implement this function to allow updating inflation receiver contracts through AddressUpdater.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]stringContract name.
+
+
+
+

getCurrentRewardEpoch#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function getCurrentRewardEpoch(
+) external view returns (
+    uint256);
+
+

Returns the current reward epoch ID.

+
+
+
+

getDataProviderCurrentFeePercentage#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function getDataProviderCurrentFeePercentage(
+    address _dataProvider
+) external view returns (
+    uint256);
+
+

Returns the current fee percentage of a data provider.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_dataProvideraddressAddress of the queried data provider.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256
+
+
+
+

getDataProviderFeePercentage#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function getDataProviderFeePercentage(
+    address _dataProvider,
+    uint256 _rewardEpoch
+) external view returns (
+    uint256 _feePercentageBIPS);
+
+

Returns the fee percentage of a data provider at a +given reward epoch.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_dataProvideraddressAddress of the queried data provider.
_rewardEpochuint256Reward epoch ID.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_feePercentageBIPSuint256Fee percentage in BIPS.
+
+
+
+

getDataProviderPerformanceInfo#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function getDataProviderPerformanceInfo(
+    uint256 _rewardEpoch,
+    address _dataProvider
+) external view returns (
+    uint256 _rewardAmount,
+    uint256 _votePowerIgnoringRevocation);
+
+

Returns information on rewards and vote power of a data provider at a given reward epoch.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardEpochuint256Reward epoch ID.
_dataProvideraddressAddress of the data provider to query.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_rewardAmountuint256Amount of rewards (wei).
_votePowerIgnoringRevocationuint256Vote power, not including revocations.
+
+
+
+

getDataProviderScheduledFeePercentageChanges#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function getDataProviderScheduledFeePercentageChanges(
+    address _dataProvider
+) external view returns (
+    uint256[] _feePercentageBIPS,
+    uint256[] _validFromEpoch,
+    bool[] _fixed);
+
+

Returns the scheduled fee percentage changes for a data +provider.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_dataProvideraddressAddress of the queried data provider.
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_feePercentageBIPSuint256[]Array of fee percentages in BIPS.
_validFromEpochuint256[]Array of block numbers from which the fee settings are effective.
_fixedbool[]Array of boolean values indicating whether settings are subject to change or not.
+
+
+
+

getEpochReward#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function getEpochReward(
+    uint256 _rewardEpoch
+) external view returns (
+    uint256 _totalReward,
+    uint256 _claimedReward);
+
+

Returns information on an epoch's rewards.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardEpochuint256Reward epoch ID.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_totalRewarduint256Total amount of rewards accrued on that epoch, in wei.
_claimedRewarduint256Total amount of rewards that have already been claimed, in wei.
+
+
+
+

getEpochsWithClaimableRewards#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function getEpochsWithClaimableRewards(
+) external view returns (
+    uint256 _startEpochId,
+    uint256 _endEpochId);
+
+

Returns the reward epoch range for which rewards can be claimed. +Rewards outside this range are unclaimable, either because they have expired or because the reward epoch is +still ongoing.

+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_startEpochIduint256The oldest epoch ID that allows reward claiming.
_endEpochIduint256The newest epoch ID that allows reward claiming.
+
+
+
+

getEpochsWithUnclaimedRewards#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function getEpochsWithUnclaimedRewards(
+    address _beneficiary
+) external view returns (
+    uint256[] _epochIds);
+
+

Returns the array of claimable epoch IDs for which the rewards of a reward owner have not yet been claimed.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_beneficiaryaddressAddress of the reward owner to query. Reverts if it uses delegation by amount.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_epochIdsuint256[]Array of epoch IDs.
+
+
+
+

getExpectedBalance#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function getExpectedBalance(
+) external view returns (
+    uint256);
+
+

Returns the contract's expected balance +(actual balance may be higher due to self-destruct funds).

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Expected native token balance.
+
+
+
+

getInflationAddress#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function getInflationAddress(
+) external view returns (
+    address);
+
+

Returns the address of the Inflation contract.

+
+
+
+

getInitialRewardEpoch#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function getInitialRewardEpoch(
+) external view returns (
+    uint256 _initialRewardEpoch);
+
+

Returns the initial reward epoch ID for this reward manager contract. +This corresponds to the oldest reward epoch with claimable rewards in the previous reward manager when this +one took over. +Set by governance through setInitialRewardData.

+
+
+
+

getRewardEpochToExpireNext#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function getRewardEpochToExpireNext(
+) external view returns (
+    uint256);
+
+

Returns the reward epoch that will expire next once a new reward epoch starts.

+
+
+
+

getRewardEpochVotePowerBlock#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function getRewardEpochVotePowerBlock(
+    uint256 _rewardEpoch
+) external view returns (
+    uint256);
+
+

Returns the vote power block of a given reward epoch.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardEpochuint256Reward epoch ID.
+
+
+
+

getStateOfRewards#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function getStateOfRewards(
+    address _beneficiary,
+    uint256 _rewardEpoch
+) external view returns (
+    address[] _dataProviders,
+    uint256[] _rewardAmounts,
+    bool[] _claimed,
+    bool _claimable);
+
+

Returns the state of rewards for a given address at a specific reward epoch.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_beneficiaryaddressAddress of the beneficiary to query. It can be a data provider or a delegator, for example.
Reverts if the queried address is delegating by amount.
_rewardEpochuint256Reward epoch ID to query.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_dataProvidersaddress[]Array of addresses of data providers.
_rewardAmountsuint256[]Array of reward amounts received from each provider, in wei.
_claimedbool[]Array of boolean values indicating whether each reward has been claimed or not.
_claimableboolBoolean value indicating whether rewards are claimable or not.
+
+
+
+

getStateOfRewardsFromDataProviders#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function getStateOfRewardsFromDataProviders(
+    address _beneficiary,
+    uint256 _rewardEpoch,
+    address[] _dataProviders
+) external view returns (
+    uint256[] _rewardAmounts,
+    bool[] _claimed,
+    bool _claimable);
+
+

Returns the state of rewards for a given address coming from a specific set of data providers, at a specific +reward epoch.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_beneficiaryaddressAddress of beneficiary to query.
_rewardEpochuint256Reward epoch ID to query.
_dataProvidersaddress[]Array of addresses of the data providers to query.
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_rewardAmountsuint256[]Array of reward amounts received from each provider, in wei.
_claimedbool[]Array of boolean values indicating whether each reward has been claimed or not.
_claimableboolBoolean value indicating whether rewards are claimable or not.
+
+
+
+

getTokenPoolSupplyData#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function getTokenPoolSupplyData(
+) external view returns (
+    uint256 _lockedFundsWei,
+    uint256 _totalInflationAuthorizedWei,
+    uint256 _totalClaimedWei);
+
+

Returns token pool supply data.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_lockedFundsWeiuint256Total amount of funds ever locked in the token pool (wei). _lockedFundsWei - _totalClaimedWei is the amount currently locked and outside the circulating supply.
_totalInflationAuthorizedWeiuint256Total inflation authorized amount (wei).
_totalClaimedWeiuint256Total claimed amount (wei).
+
+
+
+

getTotals#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function getTotals(
+) external view returns (
+    uint256 _totalAwardedWei,
+    uint256 _totalClaimedWei,
+    uint256 _totalExpiredWei,
+    uint256 _totalUnearnedWei,
+    uint256 _totalBurnedWei,
+    uint256 _totalInflationAuthorizedWei,
+    uint256 _totalInflationReceivedWei,
+    uint256 _lastInflationAuthorizationReceivedTs,
+    uint256 _dailyAuthorizedInflation);
+
+

Returns statistics regarding rewards, accumulated over the whole lifespan of the reward manager contract.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_totalAwardedWeiuint256Rewards that were distributed (wei).
_totalClaimedWeiuint256Distributed rewards that were claimed in time (wei).
_totalExpiredWeiuint256Distributed rewards that were not claimed in time and expired (wei).
_totalUnearnedWeiuint256Rewards that were unearned (due to FTSO being in fallback mode) and thus were not distributed (wei).
_totalBurnedWeiuint256Rewards that were unearned or expired and thus burned (wei).
_totalInflationAuthorizedWeiuint256Total inflation authorized amount (wei).
_totalInflationReceivedWeiuint256Total inflation received amount (wei).
_lastInflationAuthorizationReceivedTsuint256UNIX timestamp of the last inflation authorization.
_dailyAuthorizedInflationuint256Inflation authorized amount (wei) at the time of last authorization.
+
+
+
+

getUnclaimedReward#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function getUnclaimedReward(
+    uint256 _rewardEpoch,
+    address _dataProvider
+) external view returns (
+    uint256 _amount,
+    uint256 _weight);
+
+

Returns information on unclaimed rewards for a given data provider and epoch.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardEpochuint256Queried reward epoch ID.
_dataProvideraddressAddress of the queried data provider.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_amountuint256Amount available to be claimed, in wei.
_weightuint256Portion of total vote power used in this reward epoch that has not yet claimed its reward, in BIPS. It decreases to 0 when all data providers have claimed their rewards.
+
+
+
+

governance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function governance(
+) public view returns (
+    address);
+
+

Returns the current effective governance address.

+
+
+
+

nextClaimableRewardEpoch#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function nextClaimableRewardEpoch(
+    address _rewardOwner
+) external view returns (
+    uint256);
+
+

Returns the next claimable reward epoch for a reward owner.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardOwneraddressAddress of the reward owner to query.
+
+
+
+

receiveInflation#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function receiveInflation(
+) external payable;
+
+

Receive native tokens from inflation.

+

Only the inflation contract can call this method.

+
+
+
+

setDailyAuthorizedInflation#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function setDailyAuthorizedInflation(
+    uint256 _toAuthorizeWei
+) external;
+
+

Notify the receiver that it is entitled to receive a new inflation amount.

+

Only the inflation contract can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_toAuthorizeWeiuint256The amount of inflation that can be awarded in the coming day, in wei.
+
+
+
+

setDataProviderFeePercentage#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function setDataProviderFeePercentage(
+    uint256 _feePercentageBIPS
+) external returns (
+    uint256);
+
+

Sets the fee a data provider keeps from all delegations.

+

Takes effect after feeValueUpdateOffset reward epochs have elapsed.

+

When called multiple times inside the same reward epoch, only the last value remains.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_feePercentageBIPSuint256Fee percentage in BIPS.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256
+
+
+
+

setInitialRewardData#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function setInitialRewardData(
+) external;
+
+

Copy initial reward data from oldFtsoRewardManager before starting up this new reward manager. +Should be called at the time of switching to the new reward manager, can be called only once, and only +by governance.

+
+
+
+

setNewFtsoRewardManager#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
function setNewFtsoRewardManager(
+    address _newFtsoRewardManager
+) external;
+
+

Sets new ftso reward manager which will take over closing expired reward epochs +Should be called at the time of switching to the new reward manager, can be called only once, and only +by governance.

+
+
+
+

switchToProductionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function switchToProductionMode(
+) external;
+
+

Enter the production mode after all the initial governance settings have been set. +This enables timelocks and the governance can be obtained afterward by calling +governanceSettings.getGovernanceAddress(). +Emits GovernedProductionModeEntered.

+
+
+
+

updateContractAddresses#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
function updateContractAddresses(
+    bytes32[] _contractNameHashes,
+    address[] _contractAddresses
+) external;
+
+

External method called from AddressUpdater only.

+
+
+
+
+

Modifiers#

+
+

mustBalance#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
modifier mustBalance()
+
+
+
+
+

nonReentrant#

+
+

Defined in ReentrancyGuard (Source).

+
+
+
modifier nonReentrant()
+
+

Prevents a contract from calling itself, directly or indirectly. +Calling a nonReentrant function from another nonReentrant +function is not supported. It is possible to prevent this from happening +by making the nonReentrant function external, and make it call a +private function that does the actual work.

+
+
+
+

onlyAddressUpdater#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
modifier onlyAddressUpdater()
+
+

Only the AdressUpdater contract can call this method. +Its address is set at construction time but it can also update itself.

+
+
+
+

onlyExecutorAndAllowedRecipient#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
modifier onlyExecutorAndAllowedRecipient(    address _rewardOwner,
+    address _recipient)
+
+

Only the reward owner and its authorized executors can call this method. +Executors can only send rewards to authorized recipients. +See ClaimSetupManager.

+
+
+
+

onlyFtsoManager#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
modifier onlyFtsoManager()
+
+

Only the ftsoManager contract can call this method.

+
+
+
+

onlyGovernance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
modifier onlyGovernance()
+
+
+
+
+

onlyIfActive#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
modifier onlyIfActive()
+
+

This method can only be called if the contract is active.

+
+
+
+

onlyImmediateGovernance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
modifier onlyImmediateGovernance()
+
+
+
+
+

onlyInflation#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
modifier onlyInflation()
+
+

Only the Inflation contract can call this method.

+
+
+
+
+

Structures#

+
+

RewardClaim#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
struct RewardClaim {
+  bool claimed;
+  uint128 amount;
+}
+
+
+
+

RewardState#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
struct RewardState {
+  address[] dataProviders;
+  uint256[] weights;
+  uint256[] amounts;
+  bool[] claimed;
+}
+
+
+
+

TimelockedCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
struct TimelockedCall {
+  uint256 allowedAfterTimestamp;
+  bytes encodedCall;
+}
+
+
+
+

UnclaimedRewardState#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
struct UnclaimedRewardState {
+  uint128 amount;
+  uint128 weight;
+}
+
+
+
+
+

Variables#

+
+

active#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
    bool active
+
+

Whether rewards can be claimed from this reward manager.

+
+
+
+

claimSetupManager#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
    contract IIClaimSetupManager claimSetupManager
+
+

The ClaimSetupManager contract that helps automate reward claiming.

+
+
+
+

firstClaimableRewardEpoch#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
    uint256 firstClaimableRewardEpoch
+
+

Epochs before the token distribution event at Flare launch were not be claimable. +This variable holds the first reward epoch that was claimable.

+
+
+
+

ftsoManager#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
    contract IIFtsoManager ftsoManager
+
+

The FtsoManager contract that controls reward distribution.

+
+
+
+

governanceSettings#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    contract IGovernanceSettings governanceSettings
+
+

Governance Settings.

+
+
+
+

newFtsoRewardManager#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
    address newFtsoRewardManager
+
+

Address of the new FtsoRewardManager that replaced this one.

+
+
+
+

oldFtsoRewardManager#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
    address oldFtsoRewardManager
+
+

Address of the old FtsoRewardManager, replaced by this one.

+
+
+
+

productionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    bool productionMode
+
+

When true, governance is enabled and cannot be disabled. See switchToProductionMode.

+
+
+
+

timelockedCalls#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    mapping(bytes4 => struct GovernedBase.TimelockedCall) timelockedCalls
+
+

List of pending timelocked governance calls.

+
+
+
+

wNat#

+
+

Defined in FtsoRewardManager (Docs, Source).

+
+
+
    contract WNat wNat
+
+

Address of the wrapped native token (WNat) contract.

+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/GovernanceSettings/index.html b/apis/smart-contracts/GovernanceSettings/index.html new file mode 100644 index 000000000..0742f964c --- /dev/null +++ b/apis/smart-contracts/GovernanceSettings/index.html @@ -0,0 +1,4527 @@ + + + + + + + + + + + + + + + + + + GovernanceSettings - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

GovernanceSettings#

+
+

Source | Inherits from IGovernanceSettings

+
+
+

A special contract that holds the Flare governance address and its timelock.

+

All governance calls are delayed by the timelock specified in this contract.

+

This contract enables updating governance address and timelock only by hard-forking the network, +this is, only by updating validator code.

+
+
+

Events#

+
+

GovernanceAddressUpdated#

+
+

Defined in GovernanceSettings (Docs, Source).

+
+
+
event GovernanceAddressUpdated(
+    uint256 timestamp,
+    address oldGovernanceAddress,
+    address newGovernanceAddress
+)
+
+

Emitted when the governance address has been changed.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
timestampuint256Timestamp of the block where the change happened, in seconds from UNIX epoch.
oldGovernanceAddressaddressGovernance address before the change.
newGovernanceAddressaddressGovernance address after the change.
+
+
+
+

GovernanceExecutorsUpdated#

+
+

Defined in GovernanceSettings (Docs, Source).

+
+
+
event GovernanceExecutorsUpdated(
+    uint256 timestamp,
+    address[] oldExecutors,
+    address[] newExecutors
+)
+
+

The list of addresses that are allowed to perform governance calls has been changed.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
timestampuint256Timestamp of the block where the change happened, in seconds from UNIX epoch.
oldExecutorsaddress[]Array of executor addresses before the change.
newExecutorsaddress[]Array of executor addresses after the change.
+
+
+
+

GovernanceTimelockUpdated#

+
+

Defined in GovernanceSettings (Docs, Source).

+
+
+
event GovernanceTimelockUpdated(
+    uint256 timestamp,
+    uint256 oldTimelock,
+    uint256 newTimelock
+)
+
+

Emitted when the timelock has been changed.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
timestampuint256Timestamp of the block where the change happened, in seconds from UNIX epoch.
oldTimelockuint256Timelock before the change (in seconds).
newTimelockuint256Timelock after the change (in seconds).
+
+
+
+
+

Functions#

+
+

getExecutors#

+
+

Defined in GovernanceSettings (Docs, Source).

+
+
+
function getExecutors(
+) external view returns (
+    address[]);
+
+

Gets the addresses of the accounts that are allowed to execute the timelocked governance calls, +once the timelock period expires. +Executors can be changed without a hard fork, via a normal governance call.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]address[]
+
+
+
+

getGovernanceAddress#

+
+

Defined in GovernanceSettings (Docs, Source).

+
+
+
function getGovernanceAddress(
+) external view returns (
+    address);
+
+

Gets the governance account address. +The governance address can only be changed by a hard fork.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]address
+
+
+
+

getTimelock#

+
+

Defined in GovernanceSettings (Docs, Source).

+
+
+
function getTimelock(
+) external view returns (
+    uint256);
+
+

Gets the time in seconds that must pass between a governance call and its execution. +The timelock value can only be changed by a hard fork.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256
+
+
+
+

initialise#

+
+

Defined in GovernanceSettings (Docs, Source).

+
+
+
function initialise(
+    address _governanceAddress,
+    uint256 _timelock,
+    address[] _executors
+) external;
+
+

Perform initialization, which cannot be done in constructor, since this is a genesis contract. +Can only be called once.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_governanceAddressaddressInitial governance address.
_timelockuint256Initial timelock value, in seconds.
_executorsaddress[]Initial list of addresses allowed to perform governance calls.
+
+
+
+

isExecutor#

+
+

Defined in GovernanceSettings (Docs, Source).

+
+
+
function isExecutor(
+    address _address
+) external view returns (
+    bool);
+
+

Checks whether an address is one of the allowed executors. See getExecutors.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_addressaddressThe address to check.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]boolTrue if _address is in the executors list.
+
+
+
+

setExecutors#

+
+

Defined in GovernanceSettings (Docs, Source).

+
+
+
function setExecutors(
+    address[] _newExecutors
+) external;
+
+

Set the addresses of the accounts that are allowed to execute the timelocked governance calls +once the timelock period expires. +It isn't very dangerous to allow for anyone to execute timelocked calls, but we reserve the right to +make sure the timing of the execution is under control. +Can only be called by the governance.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_newExecutorsaddress[]New list of allowed executors. The previous list is replaced.
+
+
+
+

setGovernanceAddress#

+
+

Defined in GovernanceSettings (Docs, Source).

+
+
+
function setGovernanceAddress(
+    address _newGovernance
+) external;
+
+

Change the governance address. +Can only be called by validators via fork.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_newGovernanceaddressNew governance address.
+
+
+
+

setTimelock#

+
+

Defined in GovernanceSettings (Docs, Source).

+
+
+
function setTimelock(
+    uint256 _newTimelock
+) external;
+
+

Change the timelock, this is, the amount of time between a governance call and +its execution. +Can only be called by validators via fork.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_newTimelockuint256New timelock value, in seconds.
+
+
+
+
+

Variables#

+
+

SIGNAL_COINBASE#

+
+

Defined in GovernanceSettings (Docs, Source).

+
+
+
    address SIGNAL_COINBASE
+
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/GovernanceVotePower/index.html b/apis/smart-contracts/GovernanceVotePower/index.html new file mode 100644 index 000000000..1efc50fde --- /dev/null +++ b/apis/smart-contracts/GovernanceVotePower/index.html @@ -0,0 +1,4785 @@ + + + + + + + + + + + + + + + + + + GovernanceVotePower - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + +

GovernanceVotePower#

+
+

Source | Inherits from IIGovernanceVotePower

+
+
+

Contract managing governance vote power and its delegation.

+
+
+

Functions#

+
+

constructor#

+
+

Defined in GovernanceVotePower (Docs, Source).

+
+
+
constructor(
+    contract IVPToken _ownerToken
+) public;
+
+

Construct GovernanceVotePower for given VPToken.

+
+
+
+

delegate#

+
+

Defined in GovernanceVotePower (Docs, Source).

+
+
+
function delegate(
+    address _to
+) public;
+
+

Delegates all governance vote power of msg.sender to address _to.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_toaddressThe address of the recipient.
+
+
+
+

delegatedGovernanceVotePowerHistoryCleanup#

+
+

Defined in GovernanceVotePower (Docs, Source).

+
+
+
function delegatedGovernanceVotePowerHistoryCleanup(
+    address _owner,
+    uint256 _count
+) external returns (
+    uint256);
+
+

Delete governance vote power checkpoints that expired (i.e. are before cleanupBlockNumber). +Method can only be called from the cleanerContract (which may be a proxy to external cleaners).

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressVote power owner account address.
_countuint256Maximum number of checkpoints to delete.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The number of deleted checkpoints.
+
+
+
+

delegatesHistoryCleanup#

+
+

Defined in GovernanceVotePower (Docs, Source).

+
+
+
function delegatesHistoryCleanup(
+    address _owner,
+    uint256 _count
+) external returns (
+    uint256);
+
+

Delete delegates checkpoints that expired (i.e. are before cleanupBlockNumber). +Method can only be called from the cleanerContract (which may be a proxy to external cleaners).

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressVote power owner account address.
_countuint256Maximum number of checkpoints to delete.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The number of deleted checkpoints.
+
+
+
+

getCleanupBlockNumber#

+
+

Defined in GovernanceVotePower (Docs, Source).

+
+
+
function getCleanupBlockNumber(
+) external view returns (
+    uint256);
+
+

Get the current cleanup block number set with setCleanupBlockNumber.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The currently set cleanup block number.
+
+
+
+

getDelegateOfAt#

+
+

Defined in GovernanceVotePower (Docs, Source).

+
+
+
function getDelegateOfAt(
+    address _who,
+    uint256 _blockNumber
+) public view returns (
+    address);
+
+

Gets the address an account is delegating its governance vote power to, at a given block number.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address being queried.
_blockNumberuint256The block number at which to fetch the address.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]addressAddress where _who was delegating its governance vote power at block _blockNumber.
+
+
+
+

getDelegateOfAtNow#

+
+

Defined in GovernanceVotePower (Docs, Source).

+
+
+
function getDelegateOfAtNow(
+    address _who
+) public view returns (
+    address);
+
+

Gets the address an account is delegating its governance vote power to, at the latest block number.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address being queried.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]addressAddress where _who is currently delegating its governance vote power.
+
+
+
+

getVotes#

+
+

Defined in GovernanceVotePower (Docs, Source).

+
+
+
function getVotes(
+    address _who
+) public view returns (
+    uint256);
+
+

Gets the governance vote power of an address at the latest block, including +all delegations made to it.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address being queried.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Governance vote power of account at the lastest block.
+
+
+
+

ownerToken#

+
+

Defined in IIGovernanceVotePower (Docs, Source).

+
+
+
function ownerToken(
+) external view returns (
+    contract IVPToken);
+
+

Get the token that this governance vote power contract belongs to.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]contract IVPTokenThe IVPToken interface owning this contract.
+
+
+
+

setCleanerContract#

+
+

Defined in GovernanceVotePower (Docs, Source).

+
+
+
function setCleanerContract(
+    address _cleanerContract
+) external;
+
+

Set the contract that is allowed to call history cleaning methods.

+

This method can be called by the ownerToken only.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_cleanerContractaddressAddress of the cleanup contract. Usually this will be an instance of CleanupBlockNumberManager.
+
+
+
+

setCleanupBlockNumber#

+
+

Defined in GovernanceVotePower (Docs, Source).

+
+
+
function setCleanupBlockNumber(
+    uint256 _blockNumber
+) external;
+
+

Set the cleanup block number. +Historic data for the blocks before cleanupBlockNumber can be erased. +History before that block should never be used since it can be inconsistent. +In particular, cleanup block number must be lower than the current vote power block.

+

This method can be called by the ownerToken only.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockNumberuint256The new cleanup block number.
+
+
+
+

undelegate#

+
+

Defined in GovernanceVotePower (Docs, Source).

+
+
+
function undelegate(
+) public;
+
+

Undelegates all governance vote power of msg.sender.

+
+
+
+

updateAtTokenTransfer#

+
+

Defined in GovernanceVotePower (Docs, Source).

+
+
+
function updateAtTokenTransfer(
+    address _from,
+    address _to,
+    uint256,
+    uint256,
+    uint256 _amount
+) external;
+
+

Update governance vote power of all involved delegates after tokens are transferred.

+

This function MUST be called after each governance token transfer for the +delegates to reflect the correct balance.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressSource address of the transfer.
_toaddressDestination address of the transfer.
``uint256
``uint256
_amountuint256Amount being transferred.
+
+
+
+

votePowerOfAt#

+
+

Defined in GovernanceVotePower (Docs, Source).

+
+
+
function votePowerOfAt(
+    address _who,
+    uint256 _blockNumber
+) public view returns (
+    uint256);
+
+

Gets the governance vote power of an address at a given block number, including +all delegations made to it.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address being queried.
_blockNumberuint256The block number at which to fetch the vote power.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Governance vote power of _who at _blockNumber.
+
+
+
+
+

Modifiers#

+
+

onlyCleaner#

+
+

Defined in GovernanceVotePower (Docs, Source).

+
+
+
modifier onlyCleaner()
+
+

History cleaning methods can be called only from the cleaner address.

+
+
+
+

onlyOwnerToken#

+
+

Defined in GovernanceVotePower (Docs, Source).

+
+
+
modifier onlyOwnerToken()
+
+

All external methods in GovernanceVotePower can only be executed by the owner token.

+
+
+
+
+

Variables#

+
+

cleanerContract#

+
+

Defined in GovernanceVotePower (Docs, Source).

+
+
+
    address cleanerContract
+
+

Address of the contract that is allowed to call methods for history cleaning. +Set with setCleanerContract.

+
+
+
+

ownerToken#

+
+

Defined in GovernanceVotePower (Docs, Source).

+
+
+
    contract IVPToken ownerToken
+
+

The VPToken (or some other contract) that owns this GovernanceVotePower. +All state changing methods may be called only from this address. +This is because original msg.sender is typically sent in a parameter +and we must make sure that it cannot be faked by directly calling +GovernanceVotePower methods.

+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/Governed/index.html b/apis/smart-contracts/Governed/index.html new file mode 100644 index 000000000..37a3761cd --- /dev/null +++ b/apis/smart-contracts/Governed/index.html @@ -0,0 +1,4078 @@ + + + + + + + + + + + + + + + + + + Governed - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

Governed#

+
+

Source | Inherits from GovernedBase

+
+
+

Defines behaviors for governed contracts that must have a governor set at construction-time.

+
+
+

Functions#

+
+

cancelGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function cancelGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Cancel a timelocked governance call before it has been executed.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector.
+
+
+
+

constructor#

+
+

Defined in Governed (Docs, Source).

+
+
+
constructor(
+    address _governance
+) public;
+
+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_governanceaddressGovernance contract. Must not be zero.
+
+
+
+

executeGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function executeGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Execute the timelocked governance calls once the timelock period expires.

+

Only executor can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector (only one timelocked call per method is stored).
+
+
+
+

governance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function governance(
+) public view returns (
+    address);
+
+

Returns the current effective governance address.

+
+
+
+

switchToProductionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function switchToProductionMode(
+) external;
+
+

Enter the production mode after all the initial governance settings have been set. +This enables timelocks and the governance can be obtained afterward by calling +governanceSettings.getGovernanceAddress(). +Emits GovernedProductionModeEntered.

+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/GovernedAndFlareDaemonized/index.html b/apis/smart-contracts/GovernedAndFlareDaemonized/index.html new file mode 100644 index 000000000..15ae729fd --- /dev/null +++ b/apis/smart-contracts/GovernedAndFlareDaemonized/index.html @@ -0,0 +1,4337 @@ + + + + + + + + + + + + + + + + + + GovernedAndFlareDaemonized - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

GovernedAndFlareDaemonized#

+
+

Source | Inherits from Governed

+
+
+

Base class for contracts that are governed and triggered from the FlareDaemon.

+

See Governed and IFlareDaemonize.

+
+
+

Functions#

+
+

cancelGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function cancelGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Cancel a timelocked governance call before it has been executed.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector.
+
+
+
+

constructor#

+
+

Defined in GovernedAndFlareDaemonized (Docs, Source).

+
+
+
constructor(
+    address _governance,
+    contract FlareDaemon _flareDaemon
+) public;
+
+
+
+
+

constructor#

+
+

Defined in Governed (Docs, Source).

+
+
+
constructor(
+    address _governance
+) public;
+
+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_governanceaddressGovernance contract. Must not be zero.
+
+
+
+

executeGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function executeGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Execute the timelocked governance calls once the timelock period expires.

+

Only executor can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector (only one timelocked call per method is stored).
+
+
+
+

governance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function governance(
+) public view returns (
+    address);
+
+

Returns the current effective governance address.

+
+
+
+

switchToProductionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function switchToProductionMode(
+) external;
+
+

Enter the production mode after all the initial governance settings have been set. +This enables timelocks and the governance can be obtained afterward by calling +governanceSettings.getGovernanceAddress(). +Emits GovernedProductionModeEntered.

+
+
+
+
+

Modifiers#

+
+

onlyFlareDaemon#

+
+

Defined in GovernedAndFlareDaemonized (Docs, Source).

+
+
+
modifier onlyFlareDaemon()
+
+

Only the flareDaemon can call this method.

+
+
+
+

onlyGovernance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
modifier onlyGovernance()
+
+
+
+
+

onlyImmediateGovernance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
modifier onlyImmediateGovernance()
+
+
+
+
+
+

Variables#

+
+

flareDaemon#

+
+

Defined in GovernedAndFlareDaemonized (Docs, Source).

+
+
+
    contract FlareDaemon flareDaemon
+
+

The FlareDaemon contract, set at construction time.

+
+
+
+

governanceSettings#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    contract IGovernanceSettings governanceSettings
+
+

Governance Settings.

+
+
+
+

productionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    bool productionMode
+
+

When true, governance is enabled and cannot be disabled. See switchToProductionMode.

+
+
+
+

timelockedCalls#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    mapping(bytes4 => struct GovernedBase.TimelockedCall) timelockedCalls
+
+

List of pending timelocked governance calls.

+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/GovernedAtGenesis/index.html b/apis/smart-contracts/GovernedAtGenesis/index.html new file mode 100644 index 000000000..e9a7f774c --- /dev/null +++ b/apis/smart-contracts/GovernedAtGenesis/index.html @@ -0,0 +1,4110 @@ + + + + + + + + + + + + + + + + + + GovernedAtGenesis - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

GovernedAtGenesis#

+
+

Source | Inherits from GovernedBase

+
+
+

Defines behaviors for governed contracts that have their governor set at genesis.

+

This contract enforces a fixed governance address when the constructor +is not executed on a contract (for instance when directly loaded to the genesis block). +This is required to fix governance on a contract when the network starts, at such point +where theoretically no accounts yet exist, and leaving it ungoverned could result in a race +to claim governance by an unauthorized address.

+
+
+

Functions#

+
+

cancelGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function cancelGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Cancel a timelocked governance call before it has been executed.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector.
+
+
+
+

constructor#

+
+

Defined in GovernedAtGenesis (Docs, Source).

+
+
+
constructor(
+    address _governance
+) public;
+
+
+
+
+

executeGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function executeGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Execute the timelocked governance calls once the timelock period expires.

+

Only executor can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector (only one timelocked call per method is stored).
+
+
+
+

governance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function governance(
+) public view returns (
+    address);
+
+

Returns the current effective governance address.

+
+
+
+

initialise#

+
+

Defined in GovernedAtGenesis (Docs, Source).

+
+
+
function initialise(
+    address _governance
+) public pure;
+
+

Disallow initialise to be called.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_governanceaddressThe governance address for initial claiming.
+
+
+
+

switchToProductionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function switchToProductionMode(
+) external;
+
+

Enter the production mode after all the initial governance settings have been set. +This enables timelocks and the governance can be obtained afterward by calling +governanceSettings.getGovernanceAddress(). +Emits GovernedProductionModeEntered.

+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/GovernedBase/index.html b/apis/smart-contracts/GovernedBase/index.html new file mode 100644 index 000000000..3d4670e27 --- /dev/null +++ b/apis/smart-contracts/GovernedBase/index.html @@ -0,0 +1,4446 @@ + + + + + + + + + + + + + + + + + + GovernedBase - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + +

GovernedBase#

+
+

Source

+
+
+

Abstract base class that defines behaviors for governed contracts.

+

This class is abstract so that specific behaviors can be defined for the constructor. +Contracts should not be left ungoverned, but not all contract will have a constructor +(for example those pre-defined in genesis).

+
+
+

Events#

+
+

GovernanceCallTimelocked#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event GovernanceCallTimelocked(
+    bytes4 selector,
+    uint256 allowedAfterTimestamp,
+    bytes encodedCall
+)
+
+

Emitted when a new governance call has been recorded and is now waiting for the time lock to expire.

+
+
+
+

GovernanceInitialised#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event GovernanceInitialised(
+    address initialGovernance
+)
+
+

Emitted when the governance address is initialized. +This address will be used until production mode is entered (see GovernedProductionModeEntered). +At that point the governance address is taken from GovernanceSettings.

+
+
+
+

GovernedProductionModeEntered#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event GovernedProductionModeEntered(
+    address governanceSettings
+)
+
+

Emitted when governance is enabled and the governance address cannot be changed anymore +(only through a network fork).

+
+
+
+

TimelockedGovernanceCallCanceled#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event TimelockedGovernanceCallCanceled(
+    bytes4 selector,
+    uint256 timestamp
+)
+
+

Emitted when a timelocked governance call is canceled before execution.

+
+
+
+

TimelockedGovernanceCallExecuted#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event TimelockedGovernanceCallExecuted(
+    bytes4 selector,
+    uint256 timestamp
+)
+
+

Emitted when a timelocked governance call is executed.

+
+
+
+
+

Functions#

+
+

cancelGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function cancelGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Cancel a timelocked governance call before it has been executed.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector.
+
+
+
+

executeGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function executeGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Execute the timelocked governance calls once the timelock period expires.

+

Only executor can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector (only one timelocked call per method is stored).
+
+
+
+

governance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function governance(
+) public view returns (
+    address);
+
+

Returns the current effective governance address.

+
+
+
+

switchToProductionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function switchToProductionMode(
+) external;
+
+

Enter the production mode after all the initial governance settings have been set. +This enables timelocks and the governance can be obtained afterward by calling +governanceSettings.getGovernanceAddress(). +Emits GovernedProductionModeEntered.

+
+
+
+
+

Modifiers#

+
+

onlyGovernance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
modifier onlyGovernance()
+
+
+
+
+

onlyImmediateGovernance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
modifier onlyImmediateGovernance()
+
+
+
+
+
+

Structures#

+
+

TimelockedCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
struct TimelockedCall {
+  uint256 allowedAfterTimestamp;
+  bytes encodedCall;
+}
+
+
+
+
+

Variables#

+
+

governanceSettings#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    contract IGovernanceSettings governanceSettings
+
+

Governance Settings.

+
+
+
+

productionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    bool productionMode
+
+

When true, governance is enabled and cannot be disabled. See switchToProductionMode.

+
+
+
+

timelockedCalls#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    mapping(bytes4 => struct GovernedBase.TimelockedCall) timelockedCalls
+
+

List of pending timelocked governance calls.

+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IClaimSetupManager/index.html b/apis/smart-contracts/IClaimSetupManager/index.html new file mode 100644 index 000000000..10004cc46 --- /dev/null +++ b/apis/smart-contracts/IClaimSetupManager/index.html @@ -0,0 +1,5584 @@ + + + + + + + + + + + + + + + + + + IClaimSetupManager - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + +

IClaimSetupManager#

+
+

Source

+
+
+

Public interface for the ClaimSetupManager contract.

+
+
+

Events#

+
+

AllowedClaimRecipientsChanged#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
event AllowedClaimRecipientsChanged(
+    address owner,
+    address[] recipients
+)
+
+
+
+
+

ClaimExecutorFeeValueChanged#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
event ClaimExecutorFeeValueChanged(
+    address executor,
+    uint256 validFromRewardEpoch,
+    uint256 feeValueWei
+)
+
+
+
+
+

ClaimExecutorsChanged#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
event ClaimExecutorsChanged(
+    address owner,
+    address[] executors
+)
+
+
+
+
+

DelegationAccountCreated#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
event DelegationAccountCreated(
+    address owner,
+    contract IDelegationAccount delegationAccount
+)
+
+
+
+
+

DelegationAccountUpdated#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
event DelegationAccountUpdated(
+    address owner,
+    contract IDelegationAccount delegationAccount,
+    bool enabled
+)
+
+
+
+
+

ExecutorRegistered#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
event ExecutorRegistered(
+    address executor
+)
+
+
+
+
+

ExecutorUnregistered#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
event ExecutorUnregistered(
+    address executor,
+    uint256 validFromRewardEpoch
+)
+
+
+
+
+

MaxFeeSet#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
event MaxFeeSet(
+    uint256 maxFeeValueWei
+)
+
+
+
+
+

MinFeeSet#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
event MinFeeSet(
+    uint256 minFeeValueWei
+)
+
+
+
+
+

RegisterExecutorFeeSet#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
event RegisterExecutorFeeSet(
+    uint256 registerExecutorFeeValueWei
+)
+
+
+
+
+

SetExecutorsExcessAmountRefunded#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
event SetExecutorsExcessAmountRefunded(
+    address owner,
+    uint256 excessAmount
+)
+
+
+
+
+
+

Functions#

+
+

accountToDelegationAccount#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function accountToDelegationAccount(
+    address _owner
+) external view returns (
+    address);
+
+

Gets the PDA of an account.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressAccount to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]addressAddress of its PDA or address(0) if it has not been created yet.
+
+
+
+

allowedClaimRecipients#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function allowedClaimRecipients(
+    address _rewardOwner
+) external view returns (
+    address[]);
+
+

Gets the addresses of recipients allowed to receive rewards on behalf of an account. +Beside these, the owner of the rewards is always authorized. +See setAllowedClaimRecipients.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardOwneraddressThe account to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]address[]Addresses of all set authorized recipients.
+
+
+
+

batchDelegate#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function batchDelegate(
+    address[] _delegatees,
+    uint256[] _bips
+) external;
+
+

Undelegates all percentage delegations from the caller's +PDA and then delegate to a list of accounts.

+

See delegate.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_delegateesaddress[]The addresses of the new recipients.
_bipsuint256[]The percentage of voting power to be delegated to each delegatee, expressed in basis points (1/100 of one percent). Total of all _bips values must be lower than 10000.
+
+
+
+

claimExecutors#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function claimExecutors(
+    address _owner
+) external view returns (
+    address[]);
+
+

Gets the addresses of executors authorized to claim for an account. +See setClaimExecutors.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe account to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]address[]Addresses of all set executors.
+
+
+
+

delegate#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function delegate(
+    address _to,
+    uint256 _bips
+) external;
+
+

Delegates a percentage of the caller's +PDA's voting power to another address.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_toaddressThe address of the recipient.
_bipsuint256The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: Every call resets the delegation value. A value of 0 revokes delegation.
+
+
+
+

delegateGovernance#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function delegateGovernance(
+    address _to
+) external;
+
+

Delegates all the governance vote power of the caller's +PDA to another account.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_toaddressAddress of the recipient of the delegation.
+
+
+
+

disableDelegationAccount#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function disableDelegationAccount(
+) external;
+
+

Disables the +Personal Delegation Account (PDA).

+

When using automatic claiming, all airdrops and FTSO rewards will be sent to the owner's account. +Rewards accrued by the PDA will no longer be automatically claimed.

+

Reverts if there is no PDA.

+
+
+
+

enableDelegationAccount#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function enableDelegationAccount(
+) external returns (
+    contract IDelegationAccount);
+
+

Enables (or creates) a +Personal Delegation Account (PDA).

+

When using automatic claiming, all airdrops and FTSO rewards will be sent to the PDA, and any rewards +accrued by the PDA will be claimed too.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]contract IDelegationAccountAddress of the delegation account contract.
+
+
+
+

getDelegationAccountData#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function getDelegationAccountData(
+    address _owner
+) external view returns (
+    contract IDelegationAccount _delegationAccount,
+    bool _enabled);
+
+

Gets PDA data for an account.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressAccount to query.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_delegationAccountcontract IDelegationAccountAccount's PDA address or address(0) if it has not been created yet.
_enabledboolWhether the PDA is enabled.
+
+
+
+

getExecutorCurrentFeeValue#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function getExecutorCurrentFeeValue(
+    address _executor
+) external view returns (
+    uint256);
+
+

Returns the current fee of a registered executor. +Reverts if the executor is not registered.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_executoraddressThe executor to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Fee in wei.
+
+
+
+

getExecutorFeeValue#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function getExecutorFeeValue(
+    address _executor,
+    uint256 _rewardEpoch
+) external view returns (
+    uint256);
+
+

Returns the fee of an executor at a given reward epoch.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_executoraddressThe executor to query.
_rewardEpochuint256Reward Epoch ID to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Fee in wei at that reward epoch.
+
+
+
+

getExecutorInfo#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function getExecutorInfo(
+    address _executor
+) external view returns (
+    bool _registered,
+    uint256 _currentFeeValue);
+
+

Returns information about an executor.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_executoraddressThe executor to query.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_registeredboolWhether the executor is registered.
_currentFeeValueuint256Executor's current fee value, if registered.
+
+
+
+

getExecutorScheduledFeeValueChanges#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function getExecutorScheduledFeeValueChanges(
+    address _executor
+) external view returns (
+    uint256[] _feeValue,
+    uint256[] _validFromEpoch,
+    bool[] _fixed);
+
+

Returns the currently scheduled fee changes of an executor.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_executoraddressExecutor to query.
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_feeValueuint256[]Array of scheduled fees.
_validFromEpochuint256[]Array of reward epochs ID where the scheduled fees will become effective.
_fixedbool[]Array of booleans indicating if an scheduled fee change is fixed or it might still be changed.
+
+
+
+

getRegisteredExecutors#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function getRegisteredExecutors(
+    uint256 _start,
+    uint256 _end
+) external view returns (
+    address[] _registeredExecutors,
+    uint256 _totalLength);
+
+

Returns the list of executors registered through registerExecutor. +Supports paging.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_startuint256First executor to return.
_enduint256Last executor to return.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_registeredExecutorsaddress[]Addresses of the registered executors.
_totalLengthuint256Total amount of executors.
+
+
+
+

isClaimExecutor#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function isClaimExecutor(
+    address _owner,
+    address _executor
+) external view returns (
+    bool);
+
+

Returns whether an executor is authorized to claim on behalf of a reward owner. +See setClaimExecutors.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe reward owner to query.
_executoraddressThe executor to query.
+
+
+
+

registerExecutor#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function registerExecutor(
+    uint256 _feeValue
+) external payable returns (
+    uint256);
+
+

Registers the caller as an executor and sets its initial fee value.

+

If the executor was already registered, this method only updates the fee, which will take effect after +feeValueUpdateOffset reward epochs have elapsed.

+

Executor must pay a fee in order to register. See registerExecutorFeeValueWei.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_feeValueuint256Desired fee, in wei. Must be between minFeeValueWei and maxFeeValueWei. 0 means no fee.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Reward epoch ID when the changes become effective.
+
+
+
+

revokeDelegationAt#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function revokeDelegationAt(
+    address _who,
+    uint256 _blockNumber
+) external;
+
+

Revokes all delegation from the caller's PDA +to a given account at a given block.

+

Only affects the reads via votePowerOfAtCached() in the specified block.

+

This method should be used only to prevent rogue delegate voting in the current voting block. +To stop delegating use delegate with percentage of 0 or undelegateAll.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe account to revoke.
_blockNumberuint256Block number where the revoking will take place. Must be in the past.
+
+
+
+

setAllowedClaimRecipients#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function setAllowedClaimRecipients(
+    address[] _recipients
+) external;
+
+

Set the addresses of allowed recipients. +The reward owner is always an allowed recipient.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_recipientsaddress[]The new allowed recipients. All old recipients will be deleted and replaced by these.
+
+
+
+

setAutoClaiming#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function setAutoClaiming(
+    address[] _executors,
+    bool _enableDelegationAccount
+) external payable;
+
+

Sets the addresses of executors and optionally enables (creates) a +Personal Delegation Account (PDA).

+

If any of the executors is a registered executor, some fee needs to be paid.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_executorsaddress[]The new executors. All old executors will be deleted and replaced by these.
_enableDelegationAccountboolWhether the PDA should be enabled.
+
+
+
+

setClaimExecutors#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function setClaimExecutors(
+    address[] _executors
+) external payable;
+
+

Sets the addresses of executors.

+

If any of the executors is a registered executor, some fee needs to be paid.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_executorsaddress[]The new executors. All old executors will be deleted and replaced by these.
+
+
+
+

transferExternalToken#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function transferExternalToken(
+    contract IERC20 _token,
+    uint256 _amount
+) external;
+
+

Allows the caller to transfer ERC-20 tokens from their +PDA to the owner account.

+

The main use case is to move ERC-20 tokes received by mistake (by an airdrop, for example) out of the PDA +and into the main account, where they can be more easily managed.

+

Reverts if the target token is the WNat contract: use method withdraw for that.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_tokencontract IERC20Target token contract address.
_amountuint256Amount of tokens to transfer.
+
+
+
+

undelegateAll#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function undelegateAll(
+) external;
+
+

Removes all delegations from the caller's PDA.

+
+
+
+

undelegateGovernance#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function undelegateGovernance(
+) external;
+
+

Undelegates all governance vote power currently delegated by +the caller's PDA.

+
+
+
+

unregisterExecutor#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function unregisterExecutor(
+) external returns (
+    uint256);
+
+

Unregisters the caller as an executor.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Reward epoch ID when the change becomes effective.
+
+
+
+

updateExecutorFeeValue#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function updateExecutorFeeValue(
+    uint256 _feeValue
+) external returns (
+    uint256);
+
+

Sets the caller's executor fee. The caller must be an executor registered through registerExecutor.

+

When called multiple times inside the same reward epoch, only the last value remains.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_feeValueuint256Desired fee, in wei. Must be between minFeeValueWei and maxFeeValueWei. 0 means no fee.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Reward epoch ID when the changes become effective.
+
+
+
+

withdraw#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function withdraw(
+    uint256 _amount
+) external;
+
+

Allows the caller to transfer WNat wrapped tokens from their +PDA to the owner account.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_amountuint256Amount of tokens to transfer, in wei.
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IFlareContractRegistry/index.html b/apis/smart-contracts/IFlareContractRegistry/index.html new file mode 100644 index 000000000..808ea9961 --- /dev/null +++ b/apis/smart-contracts/IFlareContractRegistry/index.html @@ -0,0 +1,4182 @@ + + + + + + + + + + + + + + + + + + IFlareContractRegistry - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

IFlareContractRegistry#

+
+

Source

+
+
+

Interface for the FlareContractRegistry.

+

Entry point for all external dapps that need the latest contract addresses deployed by Flare.

+
+
+

Functions#

+
+

getAllContracts#

+
+

Defined in IFlareContractRegistry (Docs, Source).

+
+
+
function getAllContracts(
+) external view returns (
+    string[] _names,
+    address[] _addresses);
+
+

Returns all contract names and their corresponding addresses.

+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_namesstring[]Array of contract names.
_addressesaddress[]Array of corresponding contract addresses.
+
+
+
+

getContractAddressByHash#

+
+

Defined in IFlareContractRegistry (Docs, Source).

+
+
+
function getContractAddressByHash(
+    bytes32 _nameHash
+) external view returns (
+    address);
+
+

Returns the address of a given contract hash.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_nameHashbytes32Hash of the contract name as: keccak256(abi.encode(name)).
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]addressAddress of the contract, or address(0) if not found.
+
+
+
+

getContractAddressByName#

+
+

Defined in IFlareContractRegistry (Docs, Source).

+
+
+
function getContractAddressByName(
+    string _name
+) external view returns (
+    address);
+
+

Returns the address of a given contract name.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_namestringName of the contract.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]addressAddress of the contract, or address(0) if not found.
+
+
+
+

getContractAddressesByHash#

+
+

Defined in IFlareContractRegistry (Docs, Source).

+
+
+
function getContractAddressesByHash(
+    bytes32[] _nameHashes
+) external view returns (
+    address[]);
+
+

Returns the addresses of a list of contract hashes.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_nameHashesbytes32[]Array of contract name hashes as: keccak256(abi.encode(name)).
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]address[]Array of addresses of the contracts. Any of them might be address(0) if not found.
+
+
+
+

getContractAddressesByName#

+
+

Defined in IFlareContractRegistry (Docs, Source).

+
+
+
function getContractAddressesByName(
+    string[] _names
+) external view returns (
+    address[]);
+
+

Returns the addresses of a list of contract names.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_namesstring[]Array of contract names.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]address[]Array of addresses of the contracts. Any of them might be address(0) if not found.
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IFlareDaemonize/index.html b/apis/smart-contracts/IFlareDaemonize/index.html new file mode 100644 index 000000000..526217acf --- /dev/null +++ b/apis/smart-contracts/IFlareDaemonize/index.html @@ -0,0 +1,4026 @@ + + + + + + + + + + + + + + + + + + IFlareDaemonize - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

IFlareDaemonize#

+
+

Source

+
+
+

Interface for contracts that receive triggers from the FlareDaemon contract.

+
+
+

Functions#

+
+

daemonize#

+
+

Defined in IFlareDaemonize (Docs, Source).

+
+
+
function daemonize(
+) external returns (
+    bool);
+
+

Implement this function to receive a trigger from the FlareDaemon. +The trigger method is called by the validator right at the end of block state transition.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]boolbool Whether the contract is still active after the call. Currently unused.
+
+
+
+

getContractName#

+
+

Defined in IFlareDaemonize (Docs, Source).

+
+
+
function getContractName(
+) external view returns (
+    string);
+
+

Implement this function to allow updating daemonized contracts through the AddressUpdater.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]stringstring Contract name.
+
+
+
+

switchToFallbackMode#

+
+

Defined in IFlareDaemonize (Docs, Source).

+
+
+
function switchToFallbackMode(
+) external returns (
+    bool);
+
+

This function will be called after an error is caught in daemonize. +It will switch the contract to a simpler fallback mode, which hopefully works when full mode doesn't. +Not every contract needs to support fallback mode (FtsoManager does), so this method may be empty. +Switching back to normal mode is left to the contract (typically a governed method call). +This function may be called due to low-gas error, so it shouldn't use more than ~30.000 gas.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]boolTrue if switched to fallback mode, false if already in fallback mode or if fallback mode is not supported.
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IFtso/index.html b/apis/smart-contracts/IFtso/index.html new file mode 100644 index 000000000..113e25c25 --- /dev/null +++ b/apis/smart-contracts/IFtso/index.html @@ -0,0 +1,5049 @@ + + + + + + + + + + + + + + + + + + IFtso - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + +

IFtso#

+
+

Source

+
+
+

Interface for each of the FTSO contracts that handles an asset. +Read the FTSO documentation page +for general information about the FTSO system.

+
+
+

Enums#

+
+

PriceFinalizationType#

+
+

Defined in IFtso (Docs, Source).

+
+
+
enum PriceFinalizationType {
+  NOT_FINALIZED,
+  WEIGHTED_MEDIAN,
+  TRUSTED_ADDRESSES,
+  PREVIOUS_PRICE_COPIED,
+  TRUSTED_ADDRESSES_EXCEPTION,
+  PREVIOUS_PRICE_COPIED_EXCEPTION
+}
+
+

How did a price epoch finalize.

+
    +
  • NOT_FINALIZED: The epoch has not been finalized yet. This is the initial state.
  • +
  • WEIGHTED_MEDIAN: The median was used to calculate the final price. + This is the most common state in normal operation.
  • +
  • TRUSTED_ADDRESSES: Due to low turnout, the final price was calculated using only + the median of trusted addresses.
  • +
  • PREVIOUS_PRICE_COPIED: Due to low turnout and absence of votes from trusted addresses, + the final price was copied from the previous epoch.
  • +
  • TRUSTED_ADDRESSES_EXCEPTION: Due to an exception, the final price was calculated + using only the median of trusted addresses.
  • +
  • PREVIOUS_PRICE_COPIED_EXCEPTION: Due to an exception, the final price was copied + from the previous epoch.
  • +
+
+
+
+

Events#

+
+

LowTurnout#

+
+

Defined in IFtso (Docs, Source).

+
+
+
event LowTurnout(
+    uint256 epochId,
+    uint256 natTurnout,
+    uint256 lowNatTurnoutThresholdBIPS,
+    uint256 timestamp
+)
+
+

Not enough votes were received for this asset during a price epoch that has just ended.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
epochIduint256The ID of the epoch.
natTurnoutuint256Total received vote power, as a percentage of the circulating supply in BIPS.
lowNatTurnoutThresholdBIPSuint256Minimum required vote power, as a percentage of the circulating supply in BIPS. The fact that this number is higher than natTurnout is what triggered this event.
timestampuint256Timestamp of the block where the price epoch ended.
+
+
+
+

PriceEpochInitializedOnFtso#

+
+

Defined in IFtso (Docs, Source).

+
+
+
event PriceEpochInitializedOnFtso(
+    uint256 epochId,
+    uint256 endTime,
+    uint256 timestamp
+)
+
+

All necessary parameters have been set for an epoch and prices can start being revealed. +Note that prices can already be submitted immediately after the previous price epoch submit end time is over.

+

This event is not emitted in fallback mode (see getPriceEpochData).

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
epochIduint256The ID of the epoch that has just started.
endTimeuint256Deadline to submit prices, in seconds since UNIX epoch.
timestampuint256Current on-chain timestamp.
+
+
+
+

PriceFinalized#

+
+

Defined in IFtso (Docs, Source).

+
+
+
event PriceFinalized(
+    uint256 epochId,
+    uint256 price,
+    bool rewardedFtso,
+    uint256 lowIQRRewardPrice,
+    uint256 highIQRRewardPrice,
+    uint256 lowElasticBandRewardPrice,
+    uint256 highElasticBandRewardPrice,
+    enum IFtso.PriceFinalizationType finalizationType,
+    uint256 timestamp
+)
+
+

An epoch has ended and the asset price is available.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
epochIduint256The ID of the epoch that has just ended.
priceuint256The asset's price for that epoch.
rewardedFtsoboolWhether the next 4 parameters contain data.
lowIQRRewardPriceuint256Lowest price in the primary (inter-quartile) reward band.
highIQRRewardPriceuint256Highest price in the primary (inter-quartile) reward band.
lowElasticBandRewardPriceuint256Lowest price in the secondary (elastic) reward band.
highElasticBandRewardPriceuint256Highest price in the secondary (elastic) reward band.
finalizationTypeenum IFtso.PriceFinalizationTypeReason for the finalization of the epoch.
timestampuint256Timestamp of the block where the price has been finalized.
+
+
+
+

PriceRevealed#

+
+

Defined in IFtso (Docs, Source).

+
+
+
event PriceRevealed(
+    address voter,
+    uint256 epochId,
+    uint256 price,
+    uint256 timestamp,
+    uint256 votePowerNat,
+    uint256 votePowerAsset
+)
+
+

A voter has revealed its price.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
voteraddressThe voter.
epochIduint256The ID of the epoch for which the price has been revealed.
priceuint256The revealed price.
timestampuint256Timestamp of the block where the reveal happened.
votePowerNatuint256Vote power of the voter in this epoch. This includes the vote power derived from its WNat holdings and the delegations.
votePowerAssetuint256Unused.
+
+
+
+
+

Functions#

+
+

active#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function active(
+) external view returns (
+    bool);
+
+

Returns whether FTSO is active or not.

+
+
+
+

getCurrentEpochId#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function getCurrentEpochId(
+) external view returns (
+    uint256);
+
+

Returns the current epoch ID.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Currently running epoch ID. IDs are consecutive numbers starting from zero.
+
+
+
+

getCurrentPrice#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function getCurrentPrice(
+) external view returns (
+    uint256 _price,
+    uint256 _timestamp);
+
+

Returns the current asset price.

+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Price in USD multiplied by 10^ASSET_PRICE_USD_DECIMALS.
_timestampuint256Time when price was updated for the last time, in seconds from UNIX epoch.
+
+
+
+

getCurrentPriceDetails#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function getCurrentPriceDetails(
+) external view returns (
+    uint256 _price,
+    uint256 _priceTimestamp,
+    enum IFtso.PriceFinalizationType _priceFinalizationType,
+    uint256 _lastPriceEpochFinalizationTimestamp,
+    enum IFtso.PriceFinalizationType _lastPriceEpochFinalizationType);
+
+

Returns asset's current price details. +All timestamps are in seconds from UNIX epoch.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Price in USD multiplied by 10^ASSET_PRICE_USD_DECIMALS.
_priceTimestampuint256Time when price was updated for the last time.
_priceFinalizationTypeenum IFtso.PriceFinalizationTypeFinalization type when price was updated for the last time.
_lastPriceEpochFinalizationTimestampuint256Time when last price epoch was finalized.
_lastPriceEpochFinalizationTypeenum IFtso.PriceFinalizationTypeFinalization type of last finalized price epoch.
+
+
+
+

getCurrentPriceFromTrustedProviders#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function getCurrentPriceFromTrustedProviders(
+) external view returns (
+    uint256 _price,
+    uint256 _timestamp);
+
+

Returns current asset price calculated only using input from trusted providers.

+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Price in USD multiplied by 10^ASSET_PRICE_USD_DECIMALS.
_timestampuint256Time when price was updated for the last time, in seconds from UNIX epoch.
+
+
+
+

getCurrentPriceWithDecimals#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function getCurrentPriceWithDecimals(
+) external view returns (
+    uint256 _price,
+    uint256 _timestamp,
+    uint256 _assetPriceUsdDecimals);
+
+

Returns current asset price and number of decimals.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Price in USD multiplied by 10^_assetPriceUsdDecimals.
_timestampuint256Time when price was updated for the last time, in seconds from UNIX epoch.
_assetPriceUsdDecimalsuint256Number of decimals used to return the USD price.
+
+
+
+

getCurrentPriceWithDecimalsFromTrustedProviders#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function getCurrentPriceWithDecimalsFromTrustedProviders(
+) external view returns (
+    uint256 _price,
+    uint256 _timestamp,
+    uint256 _assetPriceUsdDecimals);
+
+

Returns current asset price calculated only using input from trusted providers and number of decimals.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Price in USD multiplied by 10^ASSET_PRICE_USD_DECIMALS.
_timestampuint256Time when price was updated for the last time, in seconds from UNIX epoch.
_assetPriceUsdDecimalsuint256Number of decimals used to return the USD price.
+
+
+
+

getCurrentRandom#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function getCurrentRandom(
+) external view returns (
+    uint256);
+
+

Returns the random number for the previous price epoch, obtained from the random numbers +provided by all data providers along with their data submissions.

+
+
+
+

getEpochId#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function getEpochId(
+    uint256 _timestamp
+) external view returns (
+    uint256);
+
+

Returns the ID of the epoch that was opened for price submission at the specified timestamp.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_timestampuint256Queried timestamp in seconds from UNIX epoch.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Epoch ID corresponding to that timestamp. IDs are consecutive numbers starting from zero.
+
+
+
+

getEpochPrice#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function getEpochPrice(
+    uint256 _epochId
+) external view returns (
+    uint256);
+
+

Returns agreed asset price in the specified epoch.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_epochIduint256ID of the epoch. Only the last 200 epochs can be queried. Out-of-bounds queries revert.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Price in USD multiplied by 10^ASSET_PRICE_USD_DECIMALS.
+
+
+
+

getEpochPriceForVoter#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function getEpochPriceForVoter(
+    uint256 _epochId,
+    address _voter
+) external view returns (
+    uint256);
+
+

Returns asset price submitted by a voter in the specified epoch.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_epochIduint256ID of the epoch being queried. Only the last 200 epochs can be queried. Out-of-bounds queries revert.
_voteraddressAddress of the voter being queried.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Price in USD multiplied by 10^ASSET_PRICE_USD_DECIMALS.
+
+
+
+

getPriceEpochConfiguration#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function getPriceEpochConfiguration(
+) external view returns (
+    uint256 _firstEpochStartTs,
+    uint256 _submitPeriodSeconds,
+    uint256 _revealPeriodSeconds);
+
+

Returns current epoch's configuration.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_firstEpochStartTsuint256First epoch start timestamp in seconds from UNIX epoch.
_submitPeriodSecondsuint256Submit period in seconds.
_revealPeriodSecondsuint256Reveal period in seconds.
+
+
+
+

getPriceEpochData#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function getPriceEpochData(
+) external view returns (
+    uint256 _epochId,
+    uint256 _epochSubmitEndTime,
+    uint256 _epochRevealEndTime,
+    uint256 _votePowerBlock,
+    bool _fallbackMode);
+
+

Returns current epoch data. +Intervals are open on the right: End times are not included.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_epochIduint256Current epoch ID.
_epochSubmitEndTimeuint256End time of the price submission window in seconds from UNIX epoch.
_epochRevealEndTimeuint256End time of the price reveal window in seconds from UNIX epoch.
_votePowerBlockuint256Vote power block for the current epoch.
_fallbackModeboolWhether the current epoch is in fallback mode. Only votes from trusted addresses are used in this mode.
+
+
+
+

getRandom#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function getRandom(
+    uint256 _epochId
+) external view returns (
+    uint256);
+
+

Returns the random number used in a specific past epoch, obtained from the random numbers +provided by all data providers along with their data submissions.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_epochIduint256ID of the queried epoch. Current epoch cannot be queried, and the previous epoch is constantly updated as data providers reveal their prices and random numbers. Only the last 50 epochs can be queried and there is no bounds checking for this parameter. Out-of-bounds queries return undefined values.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The random number used in that epoch.
+
+
+
+

symbol#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function symbol(
+) external view returns (
+    string);
+
+

Returns the FTSO symbol.

+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IFtsoGenesis/index.html b/apis/smart-contracts/IFtsoGenesis/index.html new file mode 100644 index 000000000..eaaf542e5 --- /dev/null +++ b/apis/smart-contracts/IFtsoGenesis/index.html @@ -0,0 +1,4020 @@ + + + + + + + + + + + + + + + + + + IFtsoGenesis - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

IFtsoGenesis#

+
+

Source

+
+
+

Portion of the IFtso interface that is available to contracts deployed at genesis.

+
+
+

Functions#

+
+

revealPriceSubmitter#

+
+

Defined in IFtsoGenesis (Docs, Source).

+
+
+
function revealPriceSubmitter(
+    address _voter,
+    uint256 _epochId,
+    uint256 _price,
+    uint256 _voterWNatVP
+) external;
+
+

Reveals the price submitted by a voter on a specific epoch. +The hash of _price and _random must be equal to the submitted hash

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_voteraddressVoter address.
_epochIduint256ID of the epoch in which the price hash was submitted.
_priceuint256Submitted price.
_voterWNatVPuint256Voter's vote power in WNat units.
+
+
+
+

wNatVotePowerCached#

+
+

Defined in IFtsoGenesis (Docs, Source).

+
+
+
function wNatVotePowerCached(
+    address _voter,
+    uint256 _epochId
+) external returns (
+    uint256);
+
+

Get and cache the vote power of a voter on a specific epoch, in WNat units.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_voteraddressVoter address.
_epochIduint256ID of the epoch in which the price hash was submitted.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Voter's vote power in WNat units.
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IFtsoManager/index.html b/apis/smart-contracts/IFtsoManager/index.html new file mode 100644 index 000000000..1d201799c --- /dev/null +++ b/apis/smart-contracts/IFtsoManager/index.html @@ -0,0 +1,4931 @@ + + + + + + + + + + + + + + + + + + IFtsoManager - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + +

IFtsoManager#

+
+

Source | Inherits from IFtsoManagerGenesis

+
+
+

Interface for the FtsoManager contract.

+
+
+

Events#

+
+

AccruingUnearnedRewardsFailed#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
event AccruingUnearnedRewardsFailed(
+    uint256 epochId
+)
+
+

Unexpected failure while accruing unearned rewards. +This should be a rare occurrence.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
epochIduint256Epoch ID of the failure.
+
+
+
+

DistributingRewardsFailed#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
event DistributingRewardsFailed(
+    address ftso,
+    uint256 epochId
+)
+
+

Unexpected failure while distributing rewards. +This should be a rare occurrence.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
ftsoaddressContract address of the FTSO where the failure happened.
epochIduint256Epoch ID of the failure.
+
+
+
+

FallbackMode#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
event FallbackMode(
+    bool fallbackMode
+)
+
+

Emitted when the fallback mode of the FTSO manager changes its state. +Fallback mode is a recovery mode, where only data from a trusted subset of FTSO +data providers is used to calculate the final price.

+

The FTSO Manager enters the fallback mode when ALL FTSOs are in fallback mode.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
fallbackModeboolNew state of the FTSO Manager fallback mode.
+
+
+
+

FinalizingPriceEpochFailed#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
event FinalizingPriceEpochFailed(
+    contract IIFtso ftso,
+    uint256 epochId,
+    enum IFtso.PriceFinalizationType failingType
+)
+
+

Unexpected failure while finalizing a price epoch. +This should be a rare occurrence.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
ftsocontract IIFtsoContract address of the FTSO where the failure happened.
epochIduint256Epoch ID of the failure.
failingTypeenum IFtso.PriceFinalizationTypeHow was the epoch finalized.
+
+
+
+

FtsoAdded#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
event FtsoAdded(
+    contract IIFtso ftso,
+    bool add
+)
+
+

Emitted when a new FTSO has been added or an existing one has been removed.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
ftsocontract IIFtsoContract address of the FTSO.
addboolTrue if added, removed otherwise.
+
+
+
+

FtsoFallbackMode#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
event FtsoFallbackMode(
+    contract IIFtso ftso,
+    bool fallbackMode
+)
+
+

Emitted when the fallback mode of an FTSO changes its state.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
ftsocontract IIFtsoContract address of the FTSO.
fallbackModeboolNew state of its fallback mode.
+
+
+
+

InitializingCurrentEpochStateForRevealFailed#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
event InitializingCurrentEpochStateForRevealFailed(
+    contract IIFtso ftso,
+    uint256 epochId
+)
+
+

Unexpected failure while initializing a price epoch. +This should be a rare occurrence.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
ftsocontract IIFtsoContract address of the FTSO where the failure happened.
epochIduint256Epoch ID that failed initialization.
+
+
+
+

PriceEpochFinalized#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
event PriceEpochFinalized(
+    address chosenFtso,
+    uint256 rewardEpochId
+)
+
+

Emitted when a price epoch ends, this is, +after the reveal phase, when final prices are calculated.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
chosenFtsoaddressContract address of the FTSO asset that was randomly chosen to be the basis for reward calculation. On this price epoch, rewards will be calculated based on how close each data provider was to the median of all submitted prices FOR THIS FTSO.
rewardEpochIduint256Reward epoch ID this price epoch belongs to.
+
+
+
+

RewardEpochFinalized#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
event RewardEpochFinalized(
+    uint256 votepowerBlock,
+    uint256 startBlock
+)
+
+

Emitted when a reward epoch +ends and rewards are available.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
votepowerBlockuint256The vote power block of the epoch.
startBlockuint256The first block of the epoch.
+
+
+
+

UseGoodRandomSet#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
event UseGoodRandomSet(
+    bool useGoodRandom,
+    uint256 maxWaitForGoodRandomSeconds
+)
+
+

Emitted when the requirement to provide good random numbers has changed.

+

As part of the FTSO protocol, +data providers must submit a random number along with their price reveals. +When good random numbers are enforced, all providers that submit a hash must then +submit a reveal with a random number or they will be punished. +This is a measure against random number manipulation.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
useGoodRandomboolWhether good random numbers are now enforced or not.
maxWaitForGoodRandomSecondsuint256Max number of seconds to wait for a good random number to be submitted.
+
+
+
+
+

Functions#

+
+

active#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
function active(
+) external view returns (
+    bool);
+
+

Returns whether the FTSO Manager is active or not.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]boolbool Active status.
+
+
+
+

getCurrentPriceEpochData#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
function getCurrentPriceEpochData(
+) external view returns (
+    uint256 _priceEpochId,
+    uint256 _priceEpochStartTimestamp,
+    uint256 _priceEpochEndTimestamp,
+    uint256 _priceEpochRevealEndTimestamp,
+    uint256 _currentTimestamp);
+
+

Returns timing information for the current price epoch. +All intervals are half-closed: end time is not included. +All timestamps are in seconds since UNIX epoch.

+

See the FTSO page +for information about the different submission phases.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceEpochIduint256Price epoch ID.
_priceEpochStartTimestampuint256Beginning of the commit phase.
_priceEpochEndTimestampuint256End of the commit phase.
_priceEpochRevealEndTimestampuint256End of the reveal phase.
_currentTimestampuint256Current time.
+
+
+
+

getCurrentPriceEpochId#

+
+

Defined in IFtsoManagerGenesis (Docs, Source).

+
+
+
function getCurrentPriceEpochId(
+) external view returns (
+    uint256 _priceEpochId);
+
+

Returns current price epoch ID.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceEpochIduint256Currently running epoch ID. IDs are consecutive numbers starting from zero.
+
+
+
+

getCurrentRewardEpoch#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
function getCurrentRewardEpoch(
+) external view returns (
+    uint256);
+
+

Returns current reward epoch ID (the one currently running).

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Reward epoch ID. A monotonically increasing integer.
+
+
+
+

getFallbackMode#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
function getFallbackMode(
+) external view returns (
+    bool _fallbackMode,
+    contract IIFtso[] _ftsos,
+    bool[] _ftsoInFallbackMode);
+
+

Returns whether the FTSO Manager is currently in fallback mode.

+

In this mode only submissions from trusted providers are used.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_fallbackModeboolTrue if fallback mode is enabled for the manager.
_ftsoscontract IIFtso[]Array of all currently active FTSO assets.
_ftsoInFallbackModebool[]Boolean array indicating which FTSO assets are in fallback mode. If the FTSO Manager is in fallback mode then ALL FTSOs are in fallback mode.
+
+
+
+

getFtsos#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
function getFtsos(
+) external view returns (
+    contract IIFtso[] _ftsos);
+
+

Returns the list of currently active FTSOs.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_ftsoscontract IIFtso[]Array of contract addresses for the FTSOs.
+
+
+
+

getPriceEpochConfiguration#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
function getPriceEpochConfiguration(
+) external view returns (
+    uint256 _firstPriceEpochStartTs,
+    uint256 _priceEpochDurationSeconds,
+    uint256 _revealEpochDurationSeconds);
+
+

Returns the current values for price epoch timing configuration.

+

See the FTSO page +for information about the different submission phases.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_firstPriceEpochStartTsuint256Timestamp, in seconds since UNIX epoch, of the first price epoch.
_priceEpochDurationSecondsuint256Duration in seconds of the commit phase.
_revealEpochDurationSecondsuint256Duration in seconds of the reveal phase.
+
+
+
+

getRewardEpochConfiguration#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
function getRewardEpochConfiguration(
+) external view returns (
+    uint256 _firstRewardEpochStartTs,
+    uint256 _rewardEpochDurationSeconds);
+
+

Returns the current values for reward epoch timing configuration.

+

See the Reward epochs box.

+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_firstRewardEpochStartTsuint256Timestamp, in seconds since UNIX epoch, of the first reward epoch.
_rewardEpochDurationSecondsuint256Duration in seconds of the reward epochs.
+
+
+
+

getRewardEpochToExpireNext#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
function getRewardEpochToExpireNext(
+) external view returns (
+    uint256);
+
+

Return reward epoch that will expire next, when a new reward epoch is initialized.

+

Reward epochs older than 90 days expire, and any unclaimed rewards in them become +inaccessible.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256uint256 Reward epoch ID.
+
+
+
+

getRewardEpochVotePowerBlock#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
function getRewardEpochVotePowerBlock(
+    uint256 _rewardEpoch
+) external view returns (
+    uint256);
+
+

Returns the vote power block +that was used for a past reward epoch.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardEpochuint256The queried reward epoch ID.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256uint256 The block number of that reward epoch's vote power block.
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IFtsoManagerGenesis/index.html b/apis/smart-contracts/IFtsoManagerGenesis/index.html new file mode 100644 index 000000000..d4bc52e04 --- /dev/null +++ b/apis/smart-contracts/IFtsoManagerGenesis/index.html @@ -0,0 +1,3935 @@ + + + + + + + + + + + + + + + + + + IFtsoManagerGenesis - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

IFtsoManagerGenesis#

+
+

Source

+
+
+

Portion of the IFtsoManager interface that is available to contracts deployed at genesis.

+
+
+

Functions#

+
+

getCurrentPriceEpochId#

+
+

Defined in IFtsoManagerGenesis (Docs, Source).

+
+
+
function getCurrentPriceEpochId(
+) external view returns (
+    uint256 _priceEpochId);
+
+

Returns current price epoch ID.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceEpochIduint256Currently running epoch ID. IDs are consecutive numbers starting from zero.
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IFtsoRegistry/index.html b/apis/smart-contracts/IFtsoRegistry/index.html new file mode 100644 index 000000000..afee3c69f --- /dev/null +++ b/apis/smart-contracts/IFtsoRegistry/index.html @@ -0,0 +1,5040 @@ + + + + + + + + + + + + + + + + + + IFtsoRegistry - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + +

IFtsoRegistry#

+
+

Source | Inherits from IFtsoRegistryGenesis

+
+
+

Interface for the FtsoRegistry contract.

+
+
+

Functions#

+
+

getAllCurrentPrices#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getAllCurrentPrices(
+) external view returns (
+    struct IFtsoRegistry.PriceInfo[]);
+
+

Returns the current price of all supported assets.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]struct IFtsoRegistry.PriceInfo[]Array of PriceInfo structures.
+
+
+
+

getCurrentPrice#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getCurrentPrice(
+    uint256 _ftsoIndex
+) external view returns (
+    uint256 _price,
+    uint256 _timestamp);
+
+

Public view function to get the current price of a given active FTSO index. +Reverts if the index is not supported.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsoIndexuint256Index to query.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Current price of the asset in USD multiplied by 10^ASSET_PRICE_USD_DECIMALS.
_timestampuint256Timestamp for when this price was updated, in seconds since UNIX epoch.
+
+
+
+

getCurrentPrice#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getCurrentPrice(
+    string _symbol
+) external view returns (
+    uint256 _price,
+    uint256 _timestamp);
+
+

Public view function to get the current price of a given active asset symbol. +Reverts if the symbol is not supported.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_symbolstringSymbol to query.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Current price of the asset in USD multiplied by 10^ASSET_PRICE_USD_DECIMALS.
_timestampuint256Timestamp for when this price was updated, in seconds since UNIX epoch.
+
+
+
+

getCurrentPriceWithDecimals#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getCurrentPriceWithDecimals(
+    uint256 _assetIndex
+) external view returns (
+    uint256 _price,
+    uint256 _timestamp,
+    uint256 _assetPriceUsdDecimals);
+
+

Public view function to get the current price and decimals of a given active FTSO index. +Reverts if the index is not supported.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_assetIndexuint256Index to query.
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Current price of the asset in USD multiplied by 10^_assetPriceUsdDecimals.
_timestampuint256Timestamp for when this price was updated, in seconds since UNIX epoch.
_assetPriceUsdDecimalsuint256Number of decimals used to return the _price.
+
+
+
+

getCurrentPriceWithDecimals#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getCurrentPriceWithDecimals(
+    string _symbol
+) external view returns (
+    uint256 _price,
+    uint256 _timestamp,
+    uint256 _assetPriceUsdDecimals);
+
+

Public view function to get the current price and decimals of a given active asset symbol. +Reverts if the symbol is not supported.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_symbolstringSymbol to query.
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Current price of the asset in USD multiplied by 10^_assetPriceUsdDecimals.
_timestampuint256Timestamp for when this price was updated, in seconds since UNIX epoch.
_assetPriceUsdDecimalsuint256Number of decimals used to return the _price.
+
+
+
+

getCurrentPricesByIndices#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getCurrentPricesByIndices(
+    uint256[] _indices
+) external view returns (
+    struct IFtsoRegistry.PriceInfo[]);
+
+

Returns the current price of a list of indices. +Reverts if any of the indices is not supported.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_indicesuint256[]Array of indices to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]struct IFtsoRegistry.PriceInfo[]Array of PriceInfo structures.
+
+
+
+

getCurrentPricesBySymbols#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getCurrentPricesBySymbols(
+    string[] _symbols
+) external view returns (
+    struct IFtsoRegistry.PriceInfo[]);
+
+

Returns the current price of a list of asset symbols. +Reverts if any of the symbols is not supported.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_symbolsstring[]Array of symbols to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]struct IFtsoRegistry.PriceInfo[]Array of PriceInfo structures.
+
+
+
+

getFtso#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getFtso(
+    uint256 _activeFtso
+) external view returns (
+    contract IIFtso _activeFtsoAddress);
+
+

Returns the address of the FTSO contract for a given index. +Reverts if unsupported index is passed.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_activeFtsouint256The queried index.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_activeFtsoAddresscontract IIFtsoFTSO contract address for the queried index.
+
+
+
+

getFtsoBySymbol#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getFtsoBySymbol(
+    string _symbol
+) external view returns (
+    contract IIFtso _activeFtsoAddress);
+
+

Returns the address of the FTSO contract for a given symbol. +Reverts if unsupported symbol is passed.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_symbolstringThe queried symbol.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_activeFtsoAddresscontract IIFtsoFTSO contract address for the queried symbol.
+
+
+
+

getFtsoIndex#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getFtsoIndex(
+    string _symbol
+) external view returns (
+    uint256 _assetIndex);
+
+

Returns the FTSO index corresponding to a given asset symbol. +Reverts if the symbol is not supported.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_symbolstringSymbol to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_assetIndexuint256The corresponding asset index.
+
+
+
+

getFtsoSymbol#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getFtsoSymbol(
+    uint256 _ftsoIndex
+) external view returns (
+    string _symbol);
+
+

Returns the asset symbol corresponding to a given FTSO index. +Reverts if the index is not supported.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsoIndexuint256Index to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_symbolstringThe corresponding asset symbol.
+
+
+
+

getFtsos#

+
+

Defined in IFtsoRegistryGenesis (Docs, Source).

+
+
+
function getFtsos(
+    uint256[] _indices
+) external view returns (
+    contract IFtsoGenesis[] _ftsos);
+
+

Get the addresses of the active FTSOs at the given indices. +Reverts if any of the provided indices is non-existing or inactive.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_indicesuint256[]Array of FTSO indices to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_ftsoscontract IFtsoGenesis[]The array of FTSO addresses.
+
+
+
+

getSupportedFtsos#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getSupportedFtsos(
+) external view returns (
+    contract IIFtso[] _ftsos);
+
+

Get array of all FTSO contracts for all supported asset indices. +The index of FTSO in returned array does not necessarily correspond to the asset's index. +Due to deletion, some indices might be unsupported.

+

Use getSupportedIndicesAndFtsos to retrieve pairs of correct indices and FTSOs, +where possible "null" holes are readily apparent.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_ftsoscontract IIFtso[]Array of all supported FTSOs.
+
+
+
+

getSupportedIndices#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getSupportedIndices(
+) external view returns (
+    uint256[] _supportedIndices);
+
+

Returns the indices of the currently supported FTSOs. +Active FTSOs are ones that currently receive price feeds.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_supportedIndicesuint256[]Array of all active FTSO indices in increasing order.
+
+
+
+

getSupportedIndicesAndFtsos#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getSupportedIndicesAndFtsos(
+) external view returns (
+    uint256[] _supportedIndices,
+    contract IIFtso[] _ftsos);
+
+

Get all supported indices and corresponding FTSO addresses. +Active FTSOs are ones that currently receive price feeds.

+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_supportedIndicesuint256[]Array of all supported indices.
_ftsoscontract IIFtso[]Array of all supported FTSO addresses.
+
+
+
+

getSupportedIndicesAndSymbols#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getSupportedIndicesAndSymbols(
+) external view returns (
+    uint256[] _supportedIndices,
+    string[] _supportedSymbols);
+
+

Get all supported indices and corresponding symbols. +Active FTSOs are ones that currently receive price feeds.

+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_supportedIndicesuint256[]Array of all supported indices.
_supportedSymbolsstring[]Array of all supported symbols.
+
+
+
+

getSupportedIndicesSymbolsAndFtsos#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getSupportedIndicesSymbolsAndFtsos(
+) external view returns (
+    uint256[] _supportedIndices,
+    string[] _supportedSymbols,
+    contract IIFtso[] _ftsos);
+
+

Get all supported indices, symbols, and corresponding FTSO addresses. +Active FTSOs are ones that currently receive price feeds.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_supportedIndicesuint256[]Array of all supported indices.
_supportedSymbolsstring[]Array of all supported symbols.
_ftsoscontract IIFtso[]Array of all supported FTSO addresses.
+
+
+
+

getSupportedSymbols#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getSupportedSymbols(
+) external view returns (
+    string[] _supportedSymbols);
+
+

Returns the symbols of the currently supported FTSOs. +Active FTSOs are ones that currently receive price feeds.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_supportedSymbolsstring[]Array of all active FTSO symbols in increasing order.
+
+
+
+

getSupportedSymbolsAndFtsos#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getSupportedSymbolsAndFtsos(
+) external view returns (
+    string[] _supportedSymbols,
+    contract IIFtso[] _ftsos);
+
+

Get all supported symbols and corresponding FTSO addresses. +Active FTSOs are ones that currently receive price feeds.

+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_supportedSymbolsstring[]Array of all supported symbols.
_ftsoscontract IIFtso[]Array of all supported FTSO addresses.
+
+
+
+
+

Structures#

+
+

PriceInfo#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
struct PriceInfo {
+  uint256 ftsoIndex;
+  uint256 price;
+  uint256 decimals;
+  uint256 timestamp;
+}
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IFtsoRegistryGenesis/index.html b/apis/smart-contracts/IFtsoRegistryGenesis/index.html new file mode 100644 index 000000000..27825c13e --- /dev/null +++ b/apis/smart-contracts/IFtsoRegistryGenesis/index.html @@ -0,0 +1,3953 @@ + + + + + + + + + + + + + + + + + + IFtsoRegistryGenesis - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

IFtsoRegistryGenesis#

+
+

Source

+
+
+

Portion of the IFtsoRegistry interface that is available to contracts deployed at genesis.

+
+
+

Functions#

+
+

getFtsos#

+
+

Defined in IFtsoRegistryGenesis (Docs, Source).

+
+
+
function getFtsos(
+    uint256[] _indices
+) external view returns (
+    contract IFtsoGenesis[] _ftsos);
+
+

Get the addresses of the active FTSOs at the given indices. +Reverts if any of the provided indices is non-existing or inactive.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_indicesuint256[]Array of FTSO indices to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_ftsoscontract IFtsoGenesis[]The array of FTSO addresses.
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IFtsoRewardManager/index.html b/apis/smart-contracts/IFtsoRewardManager/index.html new file mode 100644 index 000000000..430d5e4dc --- /dev/null +++ b/apis/smart-contracts/IFtsoRewardManager/index.html @@ -0,0 +1,5682 @@ + + + + + + + + + + + + + + + + + + IFtsoRewardManager - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + +

IFtsoRewardManager#

+
+

Source

+
+
+

Interface for the FtsoRewardManager contract.

+
+
+

Events#

+
+

FeePercentageChanged#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
event FeePercentageChanged(
+    address dataProvider,
+    uint256 value,
+    uint256 validFromEpoch
+)
+
+

Emitted when a data provider changes its fee.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
dataProvideraddressAddress of the data provider.
valueuint256New fee, in BIPS.
validFromEpochuint256Epoch ID where the new fee takes effect.
+
+
+
+

FtsoRewardManagerActivated#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
event FtsoRewardManagerActivated(
+    address ftsoRewardManager
+)
+
+

Emitted when the reward manager contract is activated.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
ftsoRewardManageraddressThe reward manager contract.
+
+
+
+

FtsoRewardManagerDeactivated#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
event FtsoRewardManagerDeactivated(
+    address ftsoRewardManager
+)
+
+

Emitted when the reward manager contract is deactivated.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
ftsoRewardManageraddressThe reward manager contract.
+
+
+
+

RewardClaimed#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
event RewardClaimed(
+    address dataProvider,
+    address whoClaimed,
+    address sentTo,
+    uint256 rewardEpoch,
+    uint256 amount
+)
+
+

Emitted when a data provider claims its FTSO rewards.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
dataProvideraddressAddress of the data provider that accrued the reward.
whoClaimedaddressAddress that actually performed the claim.
sentToaddressAddress that received the reward.
rewardEpochuint256ID of the reward epoch where the reward was accrued.
amountuint256Amount of rewarded native tokens (wei).
+
+
+
+

RewardClaimsEnabled#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
event RewardClaimsEnabled(
+    uint256 rewardEpochId
+)
+
+

Emitted when reward claims have been enabled.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
rewardEpochIduint256First claimable reward epoch.
+
+
+
+

RewardClaimsExpired#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
event RewardClaimsExpired(
+    uint256 rewardEpochId
+)
+
+

Unclaimed rewards have expired and are now inaccessible.

+

getUnclaimedReward() can be used to retrieve more information.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
rewardEpochIduint256ID of the reward epoch that has just expired.
+
+
+
+

RewardsDistributed#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
event RewardsDistributed(
+    address ftso,
+    uint256 epochId,
+    address[] addresses,
+    uint256[] rewards
+)
+
+

Emitted every price epoch, when rewards have been distributed to each contributing data provider. +Note that rewards are not claimable until the reward epoch finishes.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
ftsoaddressAddress of the FTSO that generated the rewards.
epochIduint256ID of the reward epoch where the rewards were accrued.
addressesaddress[]Data provider addresses that have rewards to claim.
rewardsuint256[]Amounts available for claiming (wei).
+
+
+
+

UnearnedRewardsAccrued#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
event UnearnedRewardsAccrued(
+    uint256 epochId,
+    uint256 reward
+)
+
+

Emitted when rewards cannot be distributed during a reward epoch +(for example, because the FTSO went into fallback mode) and they are accrued +for later burning.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
epochIduint256ID of the reward epoch where the reward was accrued.
rewarduint256Total amount of accrued rewards (wei).
+
+
+
+
+

Functions#

+
+

active#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function active(
+) external view returns (
+    bool);
+
+

Whether rewards can be claimed from this reward manager.

+
+
+
+

autoClaim#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function autoClaim(
+    address[] _rewardOwners,
+    uint256 _rewardEpoch
+) external;
+
+

Allows claiming rewards simultaneously for a list of reward owners and all unclaimed epochs before the +specified one.

+

This is meant as a convenience all-in-one reward claiming method to be used both by reward owners and +registered executors. +It performs a series of operations, besides claiming rewards:

+
    +
  • +

    If a reward owner has enabled its +Personal Delegation Account, rewards are also +claimed for the PDA and the total claimed amount is sent to that PDA. +Otherwise, the claimed amount is sent to the reward owner's account.

    +
  • +
  • +

    Claimed amount is automatically wrapped through the WNat contract.

    +
  • +
  • +

    If the caller is a registered executor with a non-zero fee, the fee is paid to the executor for each claimed +address.

    +
  • +
+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardOwnersaddress[]List of reward owners to claim for.
_rewardEpochuint256Last reward epoch ID to claim for. All previous epochs with pending rewards will be claimed too.
+
+
+
+

claim#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function claim(
+    address _rewardOwner,
+    address payable _recipient,
+    uint256 _rewardEpoch,
+    bool _wrap
+) external returns (
+    uint256 _rewardAmount);
+
+

Allows the caller to claim rewards for a reward owner. +The caller does not have to be the owner of the rewards, but must be approved by the owner to claim on his +behalf by using setClaimExecutors on the claimSetupManager.

+

This function is intended to be used to claim rewards in case of delegation by percentage. +Reverts if msg.sender is delegating by amount.

+

Anybody can call this method, but rewards can only be sent to the reward owner, therefore no funds can be +stolen. However, by limiting the authorized callers, the owner can control the timing of the calls.

+

When the reward owner is the caller, rewards can be sent to any recipient set by setAllowedClaimRecipients on +the claimSetupManager. +The reward owner's Personal Delegation Account +is always an authorized recipient.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardOwneraddressAddress of the reward owner.
_recipientaddress payableAddress to transfer claimed rewards to.
_rewardEpochuint256Last reward epoch to claim for. All previous epochs with pending rewards will be claimed too.
_wrapboolWhether claimed rewards should be wrapped through the WNat contract before transferring them to the _recipient. This parameter is offered as a convenience.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_rewardAmountuint256Total amount of claimed rewards (wei).
+
+
+
+

claimFromDataProviders#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function claimFromDataProviders(
+    address _rewardOwner,
+    address payable _recipient,
+    uint256[] _rewardEpochs,
+    address[] _dataProviders,
+    bool _wrap
+) external returns (
+    uint256 _rewardAmount);
+
+

Allows the caller to claim rewards for a reward owner from specific data providers. +The caller does not have to be the owner of the rewards, but must be approved by the owner to claim on his +behalf by using setClaimExecutors on the claimSetupManager.

+

This function is intended to be used to claim rewards in case of delegation by amount (explicit delegation). +Reverts if msg.sender is delegating by percentage.

+

Anybody can call this method, but rewards can only be sent to the reward owner, therefore no funds can be +stolen. However, by limiting the authorized callers, the owner can control the timing of the calls.

+

When the reward owner is the caller, rewards can be sent to any recipient set by setAllowedClaimRecipients on +the claimSetupManager. +The reward owner's Personal Delegation Account +is always an authorized recipient.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardOwneraddressAddress of the reward owner.
_recipientaddress payableAddress to transfer claimed rewards to.
_rewardEpochsuint256[]Array of reward epoch IDs to claim for.
_dataProvidersaddress[]Array of addresses of the data providers to claim the reward from.
_wrapboolWhether claimed rewards should be wrapped through the WNat contract before transferring them to the _recipient. This parameter is offered as a convenience.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_rewardAmountuint256Total amount of claimed rewards (wei).
+
+
+
+

claimReward#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function claimReward(
+    address payable _recipient,
+    uint256[] _rewardEpochs
+) external returns (
+    uint256 _rewardAmount);
+
+

Allows a percentage delegator to claim rewards. +This function is intended to be used to claim rewards in case of delegation by percentage.

+

This function is deprecated: use claim instead.

+

Reverts if msg.sender is delegating by amount. +Claims for all unclaimed reward epochs to the 'max(_rewardEpochs)'. +Retained for backward compatibility.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_recipientaddress payableAddress to transfer funds to.
_rewardEpochsuint256[]Array of reward epoch numbers to claim for.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_rewardAmountuint256Amount of total claimed rewards (wei).
+
+
+
+

claimRewardFromDataProviders#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function claimRewardFromDataProviders(
+    address payable _recipient,
+    uint256[] _rewardEpochs,
+    address[] _dataProviders
+) external returns (
+    uint256 _rewardAmount);
+
+

Allows the caller to claim rewards from specific data providers. +This function is intended to be used to claim rewards in case of delegation by amount.

+

This function is deprecated: use claimFromDataProviders instead.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_recipientaddress payableAddress to transfer funds to.
_rewardEpochsuint256[]Array of reward epoch numbers to claim for.
_dataProvidersaddress[]Array of addresses of the data providers to claim the reward from.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_rewardAmountuint256Total amount of claimed rewards (wei).
+
+
+
+

getClaimedReward#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getClaimedReward(
+    uint256 _rewardEpoch,
+    address _dataProvider,
+    address _claimer
+) external view returns (
+    bool _claimed,
+    uint256 _amount);
+
+

Returns information on the rewards accrued by a reward owner from a specific data provider at a specific +reward epoch.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardEpochuint256Reward epoch ID to query.
_dataProvideraddressAddress of the data provider to query.
_claimeraddressAddress of the reward owner to query.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_claimedboolWhether the reward has been claimed or not.
_amountuint256Accrued amount in wei.
+
+
+
+

getCurrentRewardEpoch#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getCurrentRewardEpoch(
+) external view returns (
+    uint256);
+
+

Returns the current reward epoch ID.

+
+
+
+

getDataProviderCurrentFeePercentage#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getDataProviderCurrentFeePercentage(
+    address _dataProvider
+) external view returns (
+    uint256 _feePercentageBIPS);
+
+

Returns the current fee percentage of a data provider.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_dataProvideraddressAddress of the queried data provider.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_feePercentageBIPSuint256Fee percentage in BIPS.
+
+
+
+

getDataProviderFeePercentage#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getDataProviderFeePercentage(
+    address _dataProvider,
+    uint256 _rewardEpoch
+) external view returns (
+    uint256 _feePercentageBIPS);
+
+

Returns the fee percentage of a data provider at a +given reward epoch.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_dataProvideraddressAddress of the queried data provider.
_rewardEpochuint256Reward epoch ID.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_feePercentageBIPSuint256Fee percentage in BIPS.
+
+
+
+

getDataProviderPerformanceInfo#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getDataProviderPerformanceInfo(
+    uint256 _rewardEpoch,
+    address _dataProvider
+) external view returns (
+    uint256 _rewardAmount,
+    uint256 _votePowerIgnoringRevocation);
+
+

Returns information on rewards and vote power of a data provider at a given reward epoch.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardEpochuint256Reward epoch ID.
_dataProvideraddressAddress of the data provider to query.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_rewardAmountuint256Amount of rewards (wei).
_votePowerIgnoringRevocationuint256Vote power, not including revocations.
+
+
+
+

getDataProviderScheduledFeePercentageChanges#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getDataProviderScheduledFeePercentageChanges(
+    address _dataProvider
+) external view returns (
+    uint256[] _feePercentageBIPS,
+    uint256[] _validFromEpoch,
+    bool[] _fixed);
+
+

Returns the scheduled fee percentage changes for a data +provider.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_dataProvideraddressAddress of the queried data provider.
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_feePercentageBIPSuint256[]Array of fee percentages in BIPS.
_validFromEpochuint256[]Array of block numbers from which the fee settings are effective.
_fixedbool[]Array of boolean values indicating whether settings are subject to change or not.
+
+
+
+

getEpochReward#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getEpochReward(
+    uint256 _rewardEpoch
+) external view returns (
+    uint256 _totalReward,
+    uint256 _claimedReward);
+
+

Returns information on an epoch's rewards.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardEpochuint256Reward epoch ID.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_totalRewarduint256Total amount of rewards accrued on that epoch, in wei.
_claimedRewarduint256Total amount of rewards that have already been claimed, in wei.
+
+
+
+

getEpochsWithClaimableRewards#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getEpochsWithClaimableRewards(
+) external view returns (
+    uint256 _startEpochId,
+    uint256 _endEpochId);
+
+

Returns the reward epoch range for which rewards can be claimed. +Rewards outside this range are unclaimable, either because they have expired or because the reward epoch is +still ongoing.

+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_startEpochIduint256The oldest epoch ID that allows reward claiming.
_endEpochIduint256The newest epoch ID that allows reward claiming.
+
+
+
+

getEpochsWithUnclaimedRewards#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getEpochsWithUnclaimedRewards(
+    address _beneficiary
+) external view returns (
+    uint256[] _epochIds);
+
+

Returns the array of claimable epoch IDs for which the rewards of a reward owner have not yet been claimed.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_beneficiaryaddressAddress of the reward owner to query. Reverts if it uses delegation by amount.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_epochIdsuint256[]Array of epoch IDs.
+
+
+
+

getInitialRewardEpoch#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getInitialRewardEpoch(
+) external view returns (
+    uint256);
+
+

Returns the initial reward epoch ID for this reward manager contract. +This corresponds to the oldest reward epoch with claimable rewards in the previous reward manager when this +one took over. +Set by governance through setInitialRewardData.

+
+
+
+

getRewardEpochToExpireNext#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getRewardEpochToExpireNext(
+) external view returns (
+    uint256);
+
+

Returns the reward epoch that will expire next once a new reward epoch starts.

+
+
+
+

getRewardEpochVotePowerBlock#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getRewardEpochVotePowerBlock(
+    uint256 _rewardEpoch
+) external view returns (
+    uint256);
+
+

Returns the vote power block of a given reward epoch.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardEpochuint256Reward epoch ID.
+
+
+
+

getStateOfRewards#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getStateOfRewards(
+    address _beneficiary,
+    uint256 _rewardEpoch
+) external view returns (
+    address[] _dataProviders,
+    uint256[] _rewardAmounts,
+    bool[] _claimed,
+    bool _claimable);
+
+

Returns the state of rewards for a given address at a specific reward epoch.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_beneficiaryaddressAddress of the beneficiary to query. It can be a data provider or a delegator, for example.
Reverts if the queried address is delegating by amount.
_rewardEpochuint256Reward epoch ID to query.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_dataProvidersaddress[]Array of addresses of data providers.
_rewardAmountsuint256[]Array of reward amounts received from each provider, in wei.
_claimedbool[]Array of boolean values indicating whether each reward has been claimed or not.
_claimableboolBoolean value indicating whether rewards are claimable or not.
+
+
+
+

getStateOfRewardsFromDataProviders#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getStateOfRewardsFromDataProviders(
+    address _beneficiary,
+    uint256 _rewardEpoch,
+    address[] _dataProviders
+) external view returns (
+    uint256[] _rewardAmounts,
+    bool[] _claimed,
+    bool _claimable);
+
+

Returns the state of rewards for a given address coming from a specific set of data providers, at a specific +reward epoch.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_beneficiaryaddressAddress of beneficiary to query.
_rewardEpochuint256Reward epoch ID to query.
_dataProvidersaddress[]Array of addresses of the data providers to query.
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_rewardAmountsuint256[]Array of reward amounts received from each provider, in wei.
_claimedbool[]Array of boolean values indicating whether each reward has been claimed or not.
_claimableboolBoolean value indicating whether rewards are claimable or not.
+
+
+
+

nextClaimableRewardEpoch#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function nextClaimableRewardEpoch(
+    address _rewardOwner
+) external view returns (
+    uint256);
+
+

Returns the next claimable reward epoch for a reward owner.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardOwneraddressAddress of the reward owner to query.
+
+
+
+

setDataProviderFeePercentage#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function setDataProviderFeePercentage(
+    uint256 _feePercentageBIPS
+) external returns (
+    uint256 _validFromEpoch);
+
+

Sets the fee a data provider keeps from all delegations.

+

Takes effect after feeValueUpdateOffset reward epochs have elapsed.

+

When called multiple times inside the same reward epoch, only the last value remains.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_feePercentageBIPSuint256Fee percentage in BIPS.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_validFromEpochuint256Reward epoch number when the new fee percentage will become effective.
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IGovernanceSettings/index.html b/apis/smart-contracts/IGovernanceSettings/index.html new file mode 100644 index 000000000..5955b65a5 --- /dev/null +++ b/apis/smart-contracts/IGovernanceSettings/index.html @@ -0,0 +1,4088 @@ + + + + + + + + + + + + + + + + + + IGovernanceSettings - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

IGovernanceSettings#

+
+

Source

+
+
+

Interface for the GovernanceSettings that hold the Flare governance address and its timelock.

+

All governance calls are delayed by the timelock specified in this contract.

+

NOTE: This contract enables updating the governance address and timelock only +by hard-forking the network, meaning only by updating validator code.

+
+
+

Functions#

+
+

getExecutors#

+
+

Defined in IGovernanceSettings (Docs, Source).

+
+
+
function getExecutors(
+) external view returns (
+    address[] _addresses);
+
+

Gets the addresses of the accounts that are allowed to execute the timelocked governance calls, +once the timelock period expires. +Executors can be changed without a hard fork, via a normal governance call.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_addressesaddress[]Array of executor addresses.
+
+
+
+

getGovernanceAddress#

+
+

Defined in IGovernanceSettings (Docs, Source).

+
+
+
function getGovernanceAddress(
+) external view returns (
+    address _address);
+
+

Gets the governance account address. +The governance address can only be changed by a hard fork.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_addressaddressThe governance account address.
+
+
+
+

getTimelock#

+
+

Defined in IGovernanceSettings (Docs, Source).

+
+
+
function getTimelock(
+) external view returns (
+    uint256 _timelock);
+
+

Gets the time in seconds that must pass between a governance call and its execution. +The timelock value can only be changed by a hard fork.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_timelockuint256Time in seconds that passes between the governance call and execution.
+
+
+
+

isExecutor#

+
+

Defined in IGovernanceSettings (Docs, Source).

+
+
+
function isExecutor(
+    address _address
+) external view returns (
+    bool);
+
+

Checks whether an address is one of the allowed executors. See getExecutors.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_addressaddressThe address to check.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]boolTrue if _address is in the executors list.
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IGovernanceVotePower/index.html b/apis/smart-contracts/IGovernanceVotePower/index.html new file mode 100644 index 000000000..9935d1235 --- /dev/null +++ b/apis/smart-contracts/IGovernanceVotePower/index.html @@ -0,0 +1,4215 @@ + + + + + + + + + + + + + + + + + + IGovernanceVotePower - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

IGovernanceVotePower#

+
+

Source

+
+
+

Interface for contracts delegating their governance vote power.

+
+
+

Functions#

+
+

delegate#

+
+

Defined in IGovernanceVotePower (Docs, Source).

+
+
+
function delegate(
+    address _to
+) external;
+
+

Delegates all governance vote power of msg.sender to address _to.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_toaddressThe address of the recipient.
+
+
+
+

getDelegateOfAt#

+
+

Defined in IGovernanceVotePower (Docs, Source).

+
+
+
function getDelegateOfAt(
+    address _who,
+    uint256 _blockNumber
+) external view returns (
+    address);
+
+

Gets the address an account is delegating its governance vote power to, at a given block number.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address being queried.
_blockNumberuint256The block number at which to fetch the address.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]addressAddress where _who was delegating its governance vote power at block _blockNumber.
+
+
+
+

getDelegateOfAtNow#

+
+

Defined in IGovernanceVotePower (Docs, Source).

+
+
+
function getDelegateOfAtNow(
+    address _who
+) external view returns (
+    address);
+
+

Gets the address an account is delegating its governance vote power to, at the latest block number.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address being queried.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]addressAddress where _who is currently delegating its governance vote power.
+
+
+
+

getVotes#

+
+

Defined in IGovernanceVotePower (Docs, Source).

+
+
+
function getVotes(
+    address _who
+) external view returns (
+    uint256);
+
+

Gets the governance vote power of an address at the latest block, including +all delegations made to it.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address being queried.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Governance vote power of account at the lastest block.
+
+
+
+

undelegate#

+
+

Defined in IGovernanceVotePower (Docs, Source).

+
+
+
function undelegate(
+) external;
+
+

Undelegates all governance vote power of msg.sender.

+
+
+
+

votePowerOfAt#

+
+

Defined in IGovernanceVotePower (Docs, Source).

+
+
+
function votePowerOfAt(
+    address _who,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Gets the governance vote power of an address at a given block number, including +all delegations made to it.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address being queried.
_blockNumberuint256The block number at which to fetch the vote power.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Governance vote power of _who at _blockNumber.
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IIAddressUpdatable/index.html b/apis/smart-contracts/IIAddressUpdatable/index.html new file mode 100644 index 000000000..b33959bb3 --- /dev/null +++ b/apis/smart-contracts/IIAddressUpdatable/index.html @@ -0,0 +1,3943 @@ + + + + + + + + + + + + + + + + + + IIAddressUpdatable - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

IIAddressUpdatable#

+
+

Source

+
+
+

Internal interface for contracts that depend on other contracts whose addresses can change.

+

See AddressUpdatable.

+
+
+

Functions#

+
+

updateContractAddresses#

+
+

Defined in IIAddressUpdatable (Docs, Source).

+
+
+
function updateContractAddresses(
+    bytes32[] _contractNameHashes,
+    address[] _contractAddresses
+) external;
+
+

Updates contract addresses. +Can only be called from the AddressUpdater contract typically set at construction time.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_contractNameHashesbytes32[]List of keccak256(abi.encode(...)) contract names.
_contractAddressesaddress[]List of contract addresses corresponding to the contract names.
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IIAddressUpdater/index.html b/apis/smart-contracts/IIAddressUpdater/index.html new file mode 100644 index 000000000..3c6e772ea --- /dev/null +++ b/apis/smart-contracts/IIAddressUpdater/index.html @@ -0,0 +1,4181 @@ + + + + + + + + + + + + + + + + + + IIAddressUpdater - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

IIAddressUpdater#

+
+

Source

+
+
+

Internal interface for AddressUpdater.

+
+
+

Functions#

+
+

getContractAddress#

+
+

Defined in IIAddressUpdater (Docs, Source).

+
+
+
function getContractAddress(
+    string _name
+) external view returns (
+    address);
+
+

Returns contract address for the given name, which might be address(0).

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_namestringName of the contract to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]addressCurrent address for the queried contract.
+
+
+
+

getContractAddressByHash#

+
+

Defined in IIAddressUpdater (Docs, Source).

+
+
+
function getContractAddressByHash(
+    bytes32 _nameHash
+) external view returns (
+    address);
+
+

Returns contract address for the given name hash, which might be address(0).

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_nameHashbytes32Hash of the contract name: keccak256(abi.encode(name))
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]addressCurrent address for the queried contract.
+
+
+
+

getContractAddresses#

+
+

Defined in IIAddressUpdater (Docs, Source).

+
+
+
function getContractAddresses(
+    string[] _names
+) external view returns (
+    address[]);
+
+

Returns contract addresses for the given names, which might be address(0).

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_namesstring[]Names of the contracts to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]address[]Current addresses for the queried contracts.
+
+
+
+

getContractAddressesByHash#

+
+

Defined in IIAddressUpdater (Docs, Source).

+
+
+
function getContractAddressesByHash(
+    bytes32[] _nameHashes
+) external view returns (
+    address[]);
+
+

Returns contract addresses for the given name hashes, which might be address(0).

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_nameHashesbytes32[]Hashes of the contract names: keccak256(abi.encode(name))
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]address[]Current addresses for the queried contracts.
+
+
+
+

getContractNamesAndAddresses#

+
+

Defined in IIAddressUpdater (Docs, Source).

+
+
+
function getContractNamesAndAddresses(
+) external view returns (
+    string[] _contractNames,
+    address[] _contractAddresses);
+
+

Returns all contract names and corresponding addresses currently being tracked.

+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_contractNamesstring[]Array of contract names.
_contractAddressesaddress[]Array of contract addresses.
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IIClaimSetupManager/index.html b/apis/smart-contracts/IIClaimSetupManager/index.html new file mode 100644 index 000000000..854b17faa --- /dev/null +++ b/apis/smart-contracts/IIClaimSetupManager/index.html @@ -0,0 +1,5876 @@ + + + + + + + + + + + + + + + + + + IIClaimSetupManager - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

IIClaimSetupManager#

+
+

Source | Inherits from IClaimSetupManager

+
+
+

Internal interface for the ClaimSetupManager contract.

+
+
+

Events#

+
+

AllowedClaimRecipientsChanged#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
event AllowedClaimRecipientsChanged(
+    address owner,
+    address[] recipients
+)
+
+
+
+
+

ClaimExecutorFeeValueChanged#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
event ClaimExecutorFeeValueChanged(
+    address executor,
+    uint256 validFromRewardEpoch,
+    uint256 feeValueWei
+)
+
+
+
+
+

ClaimExecutorsChanged#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
event ClaimExecutorsChanged(
+    address owner,
+    address[] executors
+)
+
+
+
+
+

DelegationAccountCreated#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
event DelegationAccountCreated(
+    address owner,
+    contract IDelegationAccount delegationAccount
+)
+
+
+
+
+

DelegationAccountUpdated#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
event DelegationAccountUpdated(
+    address owner,
+    contract IDelegationAccount delegationAccount,
+    bool enabled
+)
+
+
+
+
+

ExecutorRegistered#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
event ExecutorRegistered(
+    address executor
+)
+
+
+
+
+

ExecutorUnregistered#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
event ExecutorUnregistered(
+    address executor,
+    uint256 validFromRewardEpoch
+)
+
+
+
+
+

MaxFeeSet#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
event MaxFeeSet(
+    uint256 maxFeeValueWei
+)
+
+
+
+
+

MinFeeSet#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
event MinFeeSet(
+    uint256 minFeeValueWei
+)
+
+
+
+
+

RegisterExecutorFeeSet#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
event RegisterExecutorFeeSet(
+    uint256 registerExecutorFeeValueWei
+)
+
+
+
+
+

SetExecutorsExcessAmountRefunded#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
event SetExecutorsExcessAmountRefunded(
+    address owner,
+    uint256 excessAmount
+)
+
+
+
+
+

SetLibraryAddress#

+
+

Defined in IIClaimSetupManager (Docs, Source).

+
+
+
event SetLibraryAddress(
+    address libraryAddress
+)
+
+

Emitted when the libraryAddress has been set.

+
+
+
+
+

Functions#

+
+

accountToDelegationAccount#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function accountToDelegationAccount(
+    address _owner
+) external view returns (
+    address);
+
+

Gets the PDA of an account.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressAccount to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]addressAddress of its PDA or address(0) if it has not been created yet.
+
+
+
+

allowedClaimRecipients#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function allowedClaimRecipients(
+    address _rewardOwner
+) external view returns (
+    address[]);
+
+

Gets the addresses of recipients allowed to receive rewards on behalf of an account. +Beside these, the owner of the rewards is always authorized. +See setAllowedClaimRecipients.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardOwneraddressThe account to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]address[]Addresses of all set authorized recipients.
+
+
+
+

batchDelegate#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function batchDelegate(
+    address[] _delegatees,
+    uint256[] _bips
+) external;
+
+

Undelegates all percentage delegations from the caller's +PDA and then delegate to a list of accounts.

+

See delegate.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_delegateesaddress[]The addresses of the new recipients.
_bipsuint256[]The percentage of voting power to be delegated to each delegatee, expressed in basis points (1/100 of one percent). Total of all _bips values must be lower than 10000.
+
+
+
+

checkExecutorAndAllowedRecipient#

+
+

Defined in IIClaimSetupManager (Docs, Source).

+
+
+
function checkExecutorAndAllowedRecipient(
+    address _executor,
+    address _owner,
+    address _recipient
+) external view;
+
+

Checks if an executor can claim on behalf of a given account and send funds to a given recipient address.

+

Reverts if claiming is not possible, does nothing otherwise.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_executoraddressThe executor to query.
_owneraddressThe reward owner to query.
_recipientaddressThe address where the reward would be sent.
+
+
+
+

claimExecutors#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function claimExecutors(
+    address _owner
+) external view returns (
+    address[]);
+
+

Gets the addresses of executors authorized to claim for an account. +See setClaimExecutors.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe account to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]address[]Addresses of all set executors.
+
+
+
+

delegate#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function delegate(
+    address _to,
+    uint256 _bips
+) external;
+
+

Delegates a percentage of the caller's +PDA's voting power to another address.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_toaddressThe address of the recipient.
_bipsuint256The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: Every call resets the delegation value. A value of 0 revokes delegation.
+
+
+
+

delegateGovernance#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function delegateGovernance(
+    address _to
+) external;
+
+

Delegates all the governance vote power of the caller's +PDA to another account.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_toaddressAddress of the recipient of the delegation.
+
+
+
+

disableDelegationAccount#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function disableDelegationAccount(
+) external;
+
+

Disables the +Personal Delegation Account (PDA).

+

When using automatic claiming, all airdrops and FTSO rewards will be sent to the owner's account. +Rewards accrued by the PDA will no longer be automatically claimed.

+

Reverts if there is no PDA.

+
+
+
+

enableDelegationAccount#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function enableDelegationAccount(
+) external returns (
+    contract IDelegationAccount);
+
+

Enables (or creates) a +Personal Delegation Account (PDA).

+

When using automatic claiming, all airdrops and FTSO rewards will be sent to the PDA, and any rewards +accrued by the PDA will be claimed too.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]contract IDelegationAccountAddress of the delegation account contract.
+
+
+
+

getAutoClaimAddressesAndExecutorFee#

+
+

Defined in IIClaimSetupManager (Docs, Source).

+
+
+
function getAutoClaimAddressesAndExecutorFee(
+    address _executor,
+    address[] _owners
+) external view returns (
+    address[] _recipients,
+    uint256 _executorFeeValue);
+
+

Gets the Personal Delegation Account (PDA) for +a list of accounts for which an executor is claiming. +Returns owner address instead if the PDA is not created yet or not enabled.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_executoraddressExecutor to query.
_ownersaddress[]Array of reward owners which must have set _executor as their executor.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_recipientsaddress[]Addresses which will receive the claimed rewards. Can be the reward owners or their PDAs.
_executorFeeValueuint256Executor's fee value, in wei.
+
+
+
+

getDelegationAccountData#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function getDelegationAccountData(
+    address _owner
+) external view returns (
+    contract IDelegationAccount _delegationAccount,
+    bool _enabled);
+
+

Gets PDA data for an account.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressAccount to query.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_delegationAccountcontract IDelegationAccountAccount's PDA address or address(0) if it has not been created yet.
_enabledboolWhether the PDA is enabled.
+
+
+
+

getExecutorCurrentFeeValue#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function getExecutorCurrentFeeValue(
+    address _executor
+) external view returns (
+    uint256);
+
+

Returns the current fee of a registered executor. +Reverts if the executor is not registered.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_executoraddressThe executor to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Fee in wei.
+
+
+
+

getExecutorFeeValue#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function getExecutorFeeValue(
+    address _executor,
+    uint256 _rewardEpoch
+) external view returns (
+    uint256);
+
+

Returns the fee of an executor at a given reward epoch.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_executoraddressThe executor to query.
_rewardEpochuint256Reward Epoch ID to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Fee in wei at that reward epoch.
+
+
+
+

getExecutorInfo#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function getExecutorInfo(
+    address _executor
+) external view returns (
+    bool _registered,
+    uint256 _currentFeeValue);
+
+

Returns information about an executor.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_executoraddressThe executor to query.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_registeredboolWhether the executor is registered.
_currentFeeValueuint256Executor's current fee value, if registered.
+
+
+
+

getExecutorScheduledFeeValueChanges#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function getExecutorScheduledFeeValueChanges(
+    address _executor
+) external view returns (
+    uint256[] _feeValue,
+    uint256[] _validFromEpoch,
+    bool[] _fixed);
+
+

Returns the currently scheduled fee changes of an executor.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_executoraddressExecutor to query.
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_feeValueuint256[]Array of scheduled fees.
_validFromEpochuint256[]Array of reward epochs ID where the scheduled fees will become effective.
_fixedbool[]Array of booleans indicating if an scheduled fee change is fixed or it might still be changed.
+
+
+
+

getRegisteredExecutors#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function getRegisteredExecutors(
+    uint256 _start,
+    uint256 _end
+) external view returns (
+    address[] _registeredExecutors,
+    uint256 _totalLength);
+
+

Returns the list of executors registered through registerExecutor. +Supports paging.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_startuint256First executor to return.
_enduint256Last executor to return.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_registeredExecutorsaddress[]Addresses of the registered executors.
_totalLengthuint256Total amount of executors.
+
+
+
+

isClaimExecutor#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function isClaimExecutor(
+    address _owner,
+    address _executor
+) external view returns (
+    bool);
+
+

Returns whether an executor is authorized to claim on behalf of a reward owner. +See setClaimExecutors.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe reward owner to query.
_executoraddressThe executor to query.
+
+
+
+

registerExecutor#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function registerExecutor(
+    uint256 _feeValue
+) external payable returns (
+    uint256);
+
+

Registers the caller as an executor and sets its initial fee value.

+

If the executor was already registered, this method only updates the fee, which will take effect after +feeValueUpdateOffset reward epochs have elapsed.

+

Executor must pay a fee in order to register. See registerExecutorFeeValueWei.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_feeValueuint256Desired fee, in wei. Must be between minFeeValueWei and maxFeeValueWei. 0 means no fee.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Reward epoch ID when the changes become effective.
+
+
+
+

revokeDelegationAt#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function revokeDelegationAt(
+    address _who,
+    uint256 _blockNumber
+) external;
+
+

Revokes all delegation from the caller's PDA +to a given account at a given block.

+

Only affects the reads via votePowerOfAtCached() in the specified block.

+

This method should be used only to prevent rogue delegate voting in the current voting block. +To stop delegating use delegate with percentage of 0 or undelegateAll.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe account to revoke.
_blockNumberuint256Block number where the revoking will take place. Must be in the past.
+
+
+
+

setAllowedClaimRecipients#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function setAllowedClaimRecipients(
+    address[] _recipients
+) external;
+
+

Set the addresses of allowed recipients. +The reward owner is always an allowed recipient.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_recipientsaddress[]The new allowed recipients. All old recipients will be deleted and replaced by these.
+
+
+
+

setAutoClaiming#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function setAutoClaiming(
+    address[] _executors,
+    bool _enableDelegationAccount
+) external payable;
+
+

Sets the addresses of executors and optionally enables (creates) a +Personal Delegation Account (PDA).

+

If any of the executors is a registered executor, some fee needs to be paid.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_executorsaddress[]The new executors. All old executors will be deleted and replaced by these.
_enableDelegationAccountboolWhether the PDA should be enabled.
+
+
+
+

setClaimExecutors#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function setClaimExecutors(
+    address[] _executors
+) external payable;
+
+

Sets the addresses of executors.

+

If any of the executors is a registered executor, some fee needs to be paid.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_executorsaddress[]The new executors. All old executors will be deleted and replaced by these.
+
+
+
+

setLibraryAddress#

+
+

Defined in IIClaimSetupManager (Docs, Source).

+
+
+
function setLibraryAddress(
+    address _libraryAddress
+) external;
+
+

Sets new library address.

+
+
+
+

setMaxFeeValueWei#

+
+

Defined in IIClaimSetupManager (Docs, Source).

+
+
+
function setMaxFeeValueWei(
+    uint256 _maxFeeValueWei
+) external;
+
+

Sets maximum fee allowed for executors, in wei.

+
+
+
+

setMinFeeValueWei#

+
+

Defined in IIClaimSetupManager (Docs, Source).

+
+
+
function setMinFeeValueWei(
+    uint256 _minFeeValueWei
+) external;
+
+

Sets minimum fee allowed for executors, in wei.

+
+
+
+

setRegisterExecutorFeeValueWei#

+
+

Defined in IIClaimSetupManager (Docs, Source).

+
+
+
function setRegisterExecutorFeeValueWei(
+    uint256 _registerExecutorFeeValueWei
+) external;
+
+

Sets the fee required to register an executor, which must be higher than 0.

+
+
+
+

transferExternalToken#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function transferExternalToken(
+    contract IERC20 _token,
+    uint256 _amount
+) external;
+
+

Allows the caller to transfer ERC-20 tokens from their +PDA to the owner account.

+

The main use case is to move ERC-20 tokes received by mistake (by an airdrop, for example) out of the PDA +and into the main account, where they can be more easily managed.

+

Reverts if the target token is the WNat contract: use method withdraw for that.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_tokencontract IERC20Target token contract address.
_amountuint256Amount of tokens to transfer.
+
+
+
+

undelegateAll#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function undelegateAll(
+) external;
+
+

Removes all delegations from the caller's PDA.

+
+
+
+

undelegateGovernance#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function undelegateGovernance(
+) external;
+
+

Undelegates all governance vote power currently delegated by +the caller's PDA.

+
+
+
+

unregisterExecutor#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function unregisterExecutor(
+) external returns (
+    uint256);
+
+

Unregisters the caller as an executor.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Reward epoch ID when the change becomes effective.
+
+
+
+

updateExecutorFeeValue#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function updateExecutorFeeValue(
+    uint256 _feeValue
+) external returns (
+    uint256);
+
+

Sets the caller's executor fee. The caller must be an executor registered through registerExecutor.

+

When called multiple times inside the same reward epoch, only the last value remains.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_feeValueuint256Desired fee, in wei. Must be between minFeeValueWei and maxFeeValueWei. 0 means no fee.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Reward epoch ID when the changes become effective.
+
+
+
+

wNat#

+
+

Defined in IIClaimSetupManager (Docs, Source).

+
+
+
function wNat(
+) external view returns (
+    contract WNat);
+
+

Returns the WNat contract.

+
+
+
+

withdraw#

+
+

Defined in IClaimSetupManager (Docs, Source).

+
+
+
function withdraw(
+    uint256 _amount
+) external;
+
+

Allows the caller to transfer WNat wrapped tokens from their +PDA to the owner account.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_amountuint256Amount of tokens to transfer, in wei.
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IICleanable/index.html b/apis/smart-contracts/IICleanable/index.html new file mode 100644 index 000000000..bdac3056e --- /dev/null +++ b/apis/smart-contracts/IICleanable/index.html @@ -0,0 +1,4024 @@ + + + + + + + + + + + + + + + + + + IICleanable - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

IICleanable#

+
+

Source

+
+
+

Internal interface for entities that can have their block history cleaned.

+
+
+

Functions#

+
+

cleanupBlockNumber#

+
+

Defined in IICleanable (Docs, Source).

+
+
+
function cleanupBlockNumber(
+) external view returns (
+    uint256);
+
+

Get the current cleanup block number set with setCleanupBlockNumber.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The currently set cleanup block number.
+
+
+
+

setCleanerContract#

+
+

Defined in IICleanable (Docs, Source).

+
+
+
function setCleanerContract(
+    address _cleanerContract
+) external;
+
+

Set the contract that is allowed to call history cleaning methods.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_cleanerContractaddressAddress of the cleanup contract. Usually this will be an instance of CleanupBlockNumberManager.
+
+
+
+

setCleanupBlockNumber#

+
+

Defined in IICleanable (Docs, Source).

+
+
+
function setCleanupBlockNumber(
+    uint256 _blockNumber
+) external;
+
+

Set the cleanup block number. +Historic data for the blocks before cleanupBlockNumber can be erased. +History before that block should never be used since it can be inconsistent. +In particular, cleanup block number must be lower than the current vote power block.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockNumberuint256The new cleanup block number.
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IIFtso/index.html b/apis/smart-contracts/IIFtso/index.html new file mode 100644 index 000000000..c3229613a --- /dev/null +++ b/apis/smart-contracts/IIFtso/index.html @@ -0,0 +1,5684 @@ + + + + + + + + + + + + + + + + + + IIFtso - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + +

IIFtso#

+
+

Source | Inherits from IFtso, IFtsoGenesis

+
+
+

Internal interface for each of the FTSO contracts that handles an asset. +Read the FTSO documentation page +for general information about the FTSO system.

+
+
+

Functions#

+
+

activateFtso#

+
+

Defined in IIFtso (Docs, Source).

+
+
+
function activateFtso(
+    uint256 _firstEpochStartTs,
+    uint256 _submitPeriodSeconds,
+    uint256 _revealPeriodSeconds
+) external;
+
+

Initializes FTSO immutable settings and activates the contract.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_firstEpochStartTsuint256Timestamp of the first epoch in seconds from UNIX epoch.
_submitPeriodSecondsuint256Duration of epoch submission window in seconds.
_revealPeriodSecondsuint256Duration of epoch reveal window in seconds.
+
+
+
+

active#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function active(
+) external view returns (
+    bool);
+
+

Returns whether FTSO is active or not.

+
+
+
+

configureEpochs#

+
+

Defined in IIFtso (Docs, Source).

+
+
+
function configureEpochs(
+    uint256 _maxVotePowerNatThresholdFraction,
+    uint256 _maxVotePowerAssetThresholdFraction,
+    uint256 _lowAssetUSDThreshold,
+    uint256 _highAssetUSDThreshold,
+    uint256 _highAssetTurnoutThresholdBIPS,
+    uint256 _lowNatTurnoutThresholdBIPS,
+    uint256 _elasticBandRewardBIPS,
+    uint256 _elasticBandWidthPPM,
+    address[] _trustedAddresses
+) external;
+
+

Sets configurable settings related to epochs.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_maxVotePowerNatThresholdFractionuint256High threshold for native token vote power per voter.
_maxVotePowerAssetThresholdFractionuint256High threshold for asset vote power per voter.
_lowAssetUSDThresholduint256Threshold for low asset vote power (in scaled USD).
_highAssetUSDThresholduint256Threshold for high asset vote power (in scaled USD).
_highAssetTurnoutThresholdBIPSuint256Threshold for high asset turnout (in BIPS).
_lowNatTurnoutThresholdBIPSuint256Threshold for low nat turnout (in BIPS).
_elasticBandRewardBIPSuint256Percentage of the rewards (in BIPS) that go to the secondary reward band. The rest go to the primary reward band.
_elasticBandWidthPPMuint256Width of the secondary reward band, in parts-per-milion of the median.
_trustedAddressesaddress[]Trusted voters that will be used if low voter turnout is detected.
+
+
+
+

deactivateFtso#

+
+

Defined in IIFtso (Docs, Source).

+
+
+
function deactivateFtso(
+) external;
+
+

Deactivates the contract.

+
+
+
+

epochsConfiguration#

+
+

Defined in IIFtso (Docs, Source).

+
+
+
function epochsConfiguration(
+) external view returns (
+    uint256 _maxVotePowerNatThresholdFraction,
+    uint256 _maxVotePowerAssetThresholdFraction,
+    uint256 _lowAssetUSDThreshold,
+    uint256 _highAssetUSDThreshold,
+    uint256 _highAssetTurnoutThresholdBIPS,
+    uint256 _lowNatTurnoutThresholdBIPS,
+    uint256 _elasticBandRewardBIPS,
+    uint256 _elasticBandWidthPPM,
+    address[] _trustedAddresses);
+
+

Returns current configuration of epoch state.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_maxVotePowerNatThresholdFractionuint256High threshold for native token vote power per voter.
_maxVotePowerAssetThresholdFractionuint256High threshold for asset vote power per voter.
_lowAssetUSDThresholduint256Threshold for low asset vote power (in scaled USD).
_highAssetUSDThresholduint256Threshold for high asset vote power (in scaled USD).
_highAssetTurnoutThresholdBIPSuint256Threshold for high asset turnout (in BIPS).
_lowNatTurnoutThresholdBIPSuint256Threshold for low nat turnout (in BIPS).
_elasticBandRewardBIPSuint256Percentage of the rewards (in BIPS) that go to the secondary reward band. The rest go to the primary reward band.
_elasticBandWidthPPMuint256Width of the secondary reward band, in parts-per-milion of the median.
_trustedAddressesaddress[]Trusted voters that will be used if low voter turnout is detected.
+
+
+
+

fallbackFinalizePriceEpoch#

+
+

Defined in IIFtso (Docs, Source).

+
+
+
function fallbackFinalizePriceEpoch(
+    uint256 _epochId
+) external;
+
+

Forces finalization of a price epoch, calculating the median price from trusted addresses only.

+

Used as a fallback method, for example, due to an unexpected error during normal epoch finalization or +because the ftsoManager enabled the fallback mode.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_epochIduint256ID of the epoch to finalize.
+
+
+
+

finalizePriceEpoch#

+
+

Defined in IIFtso (Docs, Source).

+
+
+
function finalizePriceEpoch(
+    uint256 _epochId,
+    bool _returnRewardData
+) external returns (
+    address[] _eligibleAddresses,
+    uint256[] _natWeights,
+    uint256 _totalNatWeight);
+
+

Computes epoch price based on gathered votes.

+
    +
  • If the price reveal window for the epoch has ended, finalize the epoch.
  • +
  • Iterate list of price submissions.
  • +
  • Find weighted median.
  • +
  • Find adjacent 50% of price submissions.
  • +
  • Allocate rewards for price submissions.
  • +
+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_epochIduint256ID of the epoch to finalize.
_returnRewardDataboolParameter that determines if the reward data is returned.
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_eligibleAddressesaddress[]List of addresses eligible for reward.
_natWeightsuint256[]List of native token weights corresponding to the eligible addresses.
_totalNatWeightuint256Sum of weights in _natWeights.
+
+
+
+

forceFinalizePriceEpoch#

+
+

Defined in IIFtso (Docs, Source).

+
+
+
function forceFinalizePriceEpoch(
+    uint256 _epochId
+) external;
+
+

Forces finalization of a price epoch by copying the price from the previous epoch.

+

Used as a fallback method if fallbackFinalizePriceEpoch fails due to an exception.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_epochIduint256ID of the epoch to finalize.
+
+
+
+

ftsoManager#

+
+

Defined in IIFtso (Docs, Source).

+
+
+
function ftsoManager(
+) external view returns (
+    address);
+
+

Returns the FTSO manager's address.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]addressAddress of the FTSO manager contract.
+
+
+
+

getAsset#

+
+

Defined in IIFtso (Docs, Source).

+
+
+
function getAsset(
+) external view returns (
+    contract IIVPToken);
+
+

Returns the FTSO asset.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]contract IIVPTokenAddress of the IIVPToken tracked by this FTSO. null in case of multi-asset FTSO.
+
+
+
+

getAssetFtsos#

+
+

Defined in IIFtso (Docs, Source).

+
+
+
function getAssetFtsos(
+) external view returns (
+    contract IIFtso[]);
+
+

Returns the asset FTSOs.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]contract IIFtso[]Array of IIFtso contract addresses. null in case of single-asset FTSO.
+
+
+
+

getCurrentEpochId#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function getCurrentEpochId(
+) external view returns (
+    uint256);
+
+

Returns the current epoch ID.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Currently running epoch ID. IDs are consecutive numbers starting from zero.
+
+
+
+

getCurrentPrice#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function getCurrentPrice(
+) external view returns (
+    uint256 _price,
+    uint256 _timestamp);
+
+

Returns the current asset price.

+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Price in USD multiplied by 10^ASSET_PRICE_USD_DECIMALS.
_timestampuint256Time when price was updated for the last time, in seconds from UNIX epoch.
+
+
+
+

getCurrentPriceDetails#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function getCurrentPriceDetails(
+) external view returns (
+    uint256 _price,
+    uint256 _priceTimestamp,
+    enum IFtso.PriceFinalizationType _priceFinalizationType,
+    uint256 _lastPriceEpochFinalizationTimestamp,
+    enum IFtso.PriceFinalizationType _lastPriceEpochFinalizationType);
+
+

Returns asset's current price details. +All timestamps are in seconds from UNIX epoch.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Price in USD multiplied by 10^ASSET_PRICE_USD_DECIMALS.
_priceTimestampuint256Time when price was updated for the last time.
_priceFinalizationTypeenum IFtso.PriceFinalizationTypeFinalization type when price was updated for the last time.
_lastPriceEpochFinalizationTimestampuint256Time when last price epoch was finalized.
_lastPriceEpochFinalizationTypeenum IFtso.PriceFinalizationTypeFinalization type of last finalized price epoch.
+
+
+
+

getCurrentPriceFromTrustedProviders#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function getCurrentPriceFromTrustedProviders(
+) external view returns (
+    uint256 _price,
+    uint256 _timestamp);
+
+

Returns current asset price calculated only using input from trusted providers.

+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Price in USD multiplied by 10^ASSET_PRICE_USD_DECIMALS.
_timestampuint256Time when price was updated for the last time, in seconds from UNIX epoch.
+
+
+
+

getCurrentPriceWithDecimals#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function getCurrentPriceWithDecimals(
+) external view returns (
+    uint256 _price,
+    uint256 _timestamp,
+    uint256 _assetPriceUsdDecimals);
+
+

Returns current asset price and number of decimals.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Price in USD multiplied by 10^_assetPriceUsdDecimals.
_timestampuint256Time when price was updated for the last time, in seconds from UNIX epoch.
_assetPriceUsdDecimalsuint256Number of decimals used to return the USD price.
+
+
+
+

getCurrentPriceWithDecimalsFromTrustedProviders#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function getCurrentPriceWithDecimalsFromTrustedProviders(
+) external view returns (
+    uint256 _price,
+    uint256 _timestamp,
+    uint256 _assetPriceUsdDecimals);
+
+

Returns current asset price calculated only using input from trusted providers and number of decimals.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Price in USD multiplied by 10^ASSET_PRICE_USD_DECIMALS.
_timestampuint256Time when price was updated for the last time, in seconds from UNIX epoch.
_assetPriceUsdDecimalsuint256Number of decimals used to return the USD price.
+
+
+
+

getCurrentRandom#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function getCurrentRandom(
+) external view returns (
+    uint256);
+
+

Returns the random number for the previous price epoch, obtained from the random numbers +provided by all data providers along with their data submissions.

+
+
+
+

getEpochId#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function getEpochId(
+    uint256 _timestamp
+) external view returns (
+    uint256);
+
+

Returns the ID of the epoch that was opened for price submission at the specified timestamp.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_timestampuint256Queried timestamp in seconds from UNIX epoch.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Epoch ID corresponding to that timestamp. IDs are consecutive numbers starting from zero.
+
+
+
+

getEpochPrice#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function getEpochPrice(
+    uint256 _epochId
+) external view returns (
+    uint256);
+
+

Returns agreed asset price in the specified epoch.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_epochIduint256ID of the epoch. Only the last 200 epochs can be queried. Out-of-bounds queries revert.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Price in USD multiplied by 10^ASSET_PRICE_USD_DECIMALS.
+
+
+
+

getEpochPriceForVoter#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function getEpochPriceForVoter(
+    uint256 _epochId,
+    address _voter
+) external view returns (
+    uint256);
+
+

Returns asset price submitted by a voter in the specified epoch.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_epochIduint256ID of the epoch being queried. Only the last 200 epochs can be queried. Out-of-bounds queries revert.
_voteraddressAddress of the voter being queried.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Price in USD multiplied by 10^ASSET_PRICE_USD_DECIMALS.
+
+
+
+

getPriceEpochConfiguration#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function getPriceEpochConfiguration(
+) external view returns (
+    uint256 _firstEpochStartTs,
+    uint256 _submitPeriodSeconds,
+    uint256 _revealPeriodSeconds);
+
+

Returns current epoch's configuration.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_firstEpochStartTsuint256First epoch start timestamp in seconds from UNIX epoch.
_submitPeriodSecondsuint256Submit period in seconds.
_revealPeriodSecondsuint256Reveal period in seconds.
+
+
+
+

getPriceEpochData#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function getPriceEpochData(
+) external view returns (
+    uint256 _epochId,
+    uint256 _epochSubmitEndTime,
+    uint256 _epochRevealEndTime,
+    uint256 _votePowerBlock,
+    bool _fallbackMode);
+
+

Returns current epoch data. +Intervals are open on the right: End times are not included.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_epochIduint256Current epoch ID.
_epochSubmitEndTimeuint256End time of the price submission window in seconds from UNIX epoch.
_epochRevealEndTimeuint256End time of the price reveal window in seconds from UNIX epoch.
_votePowerBlockuint256Vote power block for the current epoch.
_fallbackModeboolWhether the current epoch is in fallback mode. Only votes from trusted addresses are used in this mode.
+
+
+
+

getRandom#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function getRandom(
+    uint256 _epochId
+) external view returns (
+    uint256);
+
+

Returns the random number used in a specific past epoch, obtained from the random numbers +provided by all data providers along with their data submissions.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_epochIduint256ID of the queried epoch. Current epoch cannot be queried, and the previous epoch is constantly updated as data providers reveal their prices and random numbers. Only the last 50 epochs can be queried and there is no bounds checking for this parameter. Out-of-bounds queries return undefined values.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The random number used in that epoch.
+
+
+
+

getVoteWeightingParameters#

+
+

Defined in IIFtso (Docs, Source).

+
+
+
function getVoteWeightingParameters(
+) external view returns (
+    contract IIVPToken[] _assets,
+    uint256[] _assetMultipliers,
+    uint256 _totalVotePowerNat,
+    uint256 _totalVotePowerAsset,
+    uint256 _assetWeightRatio,
+    uint256 _votePowerBlock);
+
+

Returns parameters necessary for replicating vote weighting (used in VoterWhitelister).

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_assetscontract IIVPToken[]The list of assets that are accounted in vote.
_assetMultipliersuint256[]Weight multiplier of each asset in (multiasset) FTSO.
_totalVotePowerNatuint256Total native token vote power at block.
_totalVotePowerAssetuint256Total combined asset vote power at block.
_assetWeightRatiouint256Ratio of combined asset vote power vs. native token vp (in BIPS).
_votePowerBlockuint256Vote power block for the epoch.
+
+
+
+

initializeCurrentEpochStateForReveal#

+
+

Defined in IIFtso (Docs, Source).

+
+
+
function initializeCurrentEpochStateForReveal(
+    uint256 _circulatingSupplyNat,
+    bool _fallbackMode
+) external;
+
+

Initializes current epoch instance for reveal.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_circulatingSupplyNatuint256Epoch native token circulating supply.
_fallbackModeboolWhether the current epoch is in fallback mode.
+
+
+
+

revealPriceSubmitter#

+
+

Defined in IFtsoGenesis (Docs, Source).

+
+
+
function revealPriceSubmitter(
+    address _voter,
+    uint256 _epochId,
+    uint256 _price,
+    uint256 _voterWNatVP
+) external;
+
+

Reveals the price submitted by a voter on a specific epoch. +The hash of _price and _random must be equal to the submitted hash

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_voteraddressVoter address.
_epochIduint256ID of the epoch in which the price hash was submitted.
_priceuint256Submitted price.
_voterWNatVPuint256Voter's vote power in WNat units.
+
+
+
+

setAsset#

+
+

Defined in IIFtso (Docs, Source).

+
+
+
function setAsset(
+    contract IIVPToken _asset
+) external;
+
+

Sets asset for FTSO to operate as single-asset oracle.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_assetcontract IIVPTokenAddress of the IIVPToken contract that will be the asset tracked by this FTSO.
+
+
+
+

setAssetFtsos#

+
+

Defined in IIFtso (Docs, Source).

+
+
+
function setAssetFtsos(
+    contract IIFtso[] _assetFtsos
+) external;
+
+

Sets an array of FTSOs for FTSO to operate as multi-asset oracle. +FTSOs implicitly determine the FTSO assets.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_assetFtsoscontract IIFtso[]Array of FTSOs.
+
+
+
+

setVotePowerBlock#

+
+

Defined in IIFtso (Docs, Source).

+
+
+
function setVotePowerBlock(
+    uint256 _blockNumber
+) external;
+
+

Sets the current vote power block. +Current vote power block will update per reward epoch. +The FTSO doesn't have notion of reward epochs.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockNumberuint256Vote power block.
+
+
+
+

symbol#

+
+

Defined in IFtso (Docs, Source).

+
+
+
function symbol(
+) external view returns (
+    string);
+
+

Returns the FTSO symbol.

+
+
+
+

updateInitialPrice#

+
+

Defined in IIFtso (Docs, Source).

+
+
+
function updateInitialPrice(
+    uint256 _initialPriceUSD,
+    uint256 _initialPriceTimestamp
+) external;
+
+

Updates initial asset price when the contract is not active yet.

+
+
+
+

wNat#

+
+

Defined in IIFtso (Docs, Source).

+
+
+
function wNat(
+) external view returns (
+    contract IIVPToken);
+
+

Address of the WNat contract.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]contract IIVPTokenAddress of the WNat contract.
+
+
+
+

wNatVotePowerCached#

+
+

Defined in IFtsoGenesis (Docs, Source).

+
+
+
function wNatVotePowerCached(
+    address _voter,
+    uint256 _epochId
+) external returns (
+    uint256);
+
+

Get and cache the vote power of a voter on a specific epoch, in WNat units.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_voteraddressVoter address.
_epochIduint256ID of the epoch in which the price hash was submitted.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Voter's vote power in WNat units.
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IIFtsoManager/index.html b/apis/smart-contracts/IIFtsoManager/index.html new file mode 100644 index 000000000..fa2df1677 --- /dev/null +++ b/apis/smart-contracts/IIFtsoManager/index.html @@ -0,0 +1,6340 @@ + + + + + + + + + + + + + + + + + + IIFtsoManager - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

IIFtsoManager#

+
+

Source | Inherits from IFtsoManager, IFlareDaemonize

+
+
+

Internal interface for the FtsoManager contract.

+
+
+

Events#

+
+

AccruingUnearnedRewardsFailed#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
event AccruingUnearnedRewardsFailed(
+    uint256 epochId
+)
+
+

Unexpected failure while accruing unearned rewards. +This should be a rare occurrence.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
epochIduint256Epoch ID of the failure.
+
+
+
+

ChillingNonrevealingDataProvidersFailed#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
event ChillingNonrevealingDataProvidersFailed(
+)
+
+

Unexpected failure. This should be a rare occurrence.

+
+
+
+

CleanupBlockNumberManagerFailedForBlock#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
event CleanupBlockNumberManagerFailedForBlock(
+    uint256 blockNumber
+)
+
+

Unexpected failure. This should be a rare occurrence.

+
+
+
+

ClosingExpiredRewardEpochFailed#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
event ClosingExpiredRewardEpochFailed(
+    uint256 rewardEpoch
+)
+
+

Unexpected failure. This should be a rare occurrence.

+
+
+
+

DistributingRewardsFailed#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
event DistributingRewardsFailed(
+    address ftso,
+    uint256 epochId
+)
+
+

Unexpected failure while distributing rewards. +This should be a rare occurrence.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
ftsoaddressContract address of the FTSO where the failure happened.
epochIduint256Epoch ID of the failure.
+
+
+
+

FallbackMode#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
event FallbackMode(
+    bool fallbackMode
+)
+
+

Emitted when the fallback mode of the FTSO manager changes its state. +Fallback mode is a recovery mode, where only data from a trusted subset of FTSO +data providers is used to calculate the final price.

+

The FTSO Manager enters the fallback mode when ALL FTSOs are in fallback mode.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
fallbackModeboolNew state of the FTSO Manager fallback mode.
+
+
+
+

FinalizingPriceEpochFailed#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
event FinalizingPriceEpochFailed(
+    contract IIFtso ftso,
+    uint256 epochId,
+    enum IFtso.PriceFinalizationType failingType
+)
+
+

Unexpected failure while finalizing a price epoch. +This should be a rare occurrence.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
ftsocontract IIFtsoContract address of the FTSO where the failure happened.
epochIduint256Epoch ID of the failure.
failingTypeenum IFtso.PriceFinalizationTypeHow was the epoch finalized.
+
+
+
+

FtsoAdded#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
event FtsoAdded(
+    contract IIFtso ftso,
+    bool add
+)
+
+

Emitted when a new FTSO has been added or an existing one has been removed.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
ftsocontract IIFtsoContract address of the FTSO.
addboolTrue if added, removed otherwise.
+
+
+
+

FtsoDeactivationFailed#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
event FtsoDeactivationFailed(
+    contract IIFtso ftso
+)
+
+

Unexpected failure. This should be a rare occurrence.

+
+
+
+

FtsoFallbackMode#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
event FtsoFallbackMode(
+    contract IIFtso ftso,
+    bool fallbackMode
+)
+
+

Emitted when the fallback mode of an FTSO changes its state.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
ftsocontract IIFtsoContract address of the FTSO.
fallbackModeboolNew state of its fallback mode.
+
+
+
+

InitializingCurrentEpochStateForRevealFailed#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
event InitializingCurrentEpochStateForRevealFailed(
+    contract IIFtso ftso,
+    uint256 epochId
+)
+
+

Unexpected failure while initializing a price epoch. +This should be a rare occurrence.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
ftsocontract IIFtsoContract address of the FTSO where the failure happened.
epochIduint256Epoch ID that failed initialization.
+
+
+
+

PriceEpochFinalized#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
event PriceEpochFinalized(
+    address chosenFtso,
+    uint256 rewardEpochId
+)
+
+

Emitted when a price epoch ends, this is, +after the reveal phase, when final prices are calculated.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
chosenFtsoaddressContract address of the FTSO asset that was randomly chosen to be the basis for reward calculation. On this price epoch, rewards will be calculated based on how close each data provider was to the median of all submitted prices FOR THIS FTSO.
rewardEpochIduint256Reward epoch ID this price epoch belongs to.
+
+
+
+

RewardEpochFinalized#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
event RewardEpochFinalized(
+    uint256 votepowerBlock,
+    uint256 startBlock
+)
+
+

Emitted when a reward epoch +ends and rewards are available.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
votepowerBlockuint256The vote power block of the epoch.
startBlockuint256The first block of the epoch.
+
+
+
+

UpdatingActiveValidatorsTriggerFailed#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
event UpdatingActiveValidatorsTriggerFailed(
+    uint256 rewardEpoch
+)
+
+

Unexpected failure. This should be a rare occurrence.

+
+
+
+

UseGoodRandomSet#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
event UseGoodRandomSet(
+    bool useGoodRandom,
+    uint256 maxWaitForGoodRandomSeconds
+)
+
+

Emitted when the requirement to provide good random numbers has changed.

+

As part of the FTSO protocol, +data providers must submit a random number along with their price reveals. +When good random numbers are enforced, all providers that submit a hash must then +submit a reveal with a random number or they will be punished. +This is a measure against random number manipulation.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
useGoodRandomboolWhether good random numbers are now enforced or not.
maxWaitForGoodRandomSecondsuint256Max number of seconds to wait for a good random number to be submitted.
+
+
+
+
+

Functions#

+
+

activate#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
function activate(
+) external;
+
+

Activates FTSO manager (daemonize will run jobs).

+
+
+
+

active#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
function active(
+) external view returns (
+    bool);
+
+

Returns whether the FTSO Manager is active or not.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]boolbool Active status.
+
+
+
+

addFtso#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
function addFtso(
+    contract IIFtso _ftso
+) external;
+
+

Adds FTSO to the list of managed FTSOs, to support a new price pair. +All FTSOs in a multi-asset FTSO must be managed by the same FTSO manager.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsocontract IIFtsoFTSO contract address to add.
+
+
+
+

addFtsosBulk#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
function addFtsosBulk(
+    contract IIFtso[] _ftsos
+) external;
+
+

Adds a list of FTSOs to the list of managed FTSOs, to support new price pairs. +All FTSOs in a multi-asset FTSO must be managed by the same FTSO manager.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsoscontract IIFtso[]Array of FTSO contract addresses to add.
+
+
+
+

currentRewardEpochEnds#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
function currentRewardEpochEnds(
+) external view returns (
+    uint256);
+
+

Returns when the current reward epoch finishes.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256uint256 Time in seconds since the UNIX epoch when the current reward epoch will finish.
+
+
+
+

daemonize#

+
+

Defined in IFlareDaemonize (Docs, Source).

+
+
+
function daemonize(
+) external returns (
+    bool);
+
+

Implement this function to receive a trigger from the FlareDaemon. +The trigger method is called by the validator right at the end of block state transition.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]boolbool Whether the contract is still active after the call. Currently unused.
+
+
+
+

getContractName#

+
+

Defined in IFlareDaemonize (Docs, Source).

+
+
+
function getContractName(
+) external view returns (
+    string);
+
+

Implement this function to allow updating daemonized contracts through the AddressUpdater.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]stringstring Contract name.
+
+
+
+

getCurrentPriceEpochData#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
function getCurrentPriceEpochData(
+) external view returns (
+    uint256 _priceEpochId,
+    uint256 _priceEpochStartTimestamp,
+    uint256 _priceEpochEndTimestamp,
+    uint256 _priceEpochRevealEndTimestamp,
+    uint256 _currentTimestamp);
+
+

Returns timing information for the current price epoch. +All intervals are half-closed: end time is not included. +All timestamps are in seconds since UNIX epoch.

+

See the FTSO page +for information about the different submission phases.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceEpochIduint256Price epoch ID.
_priceEpochStartTimestampuint256Beginning of the commit phase.
_priceEpochEndTimestampuint256End of the commit phase.
_priceEpochRevealEndTimestampuint256End of the reveal phase.
_currentTimestampuint256Current time.
+
+
+
+

getCurrentPriceEpochId#

+
+

Defined in IFtsoManagerGenesis (Docs, Source).

+
+
+
function getCurrentPriceEpochId(
+) external view returns (
+    uint256 _priceEpochId);
+
+

Returns current price epoch ID.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceEpochIduint256Currently running epoch ID. IDs are consecutive numbers starting from zero.
+
+
+
+

getCurrentRewardEpoch#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
function getCurrentRewardEpoch(
+) external view returns (
+    uint256);
+
+

Returns current reward epoch ID (the one currently running).

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Reward epoch ID. A monotonically increasing integer.
+
+
+
+

getElasticBandWidthPPMFtso#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
function getElasticBandWidthPPMFtso(
+    contract IIFtso _ftso
+) external view returns (
+    uint256);
+
+

Returns the secondary band's width in PPM (parts-per-million) of the median value, +for a given FTSO.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsocontract IIFtsoThe queried FTSO contract address.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256uint256 Secondary band width in PPM. To obtain the actual band width, divide this number by 10^6 and multiply by the price median value.
+
+
+
+

getFallbackMode#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
function getFallbackMode(
+) external view returns (
+    bool _fallbackMode,
+    contract IIFtso[] _ftsos,
+    bool[] _ftsoInFallbackMode);
+
+

Returns whether the FTSO Manager is currently in fallback mode.

+

In this mode only submissions from trusted providers are used.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_fallbackModeboolTrue if fallback mode is enabled for the manager.
_ftsoscontract IIFtso[]Array of all currently active FTSO assets.
_ftsoInFallbackModebool[]Boolean array indicating which FTSO assets are in fallback mode. If the FTSO Manager is in fallback mode then ALL FTSOs are in fallback mode.
+
+
+
+

getFtsos#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
function getFtsos(
+) external view returns (
+    contract IIFtso[] _ftsos);
+
+

Returns the list of currently active FTSOs.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_ftsoscontract IIFtso[]Array of contract addresses for the FTSOs.
+
+
+
+

getLastUnprocessedPriceEpochData#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
function getLastUnprocessedPriceEpochData(
+) external view returns (
+    uint256 _lastUnprocessedPriceEpoch,
+    uint256 _lastUnprocessedPriceEpochRevealEnds,
+    bool _lastUnprocessedPriceEpochInitialized);
+
+

Returns information regarding the currently unprocessed price epoch. +This epoch is not necessarily the last one, in case the network halts for some +time due to validator node problems, for example.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_lastUnprocessedPriceEpochuint256ID of the price epoch that is currently waiting finalization.
_lastUnprocessedPriceEpochRevealEndsuint256When that price epoch can be finalized, in seconds since UNIX epoch.
_lastUnprocessedPriceEpochInitializedboolWhether this price epoch has been already initialized and therefore it must be finalized before the corresponding reward epoch can be finalized.
+
+
+
+

getPriceEpochConfiguration#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
function getPriceEpochConfiguration(
+) external view returns (
+    uint256 _firstPriceEpochStartTs,
+    uint256 _priceEpochDurationSeconds,
+    uint256 _revealEpochDurationSeconds);
+
+

Returns the current values for price epoch timing configuration.

+

See the FTSO page +for information about the different submission phases.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_firstPriceEpochStartTsuint256Timestamp, in seconds since UNIX epoch, of the first price epoch.
_priceEpochDurationSecondsuint256Duration in seconds of the commit phase.
_revealEpochDurationSecondsuint256Duration in seconds of the reveal phase.
+
+
+
+

getRewardEpochConfiguration#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
function getRewardEpochConfiguration(
+) external view returns (
+    uint256 _firstRewardEpochStartTs,
+    uint256 _rewardEpochDurationSeconds);
+
+

Returns the current values for reward epoch timing configuration.

+

See the Reward epochs box.

+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_firstRewardEpochStartTsuint256Timestamp, in seconds since UNIX epoch, of the first reward epoch.
_rewardEpochDurationSecondsuint256Duration in seconds of the reward epochs.
+
+
+
+

getRewardEpochData#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
function getRewardEpochData(
+    uint256 _rewardEpochId
+) external view returns (
+    struct IIFtsoManager.RewardEpochData);
+
+

Returns data regarding a specific reward epoch ID.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardEpochIduint256Epoch ID.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]struct IIFtsoManager.RewardEpochDataRewardEpochData Its associated data.
+
+
+
+

getRewardEpochToExpireNext#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
function getRewardEpochToExpireNext(
+) external view returns (
+    uint256);
+
+

Return reward epoch that will expire next, when a new reward epoch is initialized.

+

Reward epochs older than 90 days expire, and any unclaimed rewards in them become +inaccessible.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256uint256 Reward epoch ID.
+
+
+
+

getRewardEpochVotePowerBlock#

+
+

Defined in IFtsoManager (Docs, Source).

+
+
+
function getRewardEpochVotePowerBlock(
+    uint256 _rewardEpoch
+) external view returns (
+    uint256);
+
+

Returns the vote power block +that was used for a past reward epoch.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardEpochuint256The queried reward epoch ID.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256uint256 The block number of that reward epoch's vote power block.
+
+
+
+

getRewardExpiryOffsetSeconds#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
function getRewardExpiryOffsetSeconds(
+) external view returns (
+    uint256);
+
+

Returns the currently configured reward expiration time.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256uint256 Unclaimed rewards accrued in reward epochs more than this amount of seconds in the past expire and become inaccessible.
+
+
+
+

notInitializedFtsos#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
function notInitializedFtsos(
+    contract IIFtso
+) external view returns (
+    bool);
+
+

Returns whether an FTSO has been initialized.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]boolbool Initialization state.
+
+
+
+

removeFtso#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
function removeFtso(
+    contract IIFtso _ftso
+) external;
+
+

Removes an FTSO from the list of managed FTSOs. +Reverts if FTSO is used in a multi-asset FTSO. +Deactivates the _ftso.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsocontract IIFtsoFTSO contract address to remove.
+
+
+
+

replaceFtso#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
function replaceFtso(
+    contract IIFtso _ftsoToAdd,
+    bool copyCurrentPrice,
+    bool copyAssetOrAssetFtsos
+) external;
+
+

Replaces one FTSO with another with the same symbol. +All FTSOs in a multi-asset FTSO must be managed by the same FTSO manager. +Deactivates the old FTSO.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsoToAddcontract IIFtsoFTSO contract address to add. An existing FTSO with the same symbol will be removed.
copyCurrentPriceboolWhen true, initializes the new FTSO with the current price of the previous FTSO.
copyAssetOrAssetFtsosboolWhen true, initializes the new FTSO with the current asset or asset FTSOs of the previous FTSO.
+
+
+
+

replaceFtsosBulk#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
function replaceFtsosBulk(
+    contract IIFtso[] _ftsosToAdd,
+    bool copyCurrentPrice,
+    bool copyAssetOrAssetFtsos
+) external;
+
+

Replaces a list of FTSOs with other FTSOs with the same symbol. +All FTSOs in a multi-asset FTSO must be managed by the same FTSO manager. +Deactivates the old FTSOs.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsosToAddcontract IIFtso[]Array of FTSO contract addresses to add. Every existing FTSO with the same symbols will be removed.
copyCurrentPriceboolWhen true, initializes the new FTSOs with the current price of the previous FTSOs.
copyAssetOrAssetFtsosboolWhen true, initializes the new FTSOs with the current asset or asset FTSOs of the previous FTSOs.
+
+
+
+

rewardEpochDurationSeconds#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
function rewardEpochDurationSeconds(
+) external view returns (
+    uint256);
+
+

Currently configured reward epoch duration.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256uint256 Reward epoch duration, in seconds.
+
+
+
+

rewardEpochs#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
function rewardEpochs(
+    uint256 _rewardEpochId
+) external view returns (
+    uint256 _votepowerBlock,
+    uint256 _startBlock,
+    uint256 _startTimestamp);
+
+

Returns information about a reward epoch.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardEpochIduint256The epoch ID to query.
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_votepowerBlockuint256The vote power block of the epoch.
_startBlockuint256The first block of the epoch.
_startTimestampuint256Timestamp of the epoch start, in seconds since UNIX epoch.
+
+
+
+

rewardEpochsStartTs#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
function rewardEpochsStartTs(
+) external view returns (
+    uint256);
+
+

Time when the current reward epoch started.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256uint256 Timestamp, in seconds since UNIX epoch.
+
+
+
+

setFallbackMode#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
function setFallbackMode(
+    bool _fallbackMode
+) external;
+
+

Sets whether the FTSO Manager is currently in fallback mode. +In this mode only submissions from trusted providers are used.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_fallbackModeboolTrue if fallback mode is enabled.
+
+
+
+

setFtsoAsset#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
function setFtsoAsset(
+    contract IIFtso _ftso,
+    contract IIVPToken _asset
+) external;
+
+

Sets the asset tracked by an FTSO.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsocontract IIFtsoThe FTSO contract address.
_assetcontract IIVPTokenThe VPToken contract address of the asset to track.
+
+
+
+

setFtsoAssetFtsos#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
function setFtsoAssetFtsos(
+    contract IIFtso _ftso,
+    contract IIFtso[] _assetFtsos
+) external;
+
+

Sets an array of FTSOs to be tracked by a multi-asset FTSO. +FTSOs implicitly determine the FTSO assets.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsocontract IIFtsoThe multi-asset FTSO contract address.
_assetFtsoscontract IIFtso[]Array of FTSOs to be tracked.
+
+
+
+

setFtsoFallbackMode#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
function setFtsoFallbackMode(
+    contract IIFtso _ftso,
+    bool _fallbackMode
+) external;
+
+

Sets whether an FTSO is currently in fallback mode. +In this mode only submissions from trusted providers are used.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsocontract IIFtsoThe FTSO contract address.
_fallbackModeboolFallback mode.
+
+
+
+

setGovernanceParameters#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
function setGovernanceParameters(
+    uint256 _updateTs,
+    uint256 _maxVotePowerNatThresholdFraction,
+    uint256 _maxVotePowerAssetThresholdFraction,
+    uint256 _lowAssetUSDThreshold,
+    uint256 _highAssetUSDThreshold,
+    uint256 _highAssetTurnoutThresholdBIPS,
+    uint256 _lowNatTurnoutThresholdBIPS,
+    uint256 _elasticBandRewardBIPS,
+    uint256 _rewardExpiryOffsetSeconds,
+    address[] _trustedAddresses
+) external;
+
+

Sets governance parameters for FTSOs

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_updateTsuint256Time, in seconds since UNIX epoch, when updated settings should be pushed to FTSOs.
_maxVotePowerNatThresholdFractionuint256High threshold for native token vote power per voter.
_maxVotePowerAssetThresholdFractionuint256High threshold for asset vote power per voter
_lowAssetUSDThresholduint256Threshold for low asset vote power (in scaled USD).
_highAssetUSDThresholduint256Threshold for high asset vote power (in scaled USD).
_highAssetTurnoutThresholdBIPSuint256Threshold for high asset turnout (in BIPS).
_lowNatTurnoutThresholdBIPSuint256Threshold for low nat turnout (in BIPS).
_elasticBandRewardBIPSuint256Secondary reward band, where _elasticBandRewardBIPS goes to the secondary band and 10000 - _elasticBandRewardBIPS to the primary (IQR) band.
_rewardExpiryOffsetSecondsuint256Reward epochs closed earlier than block.timestamp - _rewardExpiryOffsetSeconds expire.
_trustedAddressesaddress[]Trusted addresses will be used as a fallback mechanism for setting the price.
+
+
+
+

setInitialRewardData#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
function setInitialRewardData(
+    uint256 _nextRewardEpochToExpire,
+    uint256 _rewardEpochsLength,
+    uint256 _currentRewardEpochEnds
+) external;
+
+

Set reward data to values from old ftso manager. +Can only be called before activation.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_nextRewardEpochToExpireuint256See getRewardEpochToExpireNext.
_rewardEpochsLengthuint256See getRewardEpochConfiguration.
_currentRewardEpochEndsuint256See getCurrentRewardEpoch.
+
+
+
+

switchToFallbackMode#

+
+

Defined in IFlareDaemonize (Docs, Source).

+
+
+
function switchToFallbackMode(
+) external returns (
+    bool);
+
+

This function will be called after an error is caught in daemonize. +It will switch the contract to a simpler fallback mode, which hopefully works when full mode doesn't. +Not every contract needs to support fallback mode (FtsoManager does), so this method may be empty. +Switching back to normal mode is left to the contract (typically a governed method call). +This function may be called due to low-gas error, so it shouldn't use more than ~30.000 gas.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]boolTrue if switched to fallback mode, false if already in fallback mode or if fallback mode is not supported.
+
+
+
+
+

Structures#

+
+

RewardEpochData#

+
+

Defined in IIFtsoManager (Docs, Source).

+
+
+
struct RewardEpochData {
+  uint256 votepowerBlock;
+  uint256 startBlock;
+  uint256 startTimestamp;
+}
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IIFtsoRegistry/index.html b/apis/smart-contracts/IIFtsoRegistry/index.html new file mode 100644 index 000000000..9daca8d72 --- /dev/null +++ b/apis/smart-contracts/IIFtsoRegistry/index.html @@ -0,0 +1,5089 @@ + + + + + + + + + + + + + + + + + + IIFtsoRegistry - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + +

IIFtsoRegistry#

+
+

Source | Inherits from IFtsoRegistry

+
+
+

Internal interface for the FtsoRegistry contract.

+
+
+

Functions#

+
+

addFtso#

+
+

Defined in IIFtsoRegistry (Docs, Source).

+
+
+
function addFtso(
+    contract IIFtso _ftsoContract
+) external returns (
+    uint256);
+
+

Add a new FTSO contract to the registry.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsoContractcontract IIFtsoNew target FTSO contract.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The FTSO index assigned to the new asset.
+
+
+
+

getAllCurrentPrices#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getAllCurrentPrices(
+) external view returns (
+    struct IFtsoRegistry.PriceInfo[]);
+
+

Returns the current price of all supported assets.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]struct IFtsoRegistry.PriceInfo[]Array of PriceInfo structures.
+
+
+
+

getCurrentPrice#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getCurrentPrice(
+    uint256 _ftsoIndex
+) external view returns (
+    uint256 _price,
+    uint256 _timestamp);
+
+

Public view function to get the current price of a given active FTSO index. +Reverts if the index is not supported.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsoIndexuint256Index to query.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Current price of the asset in USD multiplied by 10^ASSET_PRICE_USD_DECIMALS.
_timestampuint256Timestamp for when this price was updated, in seconds since UNIX epoch.
+
+
+
+

getCurrentPrice#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getCurrentPrice(
+    string _symbol
+) external view returns (
+    uint256 _price,
+    uint256 _timestamp);
+
+

Public view function to get the current price of a given active asset symbol. +Reverts if the symbol is not supported.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_symbolstringSymbol to query.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Current price of the asset in USD multiplied by 10^ASSET_PRICE_USD_DECIMALS.
_timestampuint256Timestamp for when this price was updated, in seconds since UNIX epoch.
+
+
+
+

getCurrentPriceWithDecimals#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getCurrentPriceWithDecimals(
+    uint256 _assetIndex
+) external view returns (
+    uint256 _price,
+    uint256 _timestamp,
+    uint256 _assetPriceUsdDecimals);
+
+

Public view function to get the current price and decimals of a given active FTSO index. +Reverts if the index is not supported.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_assetIndexuint256Index to query.
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Current price of the asset in USD multiplied by 10^_assetPriceUsdDecimals.
_timestampuint256Timestamp for when this price was updated, in seconds since UNIX epoch.
_assetPriceUsdDecimalsuint256Number of decimals used to return the _price.
+
+
+
+

getCurrentPriceWithDecimals#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getCurrentPriceWithDecimals(
+    string _symbol
+) external view returns (
+    uint256 _price,
+    uint256 _timestamp,
+    uint256 _assetPriceUsdDecimals);
+
+

Public view function to get the current price and decimals of a given active asset symbol. +Reverts if the symbol is not supported.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_symbolstringSymbol to query.
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_priceuint256Current price of the asset in USD multiplied by 10^_assetPriceUsdDecimals.
_timestampuint256Timestamp for when this price was updated, in seconds since UNIX epoch.
_assetPriceUsdDecimalsuint256Number of decimals used to return the _price.
+
+
+
+

getCurrentPricesByIndices#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getCurrentPricesByIndices(
+    uint256[] _indices
+) external view returns (
+    struct IFtsoRegistry.PriceInfo[]);
+
+

Returns the current price of a list of indices. +Reverts if any of the indices is not supported.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_indicesuint256[]Array of indices to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]struct IFtsoRegistry.PriceInfo[]Array of PriceInfo structures.
+
+
+
+

getCurrentPricesBySymbols#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getCurrentPricesBySymbols(
+    string[] _symbols
+) external view returns (
+    struct IFtsoRegistry.PriceInfo[]);
+
+

Returns the current price of a list of asset symbols. +Reverts if any of the symbols is not supported.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_symbolsstring[]Array of symbols to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]struct IFtsoRegistry.PriceInfo[]Array of PriceInfo structures.
+
+
+
+

getFtso#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getFtso(
+    uint256 _activeFtso
+) external view returns (
+    contract IIFtso _activeFtsoAddress);
+
+

Returns the address of the FTSO contract for a given index. +Reverts if unsupported index is passed.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_activeFtsouint256The queried index.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_activeFtsoAddresscontract IIFtsoFTSO contract address for the queried index.
+
+
+
+

getFtsoBySymbol#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getFtsoBySymbol(
+    string _symbol
+) external view returns (
+    contract IIFtso _activeFtsoAddress);
+
+

Returns the address of the FTSO contract for a given symbol. +Reverts if unsupported symbol is passed.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_symbolstringThe queried symbol.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_activeFtsoAddresscontract IIFtsoFTSO contract address for the queried symbol.
+
+
+
+

getFtsoIndex#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getFtsoIndex(
+    string _symbol
+) external view returns (
+    uint256 _assetIndex);
+
+

Returns the FTSO index corresponding to a given asset symbol. +Reverts if the symbol is not supported.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_symbolstringSymbol to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_assetIndexuint256The corresponding asset index.
+
+
+
+

getFtsoSymbol#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getFtsoSymbol(
+    uint256 _ftsoIndex
+) external view returns (
+    string _symbol);
+
+

Returns the asset symbol corresponding to a given FTSO index. +Reverts if the index is not supported.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsoIndexuint256Index to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_symbolstringThe corresponding asset symbol.
+
+
+
+

getFtsos#

+
+

Defined in IFtsoRegistryGenesis (Docs, Source).

+
+
+
function getFtsos(
+    uint256[] _indices
+) external view returns (
+    contract IFtsoGenesis[] _ftsos);
+
+

Get the addresses of the active FTSOs at the given indices. +Reverts if any of the provided indices is non-existing or inactive.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_indicesuint256[]Array of FTSO indices to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_ftsoscontract IFtsoGenesis[]The array of FTSO addresses.
+
+
+
+

getSupportedFtsos#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getSupportedFtsos(
+) external view returns (
+    contract IIFtso[] _ftsos);
+
+

Get array of all FTSO contracts for all supported asset indices. +The index of FTSO in returned array does not necessarily correspond to the asset's index. +Due to deletion, some indices might be unsupported.

+

Use getSupportedIndicesAndFtsos to retrieve pairs of correct indices and FTSOs, +where possible "null" holes are readily apparent.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_ftsoscontract IIFtso[]Array of all supported FTSOs.
+
+
+
+

getSupportedIndices#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getSupportedIndices(
+) external view returns (
+    uint256[] _supportedIndices);
+
+

Returns the indices of the currently supported FTSOs. +Active FTSOs are ones that currently receive price feeds.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_supportedIndicesuint256[]Array of all active FTSO indices in increasing order.
+
+
+
+

getSupportedIndicesAndFtsos#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getSupportedIndicesAndFtsos(
+) external view returns (
+    uint256[] _supportedIndices,
+    contract IIFtso[] _ftsos);
+
+

Get all supported indices and corresponding FTSO addresses. +Active FTSOs are ones that currently receive price feeds.

+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_supportedIndicesuint256[]Array of all supported indices.
_ftsoscontract IIFtso[]Array of all supported FTSO addresses.
+
+
+
+

getSupportedIndicesAndSymbols#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getSupportedIndicesAndSymbols(
+) external view returns (
+    uint256[] _supportedIndices,
+    string[] _supportedSymbols);
+
+

Get all supported indices and corresponding symbols. +Active FTSOs are ones that currently receive price feeds.

+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_supportedIndicesuint256[]Array of all supported indices.
_supportedSymbolsstring[]Array of all supported symbols.
+
+
+
+

getSupportedIndicesSymbolsAndFtsos#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getSupportedIndicesSymbolsAndFtsos(
+) external view returns (
+    uint256[] _supportedIndices,
+    string[] _supportedSymbols,
+    contract IIFtso[] _ftsos);
+
+

Get all supported indices, symbols, and corresponding FTSO addresses. +Active FTSOs are ones that currently receive price feeds.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_supportedIndicesuint256[]Array of all supported indices.
_supportedSymbolsstring[]Array of all supported symbols.
_ftsoscontract IIFtso[]Array of all supported FTSO addresses.
+
+
+
+

getSupportedSymbols#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getSupportedSymbols(
+) external view returns (
+    string[] _supportedSymbols);
+
+

Returns the symbols of the currently supported FTSOs. +Active FTSOs are ones that currently receive price feeds.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_supportedSymbolsstring[]Array of all active FTSO symbols in increasing order.
+
+
+
+

getSupportedSymbolsAndFtsos#

+
+

Defined in IFtsoRegistry (Docs, Source).

+
+
+
function getSupportedSymbolsAndFtsos(
+) external view returns (
+    string[] _supportedSymbols,
+    contract IIFtso[] _ftsos);
+
+

Get all supported symbols and corresponding FTSO addresses. +Active FTSOs are ones that currently receive price feeds.

+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_supportedSymbolsstring[]Array of all supported symbols.
_ftsoscontract IIFtso[]Array of all supported FTSO addresses.
+
+
+
+

removeFtso#

+
+

Defined in IIFtsoRegistry (Docs, Source).

+
+
+
function removeFtso(
+    contract IIFtso _ftso
+) external;
+
+

Removes the FTSO and keeps part of the history. +Reverts if the provided address is not supported.

+

From now on, the index this asset was using is "reserved" and cannot be used again. +It will not be returned in any list of currently supported assets.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsocontract IIFtsoAddress of the FTSO contract to remove.
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IIFtsoRewardManager/index.html b/apis/smart-contracts/IIFtsoRewardManager/index.html new file mode 100644 index 000000000..9170daa6e --- /dev/null +++ b/apis/smart-contracts/IIFtsoRewardManager/index.html @@ -0,0 +1,6446 @@ + + + + + + + + + + + + + + + + + + IIFtsoRewardManager - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

IIFtsoRewardManager#

+ +
+

Internal interface for the FtsoRewardManager.

+
+
+

Events#

+
+

DailyAuthorizedInflationSet#

+
+

Defined in IIFtsoRewardManager (Docs, Source).

+
+
+
event DailyAuthorizedInflationSet(
+    uint256 authorizedAmountWei
+)
+
+

Emitted when the contract's daily authorized inflation has been set.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
authorizedAmountWeiuint256Authorized amount of native tokens, in wei.
+
+
+
+

FeePercentageChanged#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
event FeePercentageChanged(
+    address dataProvider,
+    uint256 value,
+    uint256 validFromEpoch
+)
+
+

Emitted when a data provider changes its fee.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
dataProvideraddressAddress of the data provider.
valueuint256New fee, in BIPS.
validFromEpochuint256Epoch ID where the new fee takes effect.
+
+
+
+

FtsoRewardManagerActivated#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
event FtsoRewardManagerActivated(
+    address ftsoRewardManager
+)
+
+

Emitted when the reward manager contract is activated.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
ftsoRewardManageraddressThe reward manager contract.
+
+
+
+

FtsoRewardManagerDeactivated#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
event FtsoRewardManagerDeactivated(
+    address ftsoRewardManager
+)
+
+

Emitted when the reward manager contract is deactivated.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
ftsoRewardManageraddressThe reward manager contract.
+
+
+
+

InflationReceived#

+
+

Defined in IIFtsoRewardManager (Docs, Source).

+
+
+
event InflationReceived(
+    uint256 amountReceivedWei
+)
+
+

Emitted when the contract has received the daily inflation amount.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
amountReceivedWeiuint256Received amount of native tokens, in wei.
+
+
+
+

RewardClaimed#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
event RewardClaimed(
+    address dataProvider,
+    address whoClaimed,
+    address sentTo,
+    uint256 rewardEpoch,
+    uint256 amount
+)
+
+

Emitted when a data provider claims its FTSO rewards.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
dataProvideraddressAddress of the data provider that accrued the reward.
whoClaimedaddressAddress that actually performed the claim.
sentToaddressAddress that received the reward.
rewardEpochuint256ID of the reward epoch where the reward was accrued.
amountuint256Amount of rewarded native tokens (wei).
+
+
+
+

RewardClaimsEnabled#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
event RewardClaimsEnabled(
+    uint256 rewardEpochId
+)
+
+

Emitted when reward claims have been enabled.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
rewardEpochIduint256First claimable reward epoch.
+
+
+
+

RewardClaimsExpired#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
event RewardClaimsExpired(
+    uint256 rewardEpochId
+)
+
+

Unclaimed rewards have expired and are now inaccessible.

+

getUnclaimedReward() can be used to retrieve more information.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
rewardEpochIduint256ID of the reward epoch that has just expired.
+
+
+
+

RewardsBurned#

+
+

Defined in IIFtsoRewardManager (Docs, Source).

+
+
+
event RewardsBurned(
+    uint256 amountBurnedWei
+)
+
+

Emitted when unclaimed rewards are burned.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
amountBurnedWeiuint256Burned amount of native tokens, in wei.
+
+
+
+

RewardsDistributed#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
event RewardsDistributed(
+    address ftso,
+    uint256 epochId,
+    address[] addresses,
+    uint256[] rewards
+)
+
+

Emitted every price epoch, when rewards have been distributed to each contributing data provider. +Note that rewards are not claimable until the reward epoch finishes.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
ftsoaddressAddress of the FTSO that generated the rewards.
epochIduint256ID of the reward epoch where the rewards were accrued.
addressesaddress[]Data provider addresses that have rewards to claim.
rewardsuint256[]Amounts available for claiming (wei).
+
+
+
+

UnearnedRewardsAccrued#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
event UnearnedRewardsAccrued(
+    uint256 epochId,
+    uint256 reward
+)
+
+

Emitted when rewards cannot be distributed during a reward epoch +(for example, because the FTSO went into fallback mode) and they are accrued +for later burning.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
epochIduint256ID of the reward epoch where the reward was accrued.
rewarduint256Total amount of accrued rewards (wei).
+
+
+
+
+

Functions#

+
+

accrueUnearnedRewards#

+
+

Defined in IIFtsoRewardManager (Docs, Source).

+
+
+
function accrueUnearnedRewards(
+    uint256 epochId,
+    uint256 priceEpochDurationSeconds,
+    uint256 priceEpochEndTime
+) external;
+
+

Accrue unearned rewards for a given price epoch. +Typically done when the FTSO is in fallback mode or because of insufficient vote power. +Simply accrue them so they will not be distributed and will be burned later.

+

The amount of rewards that will be burned is calculated in the same way as in distributeRewards.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
epochIduint256Price epoch ID.
priceEpochDurationSecondsuint256Duration of price epochs (180s).
priceEpochEndTimeuint256Timestamp of the price epoch end time (end of submit period), in seconds since UNIX epoch.
+
+
+
+

activate#

+
+

Defined in IIFtsoRewardManager (Docs, Source).

+
+
+
function activate(
+) external;
+
+

Activates reward manager (allows claiming rewards).

+
+
+
+

active#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function active(
+) external view returns (
+    bool);
+
+

Whether rewards can be claimed from this reward manager.

+
+
+
+

autoClaim#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function autoClaim(
+    address[] _rewardOwners,
+    uint256 _rewardEpoch
+) external;
+
+

Allows claiming rewards simultaneously for a list of reward owners and all unclaimed epochs before the +specified one.

+

This is meant as a convenience all-in-one reward claiming method to be used both by reward owners and +registered executors. +It performs a series of operations, besides claiming rewards:

+
    +
  • +

    If a reward owner has enabled its +Personal Delegation Account, rewards are also +claimed for the PDA and the total claimed amount is sent to that PDA. +Otherwise, the claimed amount is sent to the reward owner's account.

    +
  • +
  • +

    Claimed amount is automatically wrapped through the WNat contract.

    +
  • +
  • +

    If the caller is a registered executor with a non-zero fee, the fee is paid to the executor for each claimed +address.

    +
  • +
+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardOwnersaddress[]List of reward owners to claim for.
_rewardEpochuint256Last reward epoch ID to claim for. All previous epochs with pending rewards will be claimed too.
+
+
+
+

claim#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function claim(
+    address _rewardOwner,
+    address payable _recipient,
+    uint256 _rewardEpoch,
+    bool _wrap
+) external returns (
+    uint256 _rewardAmount);
+
+

Allows the caller to claim rewards for a reward owner. +The caller does not have to be the owner of the rewards, but must be approved by the owner to claim on his +behalf by using setClaimExecutors on the claimSetupManager.

+

This function is intended to be used to claim rewards in case of delegation by percentage. +Reverts if msg.sender is delegating by amount.

+

Anybody can call this method, but rewards can only be sent to the reward owner, therefore no funds can be +stolen. However, by limiting the authorized callers, the owner can control the timing of the calls.

+

When the reward owner is the caller, rewards can be sent to any recipient set by setAllowedClaimRecipients on +the claimSetupManager. +The reward owner's Personal Delegation Account +is always an authorized recipient.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardOwneraddressAddress of the reward owner.
_recipientaddress payableAddress to transfer claimed rewards to.
_rewardEpochuint256Last reward epoch to claim for. All previous epochs with pending rewards will be claimed too.
_wrapboolWhether claimed rewards should be wrapped through the WNat contract before transferring them to the _recipient. This parameter is offered as a convenience.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_rewardAmountuint256Total amount of claimed rewards (wei).
+
+
+
+

claimFromDataProviders#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function claimFromDataProviders(
+    address _rewardOwner,
+    address payable _recipient,
+    uint256[] _rewardEpochs,
+    address[] _dataProviders,
+    bool _wrap
+) external returns (
+    uint256 _rewardAmount);
+
+

Allows the caller to claim rewards for a reward owner from specific data providers. +The caller does not have to be the owner of the rewards, but must be approved by the owner to claim on his +behalf by using setClaimExecutors on the claimSetupManager.

+

This function is intended to be used to claim rewards in case of delegation by amount (explicit delegation). +Reverts if msg.sender is delegating by percentage.

+

Anybody can call this method, but rewards can only be sent to the reward owner, therefore no funds can be +stolen. However, by limiting the authorized callers, the owner can control the timing of the calls.

+

When the reward owner is the caller, rewards can be sent to any recipient set by setAllowedClaimRecipients on +the claimSetupManager. +The reward owner's Personal Delegation Account +is always an authorized recipient.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardOwneraddressAddress of the reward owner.
_recipientaddress payableAddress to transfer claimed rewards to.
_rewardEpochsuint256[]Array of reward epoch IDs to claim for.
_dataProvidersaddress[]Array of addresses of the data providers to claim the reward from.
_wrapboolWhether claimed rewards should be wrapped through the WNat contract before transferring them to the _recipient. This parameter is offered as a convenience.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_rewardAmountuint256Total amount of claimed rewards (wei).
+
+
+
+

claimReward#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function claimReward(
+    address payable _recipient,
+    uint256[] _rewardEpochs
+) external returns (
+    uint256 _rewardAmount);
+
+

Allows a percentage delegator to claim rewards. +This function is intended to be used to claim rewards in case of delegation by percentage.

+

This function is deprecated: use claim instead.

+

Reverts if msg.sender is delegating by amount. +Claims for all unclaimed reward epochs to the 'max(_rewardEpochs)'. +Retained for backward compatibility.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_recipientaddress payableAddress to transfer funds to.
_rewardEpochsuint256[]Array of reward epoch numbers to claim for.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_rewardAmountuint256Amount of total claimed rewards (wei).
+
+
+
+

claimRewardFromDataProviders#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function claimRewardFromDataProviders(
+    address payable _recipient,
+    uint256[] _rewardEpochs,
+    address[] _dataProviders
+) external returns (
+    uint256 _rewardAmount);
+
+

Allows the caller to claim rewards from specific data providers. +This function is intended to be used to claim rewards in case of delegation by amount.

+

This function is deprecated: use claimFromDataProviders instead.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_recipientaddress payableAddress to transfer funds to.
_rewardEpochsuint256[]Array of reward epoch numbers to claim for.
_dataProvidersaddress[]Array of addresses of the data providers to claim the reward from.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_rewardAmountuint256Total amount of claimed rewards (wei).
+
+
+
+

closeExpiredRewardEpoch#

+
+

Defined in IIFtsoRewardManager (Docs, Source).

+
+
+
function closeExpiredRewardEpoch(
+    uint256 _rewardEpochId
+) external;
+
+

Collects funds from expired reward epoch and calculates totals.

+

Triggered by ftsoManager on finalization of a reward epoch. +Operation is irreversible: when some reward epoch is closed according to current +settings, it cannot be reopened even if new parameters would +allow it, because nextRewardEpochToExpire in ftsoManager never decreases.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardEpochIduint256ID of the epoch to close.
+
+
+
+

deactivate#

+
+

Defined in IIFtsoRewardManager (Docs, Source).

+
+
+
function deactivate(
+) external;
+
+

Deactivates reward manager (prevents claiming rewards).

+
+
+
+

distributeRewards#

+
+

Defined in IIFtsoRewardManager (Docs, Source).

+
+
+
function distributeRewards(
+    address[] addresses,
+    uint256[] weights,
+    uint256 totalWeight,
+    uint256 epochId,
+    address ftso,
+    uint256 priceEpochDurationSeconds,
+    uint256 currentRewardEpoch,
+    uint256 priceEpochEndTime,
+    uint256 votePowerBlock
+) external;
+
+

Distributes price epoch rewards to data provider accounts, according to input parameters. +Must be called with totalWeight > 0 and addresses.length > 0.

+

The amount of rewards for a given price epoch ID are calculated in FtsoRewardManager from +priceEpochDurationSeconds, priceEpochEndTime and inflation authorization data +(see _getTotalPriceEpochRewardWei in FtsoRewardManager. +Then each data provider address is given a portion of this amount according to corresponding weight +and total sum of weights.

+

Parameters epochId and ftso are only needed so they can be passed onto the emitted event.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
addressesaddress[]Data provider addresses to reward.
weightsuint256[]Weights corresponding to rewarded addresses.
totalWeightuint256Sum of all weights.
epochIduint256Price epoch ID.
ftsoaddressRandomly chosen FTSO contract used to calculate the weights.
priceEpochDurationSecondsuint256Duration of price epochs (180s).
currentRewardEpochuint256ID of the current reward epoch. Rewards for the price epoch are added to this reward epoch.
priceEpochEndTimeuint256Timestamp of the price epoch end time (end of submit period), in seconds since UNIX epoch.
votePowerBlockuint256Vote power block used in the given reward epoch.
+
+
+
+

enableClaims#

+
+

Defined in IIFtsoRewardManager (Docs, Source).

+
+
+
function enableClaims(
+) external;
+
+

Enable claiming for current and all future reward epochs.

+
+
+
+

firstClaimableRewardEpoch#

+
+

Defined in IIFtsoRewardManager (Docs, Source).

+
+
+
function firstClaimableRewardEpoch(
+) external view returns (
+    uint256);
+
+

Epochs before the token distribution event at Flare launch were not be claimable. +Use this method to know the first reward epoch that was claimable.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256uint256 The first reward epoch that can be claimed.
+
+
+
+

getClaimedReward#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getClaimedReward(
+    uint256 _rewardEpoch,
+    address _dataProvider,
+    address _claimer
+) external view returns (
+    bool _claimed,
+    uint256 _amount);
+
+

Returns information on the rewards accrued by a reward owner from a specific data provider at a specific +reward epoch.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardEpochuint256Reward epoch ID to query.
_dataProvideraddressAddress of the data provider to query.
_claimeraddressAddress of the reward owner to query.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_claimedboolWhether the reward has been claimed or not.
_amountuint256Accrued amount in wei.
+
+
+
+

getContractName#

+
+

Defined in IIInflationReceiver (Docs, Source).

+
+
+
function getContractName(
+) external view returns (
+    string);
+
+

Implement this function to allow updating inflation receiver contracts through AddressUpdater.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]stringContract name.
+
+
+
+

getCurrentRewardEpoch#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getCurrentRewardEpoch(
+) external view returns (
+    uint256);
+
+

Returns the current reward epoch ID.

+
+
+
+

getDataProviderCurrentFeePercentage#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getDataProviderCurrentFeePercentage(
+    address _dataProvider
+) external view returns (
+    uint256 _feePercentageBIPS);
+
+

Returns the current fee percentage of a data provider.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_dataProvideraddressAddress of the queried data provider.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_feePercentageBIPSuint256Fee percentage in BIPS.
+
+
+
+

getDataProviderFeePercentage#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getDataProviderFeePercentage(
+    address _dataProvider,
+    uint256 _rewardEpoch
+) external view returns (
+    uint256 _feePercentageBIPS);
+
+

Returns the fee percentage of a data provider at a +given reward epoch.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_dataProvideraddressAddress of the queried data provider.
_rewardEpochuint256Reward epoch ID.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_feePercentageBIPSuint256Fee percentage in BIPS.
+
+
+
+

getDataProviderPerformanceInfo#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getDataProviderPerformanceInfo(
+    uint256 _rewardEpoch,
+    address _dataProvider
+) external view returns (
+    uint256 _rewardAmount,
+    uint256 _votePowerIgnoringRevocation);
+
+

Returns information on rewards and vote power of a data provider at a given reward epoch.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardEpochuint256Reward epoch ID.
_dataProvideraddressAddress of the data provider to query.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_rewardAmountuint256Amount of rewards (wei).
_votePowerIgnoringRevocationuint256Vote power, not including revocations.
+
+
+
+

getDataProviderScheduledFeePercentageChanges#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getDataProviderScheduledFeePercentageChanges(
+    address _dataProvider
+) external view returns (
+    uint256[] _feePercentageBIPS,
+    uint256[] _validFromEpoch,
+    bool[] _fixed);
+
+

Returns the scheduled fee percentage changes for a data +provider.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_dataProvideraddressAddress of the queried data provider.
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_feePercentageBIPSuint256[]Array of fee percentages in BIPS.
_validFromEpochuint256[]Array of block numbers from which the fee settings are effective.
_fixedbool[]Array of boolean values indicating whether settings are subject to change or not.
+
+
+
+

getEpochReward#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getEpochReward(
+    uint256 _rewardEpoch
+) external view returns (
+    uint256 _totalReward,
+    uint256 _claimedReward);
+
+

Returns information on an epoch's rewards.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardEpochuint256Reward epoch ID.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_totalRewarduint256Total amount of rewards accrued on that epoch, in wei.
_claimedRewarduint256Total amount of rewards that have already been claimed, in wei.
+
+
+
+

getEpochsWithClaimableRewards#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getEpochsWithClaimableRewards(
+) external view returns (
+    uint256 _startEpochId,
+    uint256 _endEpochId);
+
+

Returns the reward epoch range for which rewards can be claimed. +Rewards outside this range are unclaimable, either because they have expired or because the reward epoch is +still ongoing.

+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_startEpochIduint256The oldest epoch ID that allows reward claiming.
_endEpochIduint256The newest epoch ID that allows reward claiming.
+
+
+
+

getEpochsWithUnclaimedRewards#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getEpochsWithUnclaimedRewards(
+    address _beneficiary
+) external view returns (
+    uint256[] _epochIds);
+
+

Returns the array of claimable epoch IDs for which the rewards of a reward owner have not yet been claimed.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_beneficiaryaddressAddress of the reward owner to query. Reverts if it uses delegation by amount.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_epochIdsuint256[]Array of epoch IDs.
+
+
+
+

getExpectedBalance#

+
+

Defined in IIInflationReceiver (Docs, Source).

+
+
+
function getExpectedBalance(
+) external view returns (
+    uint256);
+
+

Returns the contract's expected balance +(actual balance may be higher due to self-destruct funds).

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Expected native token balance.
+
+
+
+

getInflationAddress#

+
+

Defined in IIInflationReceiver (Docs, Source).

+
+
+
function getInflationAddress(
+) external returns (
+    address);
+
+

Returns the address of the Inflation contract.

+
+
+
+

getInitialRewardEpoch#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getInitialRewardEpoch(
+) external view returns (
+    uint256);
+
+

Returns the initial reward epoch ID for this reward manager contract. +This corresponds to the oldest reward epoch with claimable rewards in the previous reward manager when this +one took over. +Set by governance through setInitialRewardData.

+
+
+
+

getRewardEpochToExpireNext#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getRewardEpochToExpireNext(
+) external view returns (
+    uint256);
+
+

Returns the reward epoch that will expire next once a new reward epoch starts.

+
+
+
+

getRewardEpochVotePowerBlock#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getRewardEpochVotePowerBlock(
+    uint256 _rewardEpoch
+) external view returns (
+    uint256);
+
+

Returns the vote power block of a given reward epoch.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardEpochuint256Reward epoch ID.
+
+
+
+

getStateOfRewards#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getStateOfRewards(
+    address _beneficiary,
+    uint256 _rewardEpoch
+) external view returns (
+    address[] _dataProviders,
+    uint256[] _rewardAmounts,
+    bool[] _claimed,
+    bool _claimable);
+
+

Returns the state of rewards for a given address at a specific reward epoch.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_beneficiaryaddressAddress of the beneficiary to query. It can be a data provider or a delegator, for example.
Reverts if the queried address is delegating by amount.
_rewardEpochuint256Reward epoch ID to query.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_dataProvidersaddress[]Array of addresses of data providers.
_rewardAmountsuint256[]Array of reward amounts received from each provider, in wei.
_claimedbool[]Array of boolean values indicating whether each reward has been claimed or not.
_claimableboolBoolean value indicating whether rewards are claimable or not.
+
+
+
+

getStateOfRewardsFromDataProviders#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function getStateOfRewardsFromDataProviders(
+    address _beneficiary,
+    uint256 _rewardEpoch,
+    address[] _dataProviders
+) external view returns (
+    uint256[] _rewardAmounts,
+    bool[] _claimed,
+    bool _claimable);
+
+

Returns the state of rewards for a given address coming from a specific set of data providers, at a specific +reward epoch.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_beneficiaryaddressAddress of beneficiary to query.
_rewardEpochuint256Reward epoch ID to query.
_dataProvidersaddress[]Array of addresses of the data providers to query.
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_rewardAmountsuint256[]Array of reward amounts received from each provider, in wei.
_claimedbool[]Array of boolean values indicating whether each reward has been claimed or not.
_claimableboolBoolean value indicating whether rewards are claimable or not.
+
+
+
+

getTokenPoolSupplyData#

+
+

Defined in IITokenPool (Docs, Source).

+
+
+
function getTokenPoolSupplyData(
+) external returns (
+    uint256 _lockedFundsWei,
+    uint256 _totalInflationAuthorizedWei,
+    uint256 _totalClaimedWei);
+
+

Returns token pool supply data.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_lockedFundsWeiuint256Total amount of funds ever locked in the token pool (wei). _lockedFundsWei - _totalClaimedWei is the amount currently locked and outside the circulating supply.
_totalInflationAuthorizedWeiuint256Total inflation authorized amount (wei).
_totalClaimedWeiuint256Total claimed amount (wei).
+
+
+
+

getUnclaimedReward#

+
+

Defined in IIFtsoRewardManager (Docs, Source).

+
+
+
function getUnclaimedReward(
+    uint256 _rewardEpoch,
+    address _dataProvider
+) external view returns (
+    uint256 _amount,
+    uint256 _weight);
+
+

Returns information on unclaimed rewards for a given data provider and epoch.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardEpochuint256Queried reward epoch ID.
_dataProvideraddressAddress of the queried data provider.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_amountuint256Amount available to be claimed, in wei.
_weightuint256Portion of total vote power used in this reward epoch that has not yet claimed its reward, in BIPS. It decreases to 0 when all data providers have claimed their rewards.
+
+
+
+

nextClaimableRewardEpoch#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function nextClaimableRewardEpoch(
+    address _rewardOwner
+) external view returns (
+    uint256);
+
+

Returns the next claimable reward epoch for a reward owner.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_rewardOwneraddressAddress of the reward owner to query.
+
+
+
+

receiveInflation#

+
+

Defined in IIInflationReceiver (Docs, Source).

+
+
+
function receiveInflation(
+) external payable;
+
+

Receive native tokens from inflation.

+
+
+
+

setDailyAuthorizedInflation#

+
+

Defined in IIInflationReceiver (Docs, Source).

+
+
+
function setDailyAuthorizedInflation(
+    uint256 _toAuthorizeWei
+) external;
+
+

Notify the receiver that it is entitled to receive a new inflation amount.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_toAuthorizeWeiuint256The amount of inflation that can be awarded in the coming day, in wei.
+
+
+
+

setDataProviderFeePercentage#

+
+

Defined in IFtsoRewardManager (Docs, Source).

+
+
+
function setDataProviderFeePercentage(
+    uint256 _feePercentageBIPS
+) external returns (
+    uint256 _validFromEpoch);
+
+

Sets the fee a data provider keeps from all delegations.

+

Takes effect after feeValueUpdateOffset reward epochs have elapsed.

+

When called multiple times inside the same reward epoch, only the last value remains.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_feePercentageBIPSuint256Fee percentage in BIPS.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_validFromEpochuint256Reward epoch number when the new fee percentage will become effective.
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IIGovernanceVotePower/index.html b/apis/smart-contracts/IIGovernanceVotePower/index.html new file mode 100644 index 000000000..39a0d25f2 --- /dev/null +++ b/apis/smart-contracts/IIGovernanceVotePower/index.html @@ -0,0 +1,4602 @@ + + + + + + + + + + + + + + + + + + IIGovernanceVotePower - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

IIGovernanceVotePower#

+
+

Source | Inherits from IGovernanceVotePower

+
+
+

Internal interface for contracts delegating their governance vote power.

+
+
+

Events#

+
+

DelegateChanged#

+
+

Defined in IIGovernanceVotePower (Docs, Source).

+
+
+
event DelegateChanged(
+    address delegator,
+    address fromDelegate,
+    address toDelegate
+)
+
+

Emitted when an account starts delegating vote power or switches its delegation +to another address.

+

The event is always emitted from a GovernanceVotePower contract.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
delegatoraddressAccount delegating its vote power.
fromDelegateaddressAccount receiving the delegation before the change. Can be address(0) if there was no previous delegation.
toDelegateaddressAccount receiving the delegation after the change. Can be address(0) if delegator just undelegated all its vote power.
+
+
+
+

DelegateVotesChanged#

+
+

Defined in IIGovernanceVotePower (Docs, Source).

+
+
+
event DelegateVotesChanged(
+    address delegate,
+    uint256 previousBalance,
+    uint256 newBalance
+)
+
+

Emitted when a delegate's vote power changes, as a result of a new delegation +or a token transfer, for example.

+

The event is always emitted from a GovernanceVotePower contract.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
delegateaddressThe account receiving the changing delegated vote power.
previousBalanceuint256Delegated vote power before the change.
newBalanceuint256Delegated vote power after the change.
+
+
+
+
+

Functions#

+
+

delegate#

+
+

Defined in IGovernanceVotePower (Docs, Source).

+
+
+
function delegate(
+    address _to
+) external;
+
+

Delegates all governance vote power of msg.sender to address _to.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_toaddressThe address of the recipient.
+
+
+
+

getCleanupBlockNumber#

+
+

Defined in IIGovernanceVotePower (Docs, Source).

+
+
+
function getCleanupBlockNumber(
+) external view returns (
+    uint256);
+
+

Get the current cleanup block number set with setCleanupBlockNumber.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The currently set cleanup block number.
+
+
+
+

getDelegateOfAt#

+
+

Defined in IGovernanceVotePower (Docs, Source).

+
+
+
function getDelegateOfAt(
+    address _who,
+    uint256 _blockNumber
+) external view returns (
+    address);
+
+

Gets the address an account is delegating its governance vote power to, at a given block number.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address being queried.
_blockNumberuint256The block number at which to fetch the address.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]addressAddress where _who was delegating its governance vote power at block _blockNumber.
+
+
+
+

getDelegateOfAtNow#

+
+

Defined in IGovernanceVotePower (Docs, Source).

+
+
+
function getDelegateOfAtNow(
+    address _who
+) external view returns (
+    address);
+
+

Gets the address an account is delegating its governance vote power to, at the latest block number.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address being queried.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]addressAddress where _who is currently delegating its governance vote power.
+
+
+
+

getVotes#

+
+

Defined in IGovernanceVotePower (Docs, Source).

+
+
+
function getVotes(
+    address _who
+) external view returns (
+    uint256);
+
+

Gets the governance vote power of an address at the latest block, including +all delegations made to it.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address being queried.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Governance vote power of account at the lastest block.
+
+
+
+

ownerToken#

+
+

Defined in IIGovernanceVotePower (Docs, Source).

+
+
+
function ownerToken(
+) external view returns (
+    contract IVPToken);
+
+

Get the token that this governance vote power contract belongs to.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]contract IVPTokenThe IVPToken interface owning this contract.
+
+
+
+

setCleanerContract#

+
+

Defined in IIGovernanceVotePower (Docs, Source).

+
+
+
function setCleanerContract(
+    address _cleanerContract
+) external;
+
+

Set the contract that is allowed to call history cleaning methods.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_cleanerContractaddressAddress of the cleanup contract. Usually this will be an instance of CleanupBlockNumberManager.
+
+
+
+

setCleanupBlockNumber#

+
+

Defined in IIGovernanceVotePower (Docs, Source).

+
+
+
function setCleanupBlockNumber(
+    uint256 _blockNumber
+) external;
+
+

Set the cleanup block number. +Historic data for the blocks before cleanupBlockNumber can be erased. +History before that block should never be used since it can be inconsistent. +In particular, cleanup block number must be lower than the current vote power block.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockNumberuint256The new cleanup block number.
+
+
+
+

undelegate#

+
+

Defined in IGovernanceVotePower (Docs, Source).

+
+
+
function undelegate(
+) external;
+
+

Undelegates all governance vote power of msg.sender.

+
+
+
+

updateAtTokenTransfer#

+
+

Defined in IIGovernanceVotePower (Docs, Source).

+
+
+
function updateAtTokenTransfer(
+    address _from,
+    address _to,
+    uint256 _fromBalance,
+    uint256 _toBalance,
+    uint256 _amount
+) external;
+
+

Update governance vote power of all involved delegates after tokens are transferred.

+

This function MUST be called after each governance token transfer for the +delegates to reflect the correct balance.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressSource address of the transfer.
_toaddressDestination address of the transfer.
_fromBalanceuint256Ignored.
_toBalanceuint256Ignored.
_amountuint256Amount being transferred.
+
+
+
+

votePowerOfAt#

+
+

Defined in IGovernanceVotePower (Docs, Source).

+
+
+
function votePowerOfAt(
+    address _who,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Gets the governance vote power of an address at a given block number, including +all delegations made to it.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address being queried.
_blockNumberuint256The block number at which to fetch the vote power.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Governance vote power of _who at _blockNumber.
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IIInflationReceiver/index.html b/apis/smart-contracts/IIInflationReceiver/index.html new file mode 100644 index 000000000..81641718b --- /dev/null +++ b/apis/smart-contracts/IIInflationReceiver/index.html @@ -0,0 +1,4075 @@ + + + + + + + + + + + + + + + + + + IIInflationReceiver - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

IIInflationReceiver#

+
+

Source

+
+
+

Internal interface for contracts that can receive inflation.

+
+
+

Functions#

+
+

getContractName#

+
+

Defined in IIInflationReceiver (Docs, Source).

+
+
+
function getContractName(
+) external view returns (
+    string);
+
+

Implement this function to allow updating inflation receiver contracts through AddressUpdater.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]stringContract name.
+
+
+
+

getExpectedBalance#

+
+

Defined in IIInflationReceiver (Docs, Source).

+
+
+
function getExpectedBalance(
+) external view returns (
+    uint256);
+
+

Returns the contract's expected balance +(actual balance may be higher due to self-destruct funds).

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Expected native token balance.
+
+
+
+

getInflationAddress#

+
+

Defined in IIInflationReceiver (Docs, Source).

+
+
+
function getInflationAddress(
+) external returns (
+    address);
+
+

Returns the address of the Inflation contract.

+
+
+
+

receiveInflation#

+
+

Defined in IIInflationReceiver (Docs, Source).

+
+
+
function receiveInflation(
+) external payable;
+
+

Receive native tokens from inflation.

+
+
+
+

setDailyAuthorizedInflation#

+
+

Defined in IIInflationReceiver (Docs, Source).

+
+
+
function setDailyAuthorizedInflation(
+    uint256 _toAuthorizeWei
+) external;
+
+

Notify the receiver that it is entitled to receive a new inflation amount.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_toAuthorizeWeiuint256The amount of inflation that can be awarded in the coming day, in wei.
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IIPriceSubmitter/index.html b/apis/smart-contracts/IIPriceSubmitter/index.html new file mode 100644 index 000000000..89e6ae3e0 --- /dev/null +++ b/apis/smart-contracts/IIPriceSubmitter/index.html @@ -0,0 +1,4439 @@ + + + + + + + + + + + + + + + + + + IIPriceSubmitter - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+ +
+
+ + +
+
+ + + + + + + + + + + + +

IIPriceSubmitter#

+
+

Source | Inherits from IPriceSubmitter

+
+
+

Internal interface for the PriceSubmitter contract.

+
+
+

Functions#

+
+

getCurrentRandom#

+
+

Defined in IPriceSubmitter (Docs, Source).

+
+
+
function getCurrentRandom(
+) external view returns (
+    uint256);
+
+

Returns the random number for the previous epoch, obtained from the random numbers +provided by all data providers along with their data submissions. +Note that the random number for the previous epoch keeps updating as new submissions are revealed.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Random number calculated from all data provider's submissions.
+
+
+
+

getFtsoManager#

+
+

Defined in IPriceSubmitter (Docs, Source).

+
+
+
function getFtsoManager(
+) external view returns (
+    contract IFtsoManagerGenesis);
+
+

Returns the address of the FtsoManager contract.

+
+
+
+

getFtsoRegistry#

+
+

Defined in IPriceSubmitter (Docs, Source).

+
+
+
function getFtsoRegistry(
+) external view returns (
+    contract IFtsoRegistryGenesis);
+
+

Returns the address of the FtsoRegistry contract.

+
+
+
+

getRandom#

+
+

Defined in IPriceSubmitter (Docs, Source).

+
+
+
function getRandom(
+    uint256 _epochId
+) external view returns (
+    uint256);
+
+

Returns the random number used in a specific past epoch, obtained from the random numbers +provided by all data providers along with their data submissions.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_epochIduint256ID of the queried epoch. Current epoch cannot be queried, and the previous epoch is constantly updated as data providers reveal their prices and random numbers. Note that only the last 50 epochs can be queried and there is no bounds checking for this parameter. Out-of-bounds queries return undefined values.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The random number used in that epoch.
+
+
+
+

getTrustedAddresses#

+
+

Defined in IIPriceSubmitter (Docs, Source).

+
+
+
function getTrustedAddresses(
+) external view returns (
+    address[]);
+
+

Returns the list of trusted addresses that are always allowed to submit and reveal.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]address[]address[] Array of trusted voter addresses.
+
+
+
+

getVoterWhitelister#

+
+

Defined in IPriceSubmitter (Docs, Source).

+
+
+
function getVoterWhitelister(
+) external view returns (
+    address);
+
+

Returns the address of the VoterWhitelister contract managing the data provider whitelist.

+
+
+
+

revealPrices#

+
+

Defined in IPriceSubmitter (Docs, Source).

+
+
+
function revealPrices(
+    uint256 _epochId,
+    uint256[] _ftsoIndices,
+    uint256[] _prices,
+    uint256 _random
+) external;
+
+

Reveals submitted prices during the epoch reveal period. +The hash of FTSO indices, prices, random number, and voter address must be equal +to the hash previously submitted with submitHash. +Emits a PricesRevealed event.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_epochIduint256ID of the epoch to which the price hashes are submitted.
_ftsoIndicesuint256[]List of FTSO indices in ascending order.
_pricesuint256[]List of submitted prices in USD.
_randomuint256Submitted random number.
+
+
+
+

setTrustedAddresses#

+
+

Defined in IIPriceSubmitter (Docs, Source).

+
+
+
function setTrustedAddresses(
+    address[] _trustedAddresses
+) external;
+
+

Set trusted addresses that are always allowed to submit and reveal. +Only ftso manager can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_trustedAddressesaddress[]Array of voter addresses.
+
+
+
+

submitHash#

+
+

Defined in IPriceSubmitter (Docs, Source).

+
+
+
function submitHash(
+    uint256 _epochId,
+    bytes32 _hash
+) external;
+
+

Submits a hash for the current epoch. Can only be called by FTSO data providers +whitelisted through the VoterWhitelisted contract. +Emits the HashSubmitted event.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_epochIduint256ID of the target epoch to which the hash is submitted.
_hashbytes32A hash of the FTSO indices, prices, random number, and voter address.
+
+
+
+

voterWhitelistBitmap#

+
+

Defined in IPriceSubmitter (Docs, Source).

+
+
+
function voterWhitelistBitmap(
+    address _voter
+) external view returns (
+    uint256);
+
+

Returns a bitmap of all FTSOs for which a data provider is allowed to submit prices or hashes.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_voteraddressAddress of the voter.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256If a data provider is allowed to vote for a given FTSO index, the corresponding bit in the result is 1.
+
+
+
+

voterWhitelisted#

+
+

Defined in IIPriceSubmitter (Docs, Source).

+
+
+
function voterWhitelisted(
+    address _voter,
+    uint256 _ftsoIndex
+) external;
+
+

Called from the VoterWhitelister contract when a new voter has been whitelisted.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_voteraddressVoter address that has been added to the whitelist.
_ftsoIndexuint256Index of the FTSO to which the voter has registered. Each FTSO has its own whitelist.
+
+
+
+

votersRemovedFromWhitelist#

+
+

Defined in IIPriceSubmitter (Docs, Source).

+
+
+
function votersRemovedFromWhitelist(
+    address[] _voters,
+    uint256 _ftsoIndex
+) external;
+
+

Called from the VoterWhitelister contract when one or more voters have been removed.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_votersaddress[]Array of voter addresses that have been removed.
_ftsoIndexuint256Index of the FTSO to which the voters were registered. Each FTSO has its own whitelist.
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IITokenPool/index.html b/apis/smart-contracts/IITokenPool/index.html new file mode 100644 index 000000000..f448d3a2e --- /dev/null +++ b/apis/smart-contracts/IITokenPool/index.html @@ -0,0 +1,3947 @@ + + + + + + + + + + + + + + + + + + IITokenPool - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

IITokenPool#

+
+

Source

+
+
+

Internal interface for token pools.

+
+
+

Functions#

+
+

getTokenPoolSupplyData#

+
+

Defined in IITokenPool (Docs, Source).

+
+
+
function getTokenPoolSupplyData(
+) external returns (
+    uint256 _lockedFundsWei,
+    uint256 _totalInflationAuthorizedWei,
+    uint256 _totalClaimedWei);
+
+

Returns token pool supply data.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_lockedFundsWeiuint256Total amount of funds ever locked in the token pool (wei). _lockedFundsWei - _totalClaimedWei is the amount currently locked and outside the circulating supply.
_totalInflationAuthorizedWeiuint256Total inflation authorized amount (wei).
_totalClaimedWeiuint256Total claimed amount (wei).
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IIVPContract/index.html b/apis/smart-contracts/IIVPContract/index.html new file mode 100644 index 000000000..2a6f17974 --- /dev/null +++ b/apis/smart-contracts/IIVPContract/index.html @@ -0,0 +1,5298 @@ + + + + + + + + + + + + + + + + + + IIVPContract - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + +

IIVPContract#

+
+

Source | Inherits from IICleanable, IVPContractEvents

+
+
+

Internal interface for helper contracts handling functionality for an associated VPToken.

+
+
+

Functions#

+
+

batchVotePowerOfAt#

+
+

Defined in IIVPContract (Docs, Source).

+
+
+
function batchVotePowerOfAt(
+    address[] _owners,
+    uint256 _blockNumber
+) external view returns (
+    uint256[]);
+
+

Get the vote power of a set of addresses at a given block number.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_ownersaddress[]The list of addresses being queried.
_blockNumberuint256The block number being queried.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256[]Vote power of each address at _blockNumber, including any delegation received.
+
+
+
+

cleanupBlockNumber#

+
+

Defined in IICleanable (Docs, Source).

+
+
+
function cleanupBlockNumber(
+) external view returns (
+    uint256);
+
+

Get the current cleanup block number set with setCleanupBlockNumber.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The currently set cleanup block number.
+
+
+
+

delegate#

+
+

Defined in IIVPContract (Docs, Source).

+
+
+
function delegate(
+    address _from,
+    address _to,
+    uint256 _balance,
+    uint256 _bips
+) external;
+
+

Delegate _bips percentage of voting power from a delegator address to a delegatee address.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressThe address of the delegator.
_toaddressThe address of the delegatee.
_balanceuint256The delegator's current balance
_bipsuint256The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: every call resets the delegation value (and a value of 0 revokes delegation).
+
+
+
+

delegateExplicit#

+
+

Defined in IIVPContract (Docs, Source).

+
+
+
function delegateExplicit(
+    address _from,
+    address _to,
+    uint256 _balance,
+    uint256 _amount
+) external;
+
+

Explicitly delegate _amount tokens of voting power from a delegator address to a delegatee address.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressThe address of the delegator.
_toaddressThe address of the delegatee.
_balanceuint256The delegator's current balance.
_amountuint256An explicit vote power amount to be delegated. Not cumulative: every call resets the delegation value (and a value of 0 undelegates _to).
+
+
+
+

delegatesOf#

+
+

Defined in IIVPContract (Docs, Source).

+
+
+
function delegatesOf(
+    address _owner
+) external view returns (
+    address[] _delegateAddresses,
+    uint256[] _bips,
+    uint256 _count,
+    uint256 _delegationMode);
+
+

Get the percentages and addresses being delegated to by a vote power delegator.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address of the delegator being queried.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_delegateAddressesaddress[]Array of delegatee addresses.
_bipsuint256[]Array of delegation percents specified in basis points (1/100 or 1 percent), for each delegatee.
_countuint256The number of returned delegatees.
_delegationModeuint256The mode of the delegation (NOTSET=0, PERCENTAGE=1, AMOUNT=2). See Delegatable.DelegationMode.
+
+
+
+

delegatesOfAt#

+
+

Defined in IIVPContract (Docs, Source).

+
+
+
function delegatesOfAt(
+    address _owner,
+    uint256 _blockNumber
+) external view returns (
+    address[] _delegateAddresses,
+    uint256[] _bips,
+    uint256 _count,
+    uint256 _delegationMode);
+
+

Get the percentages and addresses being delegated to by a vote power delegator, +at a given block.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address of the delegator being queried.
_blockNumberuint256The block number being queried.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_delegateAddressesaddress[]Array of delegatee addresses.
_bipsuint256[]Array of delegation percents specified in basis points (1/100 or 1 percent), for each delegatee.
_countuint256The number of returned delegatees.
_delegationModeuint256The mode of the delegation (NOTSET=0, PERCENTAGE=1, AMOUNT=2). See Delegatable.DelegationMode.
+
+
+
+

delegationModeOf#

+
+

Defined in IIVPContract (Docs, Source).

+
+
+
function delegationModeOf(
+    address _who
+) external view returns (
+    uint256);
+
+

Get the delegation mode of an address. This mode determines whether vote power is +allocated by percentage or by explicit value and cannot be changed once set with +delegate or delegateExplicit.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address being queried.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Delegation mode (NOTSET=0, PERCENTAGE=1, AMOUNT=2). See Delegatable.DelegationMode.
+
+
+
+

isReplacement#

+
+

Defined in IIVPContract (Docs, Source).

+
+
+
function isReplacement(
+) external view returns (
+    bool);
+
+

Return true if this IIVPContract is configured to be used as a replacement for other contract. +It means that vote powers are not necessarily correct at the initialization, therefore +every method that reads vote power must check whether it is initialized for that address and block.

+
+
+
+

ownerToken#

+
+

Defined in IIVPContract (Docs, Source).

+
+
+
function ownerToken(
+) external view returns (
+    contract IVPToken);
+
+

The VPToken (or some other contract) that owns this VPContract. +All state changing methods may be called only from this address. +This is because original msg.sender is typically sent in a parameter +and we must make sure that it cannot be faked by directly calling +IIVPContract methods. +Owner token is also used in case of replacement to recover vote powers from balances.

+
+
+
+

revokeDelegationAt#

+
+

Defined in IIVPContract (Docs, Source).

+
+
+
function revokeDelegationAt(
+    address _from,
+    address _to,
+    uint256 _balance,
+    uint256 _blockNumber
+) external;
+
+

Revoke all vote power delegation from a delegator address to a delegatee address at a given block. +Only affects the reads via votePowerOfAtCached in the block _blockNumber. +This method should be used only to prevent rogue delegate voting in the current voting block. +To stop delegating use delegate or delegateExplicit with value of 0, +or undelegateAll/ undelegateAllExplicit.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressThe address of the delegator.
_toaddressAddress of the delegatee.
_balanceuint256The delegator's current balance.
_blockNumberuint256The block number at which to revoke delegation. Must be in the past.
+
+
+
+

setCleanerContract#

+
+

Defined in IICleanable (Docs, Source).

+
+
+
function setCleanerContract(
+    address _cleanerContract
+) external;
+
+

Set the contract that is allowed to call history cleaning methods.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_cleanerContractaddressAddress of the cleanup contract. Usually this will be an instance of CleanupBlockNumberManager.
+
+
+
+

setCleanupBlockNumber#

+
+

Defined in IICleanable (Docs, Source).

+
+
+
function setCleanupBlockNumber(
+    uint256 _blockNumber
+) external;
+
+

Set the cleanup block number. +Historic data for the blocks before cleanupBlockNumber can be erased. +History before that block should never be used since it can be inconsistent. +In particular, cleanup block number must be lower than the current vote power block.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockNumberuint256The new cleanup block number.
+
+
+
+

undelegateAll#

+
+

Defined in IIVPContract (Docs, Source).

+
+
+
function undelegateAll(
+    address _from,
+    uint256 _balance
+) external;
+
+

Undelegate all voting power for a delegator address. +Can only be used with percentage delegation. +Does not reset delegation mode back to NOTSET.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressThe address of the delegator.
_balanceuint256The delegator's current balance.
+
+
+
+

undelegateAllExplicit#

+
+

Defined in IIVPContract (Docs, Source).

+
+
+
function undelegateAllExplicit(
+    address _from,
+    address[] _delegateAddresses
+) external returns (
+    uint256);
+
+

Undelegate all explicit vote power by amount for a delegator address. +Can only be used with explicit delegation. +Does not reset delegation mode back to NOTSET.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressThe address of the delegator.
_delegateAddressesaddress[]Explicit delegation does not store delegatees' addresses, so the caller must supply them.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The amount still delegated (in case the list of delegates was incomplete).
+
+
+
+

undelegatedVotePowerOf#

+
+

Defined in IIVPContract (Docs, Source).

+
+
+
function undelegatedVotePowerOf(
+    address _owner,
+    uint256 _balance
+) external view returns (
+    uint256);
+
+

Compute the current undelegated vote power of an address.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address being queried.
_balanceuint256Current balance of that address.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The unallocated vote power of _owner, this is, the amount of vote power currently not being delegated to other addresses.
+
+
+
+

undelegatedVotePowerOfAt#

+
+

Defined in IIVPContract (Docs, Source).

+
+
+
function undelegatedVotePowerOfAt(
+    address _owner,
+    uint256 _balance,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Compute the undelegated vote power of an address at a given block.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address being queried.
_balanceuint256
_blockNumberuint256The block number being queried.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The unallocated vote power of _owner, this is, the amount of vote power that was not being delegated to other addresses at that block number.
+
+
+
+

updateAtTokenTransfer#

+
+

Defined in IIVPContract (Docs, Source).

+
+
+
function updateAtTokenTransfer(
+    address _from,
+    address _to,
+    uint256 _fromBalance,
+    uint256 _toBalance,
+    uint256 _amount
+) external;
+
+

Update vote powers when tokens are transferred. +Also update delegated vote powers for percentage delegation +and check for enough funds for explicit delegations.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressSource account of the transfer.
_toaddressDestination account of the transfer.
_fromBalanceuint256Balance of the source account before the transfer.
_toBalanceuint256Balance of the destination account before the transfer.
_amountuint256Amount that has been transferred.
+
+
+
+

votePowerFromTo#

+
+

Defined in IIVPContract (Docs, Source).

+
+
+
function votePowerFromTo(
+    address _from,
+    address _to,
+    uint256 _balance
+) external view returns (
+    uint256);
+
+

Get current delegated vote power from a delegator to a delegatee.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressAddress of the delegator.
_toaddressAddress of the delegatee.
_balanceuint256The delegator's current balance.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The delegated vote power.
+
+
+
+

votePowerFromToAt#

+
+

Defined in IIVPContract (Docs, Source).

+
+
+
function votePowerFromToAt(
+    address _from,
+    address _to,
+    uint256 _balance,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Get delegated the vote power from a delegator to a delegatee at a given block number.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressAddress of the delegator.
_toaddressAddress of the delegatee.
_balanceuint256The delegator's current balance.
_blockNumberuint256The block number being queried.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The delegated vote power.
+
+
+
+

votePowerOf#

+
+

Defined in IIVPContract (Docs, Source).

+
+
+
function votePowerOf(
+    address _who
+) external view returns (
+    uint256);
+
+

Get the current vote power of an address.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address being queried.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Current vote power of _who, including any delegation received.
+
+
+
+

votePowerOfAt#

+
+

Defined in IIVPContract (Docs, Source).

+
+
+
function votePowerOfAt(
+    address _who,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Get the vote power of an address at a given block number

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address being queried.
_blockNumberuint256The block number being queried.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Vote power of _who at _blockNumber, including any delegation received.
+
+
+
+

votePowerOfAtCached#

+
+

Defined in IIVPContract (Docs, Source).

+
+
+
function votePowerOfAtCached(
+    address _who,
+    uint256 _blockNumber
+) external returns (
+    uint256);
+
+

Get the vote power of an address at a given block number. +Reads/updates cache and upholds revocations.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address being queried.
_blockNumberuint256The block number being queried.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Vote power of _who at _blockNumber, including any delegation received.
+
+
+
+

votePowerOfAtIgnoringRevocation#

+
+

Defined in IIVPContract (Docs, Source).

+
+
+
function votePowerOfAtIgnoringRevocation(
+    address _who,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Get the vote power of an address at a given block number, ignoring revocation information and cache.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address being queried.
_blockNumberuint256The block number being queried.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Vote power of _who at _blockNumber, including any delegation received. Result doesn't change if vote power is revoked.
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IIVPToken/index.html b/apis/smart-contracts/IIVPToken/index.html new file mode 100644 index 000000000..c19f8abca --- /dev/null +++ b/apis/smart-contracts/IIVPToken/index.html @@ -0,0 +1,5860 @@ + + + + + + + + + + + + + + + + + + IIVPToken - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + +

IIVPToken#

+
+

Source | Inherits from IVPToken, IICleanable

+
+
+

Vote power token internal interface.

+
+
+

Functions#

+
+

allowance#

+
+

Defined in IERC20 (Source).

+
+
+
function allowance(
+    address owner,
+    address spender
+) external view returns (
+    uint256);
+
+

Returns the remaining number of tokens that spender will be +allowed to spend on behalf of owner through transferFrom. This is +zero by default.

+

This value changes when approve or transferFrom are called.

+
+
+
+

approve#

+
+

Defined in IERC20 (Source).

+
+
+
function approve(
+    address spender,
+    uint256 amount
+) external returns (
+    bool);
+
+

Sets amount as the allowance of spender over the caller's tokens.

+

Returns a boolean value indicating whether the operation succeeded.

+

IMPORTANT: Beware that changing an allowance with this method brings the risk +that someone may use both the old and the new allowance by unfortunate +transaction ordering. One possible solution to mitigate this race +condition is to first reduce the spender's allowance to 0 and set the +desired value afterwards: +https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729

+

Emits an Approval event.

+
+
+
+

balanceOf#

+
+

Defined in IERC20 (Source).

+
+
+
function balanceOf(
+    address account
+) external view returns (
+    uint256);
+
+

Returns the amount of tokens owned by account.

+
+
+
+

balanceOfAt#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function balanceOfAt(
+    address _owner,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Queries the token balance of _owner at a specific _blockNumber.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address from which the balance will be retrieved.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The balance at _blockNumber.
+
+
+
+

batchDelegate#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function batchDelegate(
+    address[] _delegatees,
+    uint256[] _bips
+) external;
+
+

Undelegate all percentage delegations from the sender and then delegate corresponding + _bips percentage of voting power from the sender to each member of the _delegatees array.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_delegateesaddress[]The addresses of the new recipients.
_bipsuint256[]The percentages of voting power to be delegated expressed in basis points (1/100 of one percent). The sum of all _bips values must be at most 10000 (100%).
+
+
+
+

batchVotePowerOfAt#

+
+

Defined in IIVPToken (Docs, Source).

+
+
+
function batchVotePowerOfAt(
+    address[] _owners,
+    uint256 _blockNumber
+) external view returns (
+    uint256[]);
+
+

Return the vote power for several addresses.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_ownersaddress[]The list of addresses to query.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256[]Array of vote power for each queried address.
+
+
+
+

cleanupBlockNumber#

+
+

Defined in IICleanable (Docs, Source).

+
+
+
function cleanupBlockNumber(
+) external view returns (
+    uint256);
+
+

Get the current cleanup block number set with setCleanupBlockNumber.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The currently set cleanup block number.
+
+
+
+

decimals#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function decimals(
+) external view returns (
+    uint8);
+
+

Returns the number of decimals used to get its user representation. +For example, if decimals equals 2, a balance of 505 tokens should +be displayed to a user as 5.05 (505 / 102).

+

Tokens usually opt for a value of 18, imitating the relationship between +Ether and wei. This is the default value returned by this function, unless +it's overridden.

+

NOTE: This information is only used for display purposes: it in +no way affects any of the arithmetic of the contract, including +balanceOf and transfer.

+

Should be compatible with ERC20 method.

+
+
+
+

delegate#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function delegate(
+    address _to,
+    uint256 _bips
+) external;
+
+

Delegate voting power to account _to from msg.sender, by percentage.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_toaddressThe address of the recipient.
_bipsuint256The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: every call resets the delegation value (and a value of 0 revokes all previous delegations).
+
+
+
+

delegateExplicit#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function delegateExplicit(
+    address _to,
+    uint256 _amount
+) external;
+
+

Explicitly delegate _amount voting power to account _to from msg.sender. +Compare with delegate which delegates by percentage.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_toaddressThe address of the recipient.
_amountuint256An explicit vote power amount to be delegated. Not cumulative: every call resets the delegation value (and a value of 0 revokes all previous delegations).
+
+
+
+

delegatesOf#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function delegatesOf(
+    address _who
+) external view returns (
+    address[] _delegateAddresses,
+    uint256[] _bips,
+    uint256 _count,
+    uint256 _delegationMode);
+
+

Get the list of addresses to which _who is delegating, and their percentages.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address to query.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_delegateAddressesaddress[]Positional array of addresses being delegated to.
_bipsuint256[]Positional array of delegation percents specified in basis points (1/100 of 1 percent). Each one matches the address in the same position in the _delegateAddresses array.
_countuint256The number of delegates.
_delegationModeuint256Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).
+
+
+
+

delegatesOfAt#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function delegatesOfAt(
+    address _who,
+    uint256 _blockNumber
+) external view returns (
+    address[] _delegateAddresses,
+    uint256[] _bips,
+    uint256 _count,
+    uint256 _delegationMode);
+
+

Get the list of addresses to which _who is delegating, and their percentages, at the given block.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address to query.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_delegateAddressesaddress[]Positional array of addresses being delegated to.
_bipsuint256[]Positional array of delegation percents specified in basis points (1/100 of 1 percent). Each one matches the address in the same position in the _delegateAddresses array.
_countuint256The number of delegates.
_delegationModeuint256Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).
+
+
+
+

delegationModeOf#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function delegationModeOf(
+    address _who
+) external view returns (
+    uint256);
+
+

Get the delegation mode for account '_who'. This mode determines whether vote power is +allocated by percentage or by explicit amount. Once the delegation mode is set, +it can never be changed, even if all delegations are removed.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address to get delegation mode.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).
+
+
+
+

governanceVotePower#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function governanceVotePower(
+) external view returns (
+    contract IGovernanceVotePower);
+
+

When set, allows token owners to participate in governance voting +and delegating governance vote power.

+
+
+
+

name#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function name(
+) external view returns (
+    string);
+
+

Returns the name of the token.

+

Should be compatible with ERC20 method.

+
+
+
+

readVotePowerContract#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function readVotePowerContract(
+) external view returns (
+    contract IVPContractEvents);
+
+

Returns VPContract event interface used for read-only operations (view methods). +The only non-view method that might be called on it is revokeDelegationAt.

+

readVotePowerContract is almost always equal to writeVotePowerContract +except during an upgrade from one VPContract to a new version (which should happen +rarely or never and will be announced beforehand).

+

Do not call any methods on VPContract directly. +State changing methods are forbidden from direct calls. +All methods are exposed via VPToken. +This is the reason that this method returns IVPContractEvents. +Use it only for listening to events and revoking.

+
+
+
+

revokeDelegationAt#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function revokeDelegationAt(
+    address _who,
+    uint256 _blockNumber
+) external;
+
+

Revoke all delegation from sender to _who at given block. +Only affects the reads via votePowerOfAtCached() in the block _blockNumber. +Block _blockNumber must be in the past. +This method should be used only to prevent rogue delegate voting in the current voting block. +To stop delegating use delegate / delegateExplicit with value of 0 or undelegateAll / undelegateAllExplicit.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressAddress of the delegatee.
_blockNumberuint256The block number at which to revoke delegation..
+
+
+
+

setCleanerContract#

+
+

Defined in IICleanable (Docs, Source).

+
+
+
function setCleanerContract(
+    address _cleanerContract
+) external;
+
+

Set the contract that is allowed to call history cleaning methods.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_cleanerContractaddressAddress of the cleanup contract. Usually this will be an instance of CleanupBlockNumberManager.
+
+
+
+

setCleanupBlockNumber#

+
+

Defined in IICleanable (Docs, Source).

+
+
+
function setCleanupBlockNumber(
+    uint256 _blockNumber
+) external;
+
+

Set the cleanup block number. +Historic data for the blocks before cleanupBlockNumber can be erased. +History before that block should never be used since it can be inconsistent. +In particular, cleanup block number must be lower than the current vote power block.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockNumberuint256The new cleanup block number.
+
+
+
+

setCleanupBlockNumberManager#

+
+

Defined in IIVPToken (Docs, Source).

+
+
+
function setCleanupBlockNumberManager(
+    address _cleanupBlockNumberManager
+) external;
+
+

Set the contract that is allowed to set cleanupBlockNumber. +Usually this will be an instance of CleanupBlockNumberManager.

+
+
+
+

setGovernanceVotePower#

+
+

Defined in IIVPToken (Docs, Source).

+
+
+
function setGovernanceVotePower(
+    contract IIGovernanceVotePower _governanceVotePower
+) external;
+
+

Sets new governance vote power contract that allows token owners to participate in governance voting +and delegate governance vote power.

+
+
+
+

symbol#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function symbol(
+) external view returns (
+    string);
+
+

Returns the symbol of the token, usually a shorter version of the name.

+

Should be compatible with ERC20 method.

+
+
+
+

totalSupply#

+
+

Defined in IERC20 (Source).

+
+
+
function totalSupply(
+) external view returns (
+    uint256);
+
+

Returns the amount of tokens in existence.

+
+
+
+

totalSupplyAt#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function totalSupplyAt(
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Total amount of tokens held by all accounts at a specific block number.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The total amount of tokens at _blockNumber.
+
+
+
+

totalVotePower#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function totalVotePower(
+) external view returns (
+    uint256);
+
+

Get the current total vote power.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The current total vote power (sum of all accounts' vote power).
+
+
+
+

totalVotePowerAt#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function totalVotePowerAt(
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Get the total vote power at block _blockNumber.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The total vote power at the queried block (sum of all accounts' vote powers).
+
+
+
+

totalVotePowerAtCached#

+
+

Defined in IIVPToken (Docs, Source).

+
+
+
function totalVotePowerAtCached(
+    uint256 _blockNumber
+) external returns (
+    uint256);
+
+

Get the total vote power at block _blockNumber using cache. + It tries to read the cached value and if it is not found, reads the actual value and stores it in the cache. + Can only be used if _blockNumber is in the past, otherwise reverts.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The total vote power at the queried block (sum of all accounts' vote powers).
+
+
+
+

transfer#

+
+

Defined in IERC20 (Source).

+
+
+
function transfer(
+    address recipient,
+    uint256 amount
+) external returns (
+    bool);
+
+

Moves amount tokens from the caller's account to recipient.

+

Returns a boolean value indicating whether the operation succeeded.

+

Emits a Transfer event.

+
+
+
+

transferFrom#

+
+

Defined in IERC20 (Source).

+
+
+
function transferFrom(
+    address sender,
+    address recipient,
+    uint256 amount
+) external returns (
+    bool);
+
+

Moves amount tokens from sender to recipient using the +allowance mechanism. amount is then deducted from the caller's +allowance.

+

Returns a boolean value indicating whether the operation succeeded.

+

Emits a Transfer event.

+
+
+
+

undelegateAll#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function undelegateAll(
+) external;
+
+

Undelegate all voting power of msg.sender. This effectively revokes all previous delegations. +Can only be used with percentage delegation. +Does not reset delegation mode back to NOT SET.

+
+
+
+

undelegateAllExplicit#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function undelegateAllExplicit(
+    address[] _delegateAddresses
+) external returns (
+    uint256);
+
+

Undelegate all explicit vote power by amount of msg.sender. +Can only be used with explicit delegation. +Does not reset delegation mode back to NOT SET.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_delegateAddressesaddress[]Explicit delegation does not store delegatees' addresses, so the caller must supply them.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The amount still delegated (in case the list of delegates was incomplete).
+
+
+
+

undelegatedVotePowerOf#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function undelegatedVotePowerOf(
+    address _owner
+) external view returns (
+    uint256);
+
+

Compute the current undelegated vote power of the _owner account.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The unallocated vote power of _owner.
+
+
+
+

undelegatedVotePowerOfAt#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function undelegatedVotePowerOfAt(
+    address _owner,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Get the undelegated vote power of the _owner account at a given block number.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address to query.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The unallocated vote power of _owner.
+
+
+
+

votePowerFromTo#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function votePowerFromTo(
+    address _from,
+    address _to
+) external view returns (
+    uint256);
+
+

Get current delegated vote power from delegator _from to delegatee _to.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressAddress of delegator.
_toaddressAddress of delegatee.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256votePower The delegated vote power.
+
+
+
+

votePowerFromToAt#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function votePowerFromToAt(
+    address _from,
+    address _to,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Get delegated vote power from delegator _from to delegatee _to at _blockNumber.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressAddress of delegator.
_toaddressAddress of delegatee.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The delegated vote power.
+
+
+
+

votePowerOf#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function votePowerOf(
+    address _owner
+) external view returns (
+    uint256);
+
+

Get the current vote power of _owner.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Current vote power of _owner.
+
+
+
+

votePowerOfAt#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function votePowerOfAt(
+    address _owner,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Get the vote power of _owner at block _blockNumber

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address to query.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Vote power of _owner at block number _blockNumber.
+
+
+
+

votePowerOfAtCached#

+
+

Defined in IIVPToken (Docs, Source).

+
+
+
function votePowerOfAtCached(
+    address _owner,
+    uint256 _blockNumber
+) external returns (
+    uint256);
+
+

Get the vote power of _owner at block _blockNumber using cache. + It tries to read the cached value and if it is not found, reads the actual value and stores it in the cache. + Can only be used if _blockNumber is in the past, otherwise reverts.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address to query.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Vote power of _owner at _blockNumber.
+
+
+
+

votePowerOfAtIgnoringRevocation#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function votePowerOfAtIgnoringRevocation(
+    address _owner,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Get the vote power of _owner at block _blockNumber, ignoring revocation information (and cache).

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address to query.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Vote power of _owner at block number _blockNumber. Result doesn't change if vote power is revoked.
+
+
+
+

writeVotePowerContract#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function writeVotePowerContract(
+) external view returns (
+    contract IVPContractEvents);
+
+

Returns VPContract event interface used for state-changing operations (non-view methods). +The only non-view method that might be called on it is revokeDelegationAt.

+

writeVotePowerContract is almost always equal to readVotePowerContract, +except during upgrade from one VPContract to a new version (which should happen +rarely or never and will be announced beforehand). +In the case of an upgrade, writeVotePowerContract is replaced first to establish delegations. +After some period (e.g., after a reward epoch ends), readVotePowerContract is set equal to it.

+

Do not call any methods on VPContract directly. +State changing methods are forbidden from direct calls. +All are exposed via VPToken. +This is the reason that this method returns IVPContractEvents +Use it only for listening to events, delegating, and revoking.

+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IIVoterWhitelister/index.html b/apis/smart-contracts/IIVoterWhitelister/index.html new file mode 100644 index 000000000..68f612623 --- /dev/null +++ b/apis/smart-contracts/IIVoterWhitelister/index.html @@ -0,0 +1,4582 @@ + + + + + + + + + + + + + + + + + + IIVoterWhitelister - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + +

IIVoterWhitelister#

+
+

Source | Inherits from IVoterWhitelister

+
+
+

Internal interface for managers of the FTSO whitelist.

+

Only addresses registered in this contract can submit data to the FTSO system.

+
+
+

Functions#

+
+

addFtso#

+
+

Defined in IIVoterWhitelister (Docs, Source).

+
+
+
function addFtso(
+    uint256 _ftsoIndex
+) external;
+
+

Create an empty whitelist with default size for a new FTSO.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsoIndexuint256Index of the new FTSO.
+
+
+
+

chillVoter#

+
+

Defined in IIVoterWhitelister (Docs, Source).

+
+
+
function chillVoter(
+    address _voter,
+    uint256 _noOfRewardEpochs,
+    uint256[] _ftsoIndices
+) external returns (
+    bool[] _removed,
+    uint256 _untilRewardEpoch);
+
+

Used to chill a data provider, this is, remove it from the whitelist for a +specified number of reward epochs.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_voteraddressData provider being chilled.
_noOfRewardEpochsuint256Number of epochs to chill the provider for.
_ftsoIndicesuint256[]Array of indices of the FTSOs that will not allow this provider to submit data.
+
+
+
+

chilledUntilRewardEpoch#

+
+

Defined in IVoterWhitelister (Docs, Source).

+
+
+
function chilledUntilRewardEpoch(
+    address _voter
+) external view returns (
+    uint256);
+
+

In case of providing bad prices (e.g. collusion), the voter can be chilled for a few reward epochs. +A voter can whitelist again from a returned reward epoch onwards.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_voteraddressAddress of the queried data provider.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256uint256 ID of the epoch where the data provider can start submitting prices again.
+
+
+
+

defaultMaxVotersForFtso#

+
+

Defined in IVoterWhitelister (Docs, Source).

+
+
+
function defaultMaxVotersForFtso(
+) external view returns (
+    uint256);
+
+

Maximum number of voters in the whitelist for a new FTSO.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256uint256 Default maximum allowed voters.
+
+
+
+

getFtsoWhitelistedPriceProviders#

+
+

Defined in IVoterWhitelister (Docs, Source).

+
+
+
function getFtsoWhitelistedPriceProviders(
+    uint256 _ftsoIndex
+) external view returns (
+    address[]);
+
+

Gets whitelisted price providers for the FTSO at a given index.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsoIndexuint256Queried index.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]address[]Array of addresses of the whitelisted data providers.
+
+
+
+

getFtsoWhitelistedPriceProvidersBySymbol#

+
+

Defined in IVoterWhitelister (Docs, Source).

+
+
+
function getFtsoWhitelistedPriceProvidersBySymbol(
+    string _symbol
+) external view returns (
+    address[]);
+
+

Gets whitelisted price providers for the FTSO with a specified symbol.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_symbolstringQueried symbol.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]address[]Array of addresses of the whitelisted data providers.
+
+
+
+

maxVotersForFtso#

+
+

Defined in IVoterWhitelister (Docs, Source).

+
+
+
function maxVotersForFtso(
+    uint256 _ftsoIndex
+) external view returns (
+    uint256);
+
+

Maximum number of voters in the whitelist for a specific FTSO. +Adjustable separately for each index.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsoIndexuint256Index of the FTSO.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256uint256 Maximum allowed voters.
+
+
+
+

removeFtso#

+
+

Defined in IIVoterWhitelister (Docs, Source).

+
+
+
function removeFtso(
+    uint256 _ftsoIndex
+) external;
+
+

Clear whitelist for a removed FTSO.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsoIndexuint256Index of the removed FTSO.
+
+
+
+

removeTrustedAddressFromWhitelist#

+
+

Defined in IIVoterWhitelister (Docs, Source).

+
+
+
function removeTrustedAddressFromWhitelist(
+    address _trustedAddress,
+    uint256 _ftsoIndex
+) external;
+
+

Remove a trusted address from whitelist.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_trustedAddressaddressAddress to remove.
_ftsoIndexuint256Index of the FTSO being modified.
+
+
+
+

requestFullVoterWhitelisting#

+
+

Defined in IVoterWhitelister (Docs, Source).

+
+
+
function requestFullVoterWhitelisting(
+    address _voter
+) external returns (
+    uint256[] _supportedIndices,
+    bool[] _success);
+
+

Requests whitelisting an account to act as a data provider for all active FTSOs. +May be called by any address, including the voter itself.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_voteraddressAddress of the voter to be whitelisted.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_supportedIndicesuint256[]Array of currently supported FTSO indices.
_successbool[]Array of success flags by FTSO index.
+
+
+
+

requestWhitelistingVoter#

+
+

Defined in IVoterWhitelister (Docs, Source).

+
+
+
function requestWhitelistingVoter(
+    address _voter,
+    uint256 _ftsoIndex
+) external;
+
+

Requests whitelisting an account to act as a data provider for a specific FTSO. +Reverts if the vote power of the account is too low. +May be called by any address, including the voter itself.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_voteraddressAddress of the voter to be whitelisted.
_ftsoIndexuint256Index of the FTSO.
+
+
+
+

setDefaultMaxVotersForFtso#

+
+

Defined in IIVoterWhitelister (Docs, Source).

+
+
+
function setDefaultMaxVotersForFtso(
+    uint256 _defaultMaxVotersForFtso
+) external;
+
+

Set the maximum number of voters in the whitelist for a new FTSOs.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_defaultMaxVotersForFtsouint256New maximum default value.
+
+
+
+

setMaxVotersForFtso#

+
+

Defined in IIVoterWhitelister (Docs, Source).

+
+
+
function setMaxVotersForFtso(
+    uint256 _ftsoIndex,
+    uint256 _newMaxVoters
+) external;
+
+

Set the maximum number of voters in the whitelist for a specific FTSO. +Can remove voters with the least votepower from the whitelist.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsoIndexuint256Index of the FTSO to modify.
_newMaxVotersuint256New size of the whitelist.
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IInflationGenesis/index.html b/apis/smart-contracts/IInflationGenesis/index.html new file mode 100644 index 000000000..6e3707499 --- /dev/null +++ b/apis/smart-contracts/IInflationGenesis/index.html @@ -0,0 +1,3922 @@ + + + + + + + + + + + + + + + + + + IInflationGenesis - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

IInflationGenesis#

+
+

Source

+
+
+

Portion of the Inflation contract that is available to contracts deployed at genesis.

+
+
+

Functions#

+
+

receiveMinting#

+
+

Defined in IInflationGenesis (Docs, Source).

+
+
+
function receiveMinting(
+) external payable;
+
+

Receive newly minted native tokens from the FlareDaemon.

+

Assume that the received amount will be >= last topup requested across all services. +If there is not enough balance sent to cover the topup request, expect the library method to revert. +Also assume that any received balance greater than the calculated topup request +came from self-destructor sending a balance to this contract.

+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IPriceSubmitter/index.html b/apis/smart-contracts/IPriceSubmitter/index.html new file mode 100644 index 000000000..bede8d8e5 --- /dev/null +++ b/apis/smart-contracts/IPriceSubmitter/index.html @@ -0,0 +1,4419 @@ + + + + + + + + + + + + + + + + + + IPriceSubmitter - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

IPriceSubmitter#

+
+

Source

+
+
+

Interface for the PriceSubmitter contract.

+

This is the contract used by all FTSO data providers +to submit their data.

+
+
+

Events#

+
+

HashSubmitted#

+
+

Defined in IPriceSubmitter (Docs, Source).

+
+
+
event HashSubmitted(
+    address submitter,
+    uint256 epochId,
+    bytes32 hash,
+    uint256 timestamp
+)
+
+

Emitted when a hash is submitted through submitHash.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
submitteraddressAddress of the submitting data provider.
epochIduint256Current price epoch ID.
hashbytes32Submitted hash.
timestampuint256Current block timestamp.
+
+
+
+

PricesRevealed#

+
+

Defined in IPriceSubmitter (Docs, Source).

+
+
+
event PricesRevealed(
+    address voter,
+    uint256 epochId,
+    contract IFtsoGenesis[] ftsos,
+    uint256[] prices,
+    uint256 random,
+    uint256 timestamp
+)
+
+

Emitted when prices are revealed through revealPrice.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
voteraddressAddress of the revealing data provider.
epochIduint256ID of the epoch in which the price hash is revealed.
ftsoscontract IFtsoGenesis[]Array of FTSOs that correspond to the indexes in the call.
pricesuint256[]List of revealed prices.
randomuint256Revealed random number.
timestampuint256Current block timestamp.
+
+
+
+
+

Functions#

+
+

getCurrentRandom#

+
+

Defined in IPriceSubmitter (Docs, Source).

+
+
+
function getCurrentRandom(
+) external view returns (
+    uint256);
+
+

Returns the random number for the previous epoch, obtained from the random numbers +provided by all data providers along with their data submissions. +Note that the random number for the previous epoch keeps updating as new submissions are revealed.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Random number calculated from all data provider's submissions.
+
+
+
+

getFtsoManager#

+
+

Defined in IPriceSubmitter (Docs, Source).

+
+
+
function getFtsoManager(
+) external view returns (
+    contract IFtsoManagerGenesis);
+
+

Returns the address of the FtsoManager contract.

+
+
+
+

getFtsoRegistry#

+
+

Defined in IPriceSubmitter (Docs, Source).

+
+
+
function getFtsoRegistry(
+) external view returns (
+    contract IFtsoRegistryGenesis);
+
+

Returns the address of the FtsoRegistry contract.

+
+
+
+

getRandom#

+
+

Defined in IPriceSubmitter (Docs, Source).

+
+
+
function getRandom(
+    uint256 _epochId
+) external view returns (
+    uint256);
+
+

Returns the random number used in a specific past epoch, obtained from the random numbers +provided by all data providers along with their data submissions.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_epochIduint256ID of the queried epoch. Current epoch cannot be queried, and the previous epoch is constantly updated as data providers reveal their prices and random numbers. Note that only the last 50 epochs can be queried and there is no bounds checking for this parameter. Out-of-bounds queries return undefined values.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The random number used in that epoch.
+
+
+
+

getVoterWhitelister#

+
+

Defined in IPriceSubmitter (Docs, Source).

+
+
+
function getVoterWhitelister(
+) external view returns (
+    address);
+
+

Returns the address of the VoterWhitelister contract managing the data provider whitelist.

+
+
+
+

revealPrices#

+
+

Defined in IPriceSubmitter (Docs, Source).

+
+
+
function revealPrices(
+    uint256 _epochId,
+    uint256[] _ftsoIndices,
+    uint256[] _prices,
+    uint256 _random
+) external;
+
+

Reveals submitted prices during the epoch reveal period. +The hash of FTSO indices, prices, random number, and voter address must be equal +to the hash previously submitted with submitHash. +Emits a PricesRevealed event.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_epochIduint256ID of the epoch to which the price hashes are submitted.
_ftsoIndicesuint256[]List of FTSO indices in ascending order.
_pricesuint256[]List of submitted prices in USD.
_randomuint256Submitted random number.
+
+
+
+

submitHash#

+
+

Defined in IPriceSubmitter (Docs, Source).

+
+
+
function submitHash(
+    uint256 _epochId,
+    bytes32 _hash
+) external;
+
+

Submits a hash for the current epoch. Can only be called by FTSO data providers +whitelisted through the VoterWhitelisted contract. +Emits the HashSubmitted event.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_epochIduint256ID of the target epoch to which the hash is submitted.
_hashbytes32A hash of the FTSO indices, prices, random number, and voter address.
+
+
+
+

voterWhitelistBitmap#

+
+

Defined in IPriceSubmitter (Docs, Source).

+
+
+
function voterWhitelistBitmap(
+    address _voter
+) external view returns (
+    uint256);
+
+

Returns a bitmap of all FTSOs for which a data provider is allowed to submit prices or hashes.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_voteraddressAddress of the voter.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256If a data provider is allowed to vote for a given FTSO index, the corresponding bit in the result is 1.
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IVPContractEvents/index.html b/apis/smart-contracts/IVPContractEvents/index.html new file mode 100644 index 000000000..9420a1048 --- /dev/null +++ b/apis/smart-contracts/IVPContractEvents/index.html @@ -0,0 +1,4018 @@ + + + + + + + + + + + + + + + + + + IVPContractEvents - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

IVPContractEvents#

+
+

Source

+
+
+

Events interface for vote-power related operations.

+
+
+

Events#

+
+

Delegate#

+
+

Defined in IVPContractEvents (Docs, Source).

+
+
+
event Delegate(
+    address from,
+    address to,
+    uint256 priorVotePower,
+    uint256 newVotePower
+)
+
+

Emitted when the amount of vote power delegated from one account to another changes.

+

Note: This event is always emitted from VPToken's writeVotePowerContract.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
fromaddressThe account that has changed the amount of vote power it is delegating.
toaddressThe account whose received vote power has changed.
priorVotePoweruint256The vote power originally delegated.
newVotePoweruint256The new vote power that triggered this event. It can be 0 if the delegation is completely canceled.
+
+
+
+

Revoke#

+
+

Defined in IVPContractEvents (Docs, Source).

+
+
+
event Revoke(
+    address delegator,
+    address delegatee,
+    uint256 votePower,
+    uint256 blockNumber
+)
+
+

Emitted when an account revokes its vote power delegation to another account +for a single current or past block (typically the current vote block).

+

Note: This event is always emitted from VPToken's writeVotePowerContract or readVotePowerContract.

+

See revokeDelegationAt in IVPToken.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
delegatoraddressThe account that revoked the delegation.
delegateeaddressThe account that has been revoked.
votePoweruint256The revoked vote power.
blockNumberuint256The block number at which the delegation has been revoked.
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IVPToken/index.html b/apis/smart-contracts/IVPToken/index.html new file mode 100644 index 000000000..deaab331a --- /dev/null +++ b/apis/smart-contracts/IVPToken/index.html @@ -0,0 +1,5476 @@ + + + + + + + + + + + + + + + + + + IVPToken - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + +

IVPToken#

+
+

Source | Inherits from IERC20

+
+
+

Vote power token interface.

+
+
+

Functions#

+
+

allowance#

+
+

Defined in IERC20 (Source).

+
+
+
function allowance(
+    address owner,
+    address spender
+) external view returns (
+    uint256);
+
+

Returns the remaining number of tokens that spender will be +allowed to spend on behalf of owner through transferFrom. This is +zero by default.

+

This value changes when approve or transferFrom are called.

+
+
+
+

approve#

+
+

Defined in IERC20 (Source).

+
+
+
function approve(
+    address spender,
+    uint256 amount
+) external returns (
+    bool);
+
+

Sets amount as the allowance of spender over the caller's tokens.

+

Returns a boolean value indicating whether the operation succeeded.

+

IMPORTANT: Beware that changing an allowance with this method brings the risk +that someone may use both the old and the new allowance by unfortunate +transaction ordering. One possible solution to mitigate this race +condition is to first reduce the spender's allowance to 0 and set the +desired value afterwards: +https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729

+

Emits an Approval event.

+
+
+
+

balanceOf#

+
+

Defined in IERC20 (Source).

+
+
+
function balanceOf(
+    address account
+) external view returns (
+    uint256);
+
+

Returns the amount of tokens owned by account.

+
+
+
+

balanceOfAt#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function balanceOfAt(
+    address _owner,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Queries the token balance of _owner at a specific _blockNumber.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address from which the balance will be retrieved.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The balance at _blockNumber.
+
+
+
+

batchDelegate#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function batchDelegate(
+    address[] _delegatees,
+    uint256[] _bips
+) external;
+
+

Undelegate all percentage delegations from the sender and then delegate corresponding + _bips percentage of voting power from the sender to each member of the _delegatees array.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_delegateesaddress[]The addresses of the new recipients.
_bipsuint256[]The percentages of voting power to be delegated expressed in basis points (1/100 of one percent). The sum of all _bips values must be at most 10000 (100%).
+
+
+
+

decimals#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function decimals(
+) external view returns (
+    uint8);
+
+

Returns the number of decimals used to get its user representation. +For example, if decimals equals 2, a balance of 505 tokens should +be displayed to a user as 5.05 (505 / 102).

+

Tokens usually opt for a value of 18, imitating the relationship between +Ether and wei. This is the default value returned by this function, unless +it's overridden.

+

NOTE: This information is only used for display purposes: it in +no way affects any of the arithmetic of the contract, including +balanceOf and transfer.

+

Should be compatible with ERC20 method.

+
+
+
+

delegate#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function delegate(
+    address _to,
+    uint256 _bips
+) external;
+
+

Delegate voting power to account _to from msg.sender, by percentage.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_toaddressThe address of the recipient.
_bipsuint256The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: every call resets the delegation value (and a value of 0 revokes all previous delegations).
+
+
+
+

delegateExplicit#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function delegateExplicit(
+    address _to,
+    uint256 _amount
+) external;
+
+

Explicitly delegate _amount voting power to account _to from msg.sender. +Compare with delegate which delegates by percentage.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_toaddressThe address of the recipient.
_amountuint256An explicit vote power amount to be delegated. Not cumulative: every call resets the delegation value (and a value of 0 revokes all previous delegations).
+
+
+
+

delegatesOf#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function delegatesOf(
+    address _who
+) external view returns (
+    address[] _delegateAddresses,
+    uint256[] _bips,
+    uint256 _count,
+    uint256 _delegationMode);
+
+

Get the list of addresses to which _who is delegating, and their percentages.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address to query.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_delegateAddressesaddress[]Positional array of addresses being delegated to.
_bipsuint256[]Positional array of delegation percents specified in basis points (1/100 of 1 percent). Each one matches the address in the same position in the _delegateAddresses array.
_countuint256The number of delegates.
_delegationModeuint256Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).
+
+
+
+

delegatesOfAt#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function delegatesOfAt(
+    address _who,
+    uint256 _blockNumber
+) external view returns (
+    address[] _delegateAddresses,
+    uint256[] _bips,
+    uint256 _count,
+    uint256 _delegationMode);
+
+

Get the list of addresses to which _who is delegating, and their percentages, at the given block.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address to query.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_delegateAddressesaddress[]Positional array of addresses being delegated to.
_bipsuint256[]Positional array of delegation percents specified in basis points (1/100 of 1 percent). Each one matches the address in the same position in the _delegateAddresses array.
_countuint256The number of delegates.
_delegationModeuint256Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).
+
+
+
+

delegationModeOf#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function delegationModeOf(
+    address _who
+) external view returns (
+    uint256);
+
+

Get the delegation mode for account '_who'. This mode determines whether vote power is +allocated by percentage or by explicit amount. Once the delegation mode is set, +it can never be changed, even if all delegations are removed.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address to get delegation mode.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).
+
+
+
+

governanceVotePower#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function governanceVotePower(
+) external view returns (
+    contract IGovernanceVotePower);
+
+

When set, allows token owners to participate in governance voting +and delegating governance vote power.

+
+
+
+

name#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function name(
+) external view returns (
+    string);
+
+

Returns the name of the token.

+

Should be compatible with ERC20 method.

+
+
+
+

readVotePowerContract#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function readVotePowerContract(
+) external view returns (
+    contract IVPContractEvents);
+
+

Returns VPContract event interface used for read-only operations (view methods). +The only non-view method that might be called on it is revokeDelegationAt.

+

readVotePowerContract is almost always equal to writeVotePowerContract +except during an upgrade from one VPContract to a new version (which should happen +rarely or never and will be announced beforehand).

+

Do not call any methods on VPContract directly. +State changing methods are forbidden from direct calls. +All methods are exposed via VPToken. +This is the reason that this method returns IVPContractEvents. +Use it only for listening to events and revoking.

+
+
+
+

revokeDelegationAt#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function revokeDelegationAt(
+    address _who,
+    uint256 _blockNumber
+) external;
+
+

Revoke all delegation from sender to _who at given block. +Only affects the reads via votePowerOfAtCached() in the block _blockNumber. +Block _blockNumber must be in the past. +This method should be used only to prevent rogue delegate voting in the current voting block. +To stop delegating use delegate / delegateExplicit with value of 0 or undelegateAll / undelegateAllExplicit.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressAddress of the delegatee.
_blockNumberuint256The block number at which to revoke delegation..
+
+
+
+

symbol#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function symbol(
+) external view returns (
+    string);
+
+

Returns the symbol of the token, usually a shorter version of the name.

+

Should be compatible with ERC20 method.

+
+
+
+

totalSupply#

+
+

Defined in IERC20 (Source).

+
+
+
function totalSupply(
+) external view returns (
+    uint256);
+
+

Returns the amount of tokens in existence.

+
+
+
+

totalSupplyAt#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function totalSupplyAt(
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Total amount of tokens held by all accounts at a specific block number.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The total amount of tokens at _blockNumber.
+
+
+
+

totalVotePower#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function totalVotePower(
+) external view returns (
+    uint256);
+
+

Get the current total vote power.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The current total vote power (sum of all accounts' vote power).
+
+
+
+

totalVotePowerAt#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function totalVotePowerAt(
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Get the total vote power at block _blockNumber.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The total vote power at the queried block (sum of all accounts' vote powers).
+
+
+
+

transfer#

+
+

Defined in IERC20 (Source).

+
+
+
function transfer(
+    address recipient,
+    uint256 amount
+) external returns (
+    bool);
+
+

Moves amount tokens from the caller's account to recipient.

+

Returns a boolean value indicating whether the operation succeeded.

+

Emits a Transfer event.

+
+
+
+

transferFrom#

+
+

Defined in IERC20 (Source).

+
+
+
function transferFrom(
+    address sender,
+    address recipient,
+    uint256 amount
+) external returns (
+    bool);
+
+

Moves amount tokens from sender to recipient using the +allowance mechanism. amount is then deducted from the caller's +allowance.

+

Returns a boolean value indicating whether the operation succeeded.

+

Emits a Transfer event.

+
+
+
+

undelegateAll#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function undelegateAll(
+) external;
+
+

Undelegate all voting power of msg.sender. This effectively revokes all previous delegations. +Can only be used with percentage delegation. +Does not reset delegation mode back to NOT SET.

+
+
+
+

undelegateAllExplicit#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function undelegateAllExplicit(
+    address[] _delegateAddresses
+) external returns (
+    uint256);
+
+

Undelegate all explicit vote power by amount of msg.sender. +Can only be used with explicit delegation. +Does not reset delegation mode back to NOT SET.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_delegateAddressesaddress[]Explicit delegation does not store delegatees' addresses, so the caller must supply them.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The amount still delegated (in case the list of delegates was incomplete).
+
+
+
+

undelegatedVotePowerOf#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function undelegatedVotePowerOf(
+    address _owner
+) external view returns (
+    uint256);
+
+

Compute the current undelegated vote power of the _owner account.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The unallocated vote power of _owner.
+
+
+
+

undelegatedVotePowerOfAt#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function undelegatedVotePowerOfAt(
+    address _owner,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Get the undelegated vote power of the _owner account at a given block number.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address to query.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The unallocated vote power of _owner.
+
+
+
+

votePowerFromTo#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function votePowerFromTo(
+    address _from,
+    address _to
+) external view returns (
+    uint256);
+
+

Get current delegated vote power from delegator _from to delegatee _to.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressAddress of delegator.
_toaddressAddress of delegatee.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256votePower The delegated vote power.
+
+
+
+

votePowerFromToAt#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function votePowerFromToAt(
+    address _from,
+    address _to,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Get delegated vote power from delegator _from to delegatee _to at _blockNumber.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressAddress of delegator.
_toaddressAddress of delegatee.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The delegated vote power.
+
+
+
+

votePowerOf#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function votePowerOf(
+    address _owner
+) external view returns (
+    uint256);
+
+

Get the current vote power of _owner.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Current vote power of _owner.
+
+
+
+

votePowerOfAt#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function votePowerOfAt(
+    address _owner,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Get the vote power of _owner at block _blockNumber

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address to query.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Vote power of _owner at block number _blockNumber.
+
+
+
+

votePowerOfAtIgnoringRevocation#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function votePowerOfAtIgnoringRevocation(
+    address _owner,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Get the vote power of _owner at block _blockNumber, ignoring revocation information (and cache).

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address to query.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Vote power of _owner at block number _blockNumber. Result doesn't change if vote power is revoked.
+
+
+
+

writeVotePowerContract#

+
+

Defined in IVPToken (Docs, Source).

+
+
+
function writeVotePowerContract(
+) external view returns (
+    contract IVPContractEvents);
+
+

Returns VPContract event interface used for state-changing operations (non-view methods). +The only non-view method that might be called on it is revokeDelegationAt.

+

writeVotePowerContract is almost always equal to readVotePowerContract, +except during upgrade from one VPContract to a new version (which should happen +rarely or never and will be announced beforehand). +In the case of an upgrade, writeVotePowerContract is replaced first to establish delegations. +After some period (e.g., after a reward epoch ends), readVotePowerContract is set equal to it.

+

Do not call any methods on VPContract directly. +State changing methods are forbidden from direct calls. +All are exposed via VPToken. +This is the reason that this method returns IVPContractEvents +Use it only for listening to events, delegating, and revoking.

+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IVoterWhitelister/index.html b/apis/smart-contracts/IVoterWhitelister/index.html new file mode 100644 index 000000000..acb1292fa --- /dev/null +++ b/apis/smart-contracts/IVoterWhitelister/index.html @@ -0,0 +1,4472 @@ + + + + + + + + + + + + + + + + + + IVoterWhitelister - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + +

IVoterWhitelister#

+
+

Source

+
+
+

Interface for managers of the FTSO whitelist.

+

Only addresses registered in this contract can submit data to the FTSO system.

+
+
+

Events#

+
+

VoterChilled#

+
+

Defined in IVoterWhitelister (Docs, Source).

+
+
+
event VoterChilled(
+    address voter,
+    uint256 untilRewardEpoch
+)
+
+

Emitted when an account is chilled from the voter whitelist.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
voteraddressAddress of the chilled account.
untilRewardEpochuint256Epoch ID when the chill will be lifted.
+
+
+
+

VoterRemovedFromWhitelist#

+
+

Defined in IVoterWhitelister (Docs, Source).

+
+
+
event VoterRemovedFromWhitelist(
+    address voter,
+    uint256 ftsoIndex
+)
+
+

Emitted when an account is removed from the voter whitelist.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
voteraddressAddress of the removed account.
ftsoIndexuint256Index of the FTSO in which it was registered.
+
+
+
+

VoterWhitelisted#

+
+

Defined in IVoterWhitelister (Docs, Source).

+
+
+
event VoterWhitelisted(
+    address voter,
+    uint256 ftsoIndex
+)
+
+

Emitted when an account is added to the voter whitelist.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
voteraddressAddress of the added account.
ftsoIndexuint256Index of the FTSO to which it has been registered.
+
+
+
+
+

Functions#

+
+

chilledUntilRewardEpoch#

+
+

Defined in IVoterWhitelister (Docs, Source).

+
+
+
function chilledUntilRewardEpoch(
+    address _voter
+) external view returns (
+    uint256);
+
+

In case of providing bad prices (e.g. collusion), the voter can be chilled for a few reward epochs. +A voter can whitelist again from a returned reward epoch onwards.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_voteraddressAddress of the queried data provider.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256uint256 ID of the epoch where the data provider can start submitting prices again.
+
+
+
+

defaultMaxVotersForFtso#

+
+

Defined in IVoterWhitelister (Docs, Source).

+
+
+
function defaultMaxVotersForFtso(
+) external view returns (
+    uint256);
+
+

Maximum number of voters in the whitelist for a new FTSO.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256uint256 Default maximum allowed voters.
+
+
+
+

getFtsoWhitelistedPriceProviders#

+
+

Defined in IVoterWhitelister (Docs, Source).

+
+
+
function getFtsoWhitelistedPriceProviders(
+    uint256 _ftsoIndex
+) external view returns (
+    address[]);
+
+

Gets whitelisted price providers for the FTSO at a given index.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsoIndexuint256Queried index.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]address[]Array of addresses of the whitelisted data providers.
+
+
+
+

getFtsoWhitelistedPriceProvidersBySymbol#

+
+

Defined in IVoterWhitelister (Docs, Source).

+
+
+
function getFtsoWhitelistedPriceProvidersBySymbol(
+    string _symbol
+) external view returns (
+    address[]);
+
+

Gets whitelisted price providers for the FTSO with a specified symbol.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_symbolstringQueried symbol.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]address[]Array of addresses of the whitelisted data providers.
+
+
+
+

maxVotersForFtso#

+
+

Defined in IVoterWhitelister (Docs, Source).

+
+
+
function maxVotersForFtso(
+    uint256 _ftsoIndex
+) external view returns (
+    uint256);
+
+

Maximum number of voters in the whitelist for a specific FTSO. +Adjustable separately for each index.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsoIndexuint256Index of the FTSO.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256uint256 Maximum allowed voters.
+
+
+
+

requestFullVoterWhitelisting#

+
+

Defined in IVoterWhitelister (Docs, Source).

+
+
+
function requestFullVoterWhitelisting(
+    address _voter
+) external returns (
+    uint256[] _supportedIndices,
+    bool[] _success);
+
+

Requests whitelisting an account to act as a data provider for all active FTSOs. +May be called by any address, including the voter itself.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_voteraddressAddress of the voter to be whitelisted.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_supportedIndicesuint256[]Array of currently supported FTSO indices.
_successbool[]Array of success flags by FTSO index.
+
+
+
+

requestWhitelistingVoter#

+
+

Defined in IVoterWhitelister (Docs, Source).

+
+
+
function requestWhitelistingVoter(
+    address _voter,
+    uint256 _ftsoIndex
+) external;
+
+

Requests whitelisting an account to act as a data provider for a specific FTSO. +Reverts if the vote power of the account is too low. +May be called by any address, including the voter itself.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_voteraddressAddress of the voter to be whitelisted.
_ftsoIndexuint256Index of the FTSO.
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/IWNat/index.html b/apis/smart-contracts/IWNat/index.html new file mode 100644 index 000000000..61b30088d --- /dev/null +++ b/apis/smart-contracts/IWNat/index.html @@ -0,0 +1,4072 @@ + + + + + + + + + + + + + + + + + + IWNat - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

IWNat#

+
+

Source

+
+
+

Wrapped native token interface.

+

This contract converts native tokens into WNAT (wrapped native) tokens and vice versa. +WNAT tokens are a one-to-one ERC20 +representation of native tokens, which are minted and burned as needed by this contract.

+

The wrapped versions of the native FLR and SGB tokens are called WFLR and WSGB respectively.

+

Code attribution: WETH9.

+
+
+

Functions#

+
+

deposit#

+
+

Defined in IWNat (Docs, Source).

+
+
+
function deposit(
+) external payable;
+
+

Deposits native tokens and mints the same amount of WNAT tokens, +which are added to the msg.sender's balance. +This operation is commonly known as "wrapping".

+
+
+
+

depositTo#

+
+

Defined in IWNat (Docs, Source).

+
+
+
function depositTo(
+    address _recipient
+) external payable;
+
+

Deposits native tokens and mints the same amount of WNAT tokens, +which are added to _recipient's balance. +This operation is commonly known as "wrapping".

+

This is equivalent to using deposit followed by transfer.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_recipientaddressThe address to receive the minted WNAT.
+
+
+
+

withdraw#

+
+

Defined in IWNat (Docs, Source).

+
+
+
function withdraw(
+    uint256 _amount
+) external;
+
+

Burns _amount of WNAT tokens from msg.sender's WNAT balance and +transfers the same amount of native tokens to msg.sender. +This operation is commonly known as "unwrapping".

+

Reverts if _amount is higher than msg.sender's WNAT balance.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_amountuint256The amount to withdraw.
+
+
+
+

withdrawFrom#

+
+

Defined in IWNat (Docs, Source).

+
+
+
function withdrawFrom(
+    address _owner,
+    uint256 _amount
+) external;
+
+

Burns _amount of WNAT tokens from _owner's WNAT balance and +transfers the same amount of native tokens to msg.sender. +This operation is commonly known as "unwrapping".

+

msg.sender must have been authorized to withdraw from _owner's account +through ERC-20's approve mechanism.

+

Reverts if _amount is higher than _owners's WNAT balance or than +msg.sender's allowance over _owner's tokens.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address containing the tokens to withdraw.
_amountuint256The amount to withdraw.
+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/Inflation/index.html b/apis/smart-contracts/Inflation/index.html new file mode 100644 index 000000000..bad17ffc4 --- /dev/null +++ b/apis/smart-contracts/Inflation/index.html @@ -0,0 +1,5716 @@ + + + + + + + + + + + + + + + + + + Inflation - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

Inflation#

+ +
+

Recognizes, authorizes, mints, and funds native tokens to Flare services that are rewardable through inflation.

+

See the technical specification.

+
+
+

Events#

+
+

GovernanceCallTimelocked#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event GovernanceCallTimelocked(
+    bytes4 selector,
+    uint256 allowedAfterTimestamp,
+    bytes encodedCall
+)
+
+

Emitted when a new governance call has been recorded and is now waiting for the time lock to expire.

+
+
+
+

GovernanceInitialised#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event GovernanceInitialised(
+    address initialGovernance
+)
+
+

Emitted when the governance address is initialized. +This address will be used until production mode is entered (see GovernedProductionModeEntered). +At that point the governance address is taken from GovernanceSettings.

+
+
+
+

GovernedProductionModeEntered#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event GovernedProductionModeEntered(
+    address governanceSettings
+)
+
+

Emitted when governance is enabled and the governance address cannot be changed anymore +(only through a network fork).

+
+
+
+

InflationAllocationSet#

+
+

Defined in Inflation (Docs, Source).

+
+
+
event InflationAllocationSet(
+    contract IIInflationAllocation inflationAllocation
+)
+
+
+
+
+

InflationAuthorized#

+
+

Defined in Inflation (Docs, Source).

+
+
+
event InflationAuthorized(
+    uint256 amountWei
+)
+
+
+
+
+

InflationRewardServiceDailyAuthorizedInflationComputed#

+
+

Defined in Inflation (Docs, Source).

+
+
+
event InflationRewardServiceDailyAuthorizedInflationComputed(
+    contract IIInflationReceiver inflationReceiver,
+    uint256 amountWei
+)
+
+
+
+
+

InflationRewardServiceTopupComputed#

+
+

Defined in Inflation (Docs, Source).

+
+
+
event InflationRewardServiceTopupComputed(
+    contract IIInflationReceiver inflationReceiver,
+    uint256 amountWei
+)
+
+
+
+
+

InflationRewardServiceTopupRequestReceived#

+
+

Defined in Inflation (Docs, Source).

+
+
+
event InflationRewardServiceTopupRequestReceived(
+    contract IIInflationReceiver inflationReceiver,
+    uint256 amountWei
+)
+
+
+
+
+

MintingReceived#

+
+

Defined in Inflation (Docs, Source).

+
+
+
event MintingReceived(
+    uint256 amountWei,
+    uint256 selfDestructAmountWei
+)
+
+
+
+
+

NewTimeSlotInitialized#

+
+

Defined in Inflation (Docs, Source).

+
+
+
event NewTimeSlotInitialized(
+    uint256 startTimeStamp,
+    uint256 endTimeStamp,
+    uint256 inflatableSupplyWei,
+    uint256 recognizedInflationWei
+)
+
+
+
+
+

SupplySet#

+
+

Defined in Inflation (Docs, Source).

+
+
+
event SupplySet(
+    contract IISupply oldSupply,
+    contract IISupply newSupply
+)
+
+
+
+
+

TimelockedGovernanceCallCanceled#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event TimelockedGovernanceCallCanceled(
+    bytes4 selector,
+    uint256 timestamp
+)
+
+

Emitted when a timelocked governance call is canceled before execution.

+
+
+
+

TimelockedGovernanceCallExecuted#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event TimelockedGovernanceCallExecuted(
+    bytes4 selector,
+    uint256 timestamp
+)
+
+

Emitted when a timelocked governance call is executed.

+
+
+
+

TopupConfigurationSet#

+
+

Defined in Inflation (Docs, Source).

+
+
+
event TopupConfigurationSet(
+    struct TopupConfiguration topupConfiguration
+)
+
+
+
+
+

TopupRequested#

+
+

Defined in Inflation (Docs, Source).

+
+
+
event TopupRequested(
+    uint256 requestAmountWei,
+    uint256 reRequestAmountWei
+)
+
+
+
+
+
+

Functions#

+
+

cancelGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function cancelGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Cancel a timelocked governance call before it has been executed.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector.
+
+
+
+

constructor#

+
+

Defined in Inflation (Docs, Source).

+
+
+
constructor(
+    address _governance,
+    contract FlareDaemon _flareDaemon,
+    address _addressUpdater,
+    uint256 _rewardEpochStartTs
+) public;
+
+
+
+
+

constructor#

+
+

Defined in GovernedAndFlareDaemonized (Docs, Source).

+
+
+
constructor(
+    address _governance,
+    contract FlareDaemon _flareDaemon
+) public;
+
+
+
+
+

constructor#

+
+

Defined in Governed (Docs, Source).

+
+
+
constructor(
+    address _governance
+) public;
+
+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_governanceaddressGovernance contract. Must not be zero.
+
+
+
+

daemonize#

+
+

Defined in IFlareDaemonize (Docs, Source).

+
+
+
function daemonize(
+) external returns (
+    bool);
+
+

Implement this function to receive a trigger from the FlareDaemon. +The trigger method is called by the validator right at the end of block state transition.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]boolbool Whether the contract is still active after the call. Currently unused.
+
+
+
+

executeGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function executeGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Execute the timelocked governance calls once the timelock period expires.

+

Only executor can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector (only one timelocked call per method is stored).
+
+
+
+

getAddressUpdater#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
function getAddressUpdater(
+) public view returns (
+    address _addressUpdater);
+
+

Returns the configured address updater.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_addressUpdateraddressThe AddresUpdater contract that can update our contract address list, as a response to a governance call.
+
+
+
+

getContractName#

+
+

Defined in Inflation (Docs, Source).

+
+
+
function getContractName(
+) external pure returns (
+    string);
+
+

Implement this function to allow updating daemonized contracts through the AddressUpdater.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]stringstring Contract name.
+
+
+
+

getCurrentTimeSlot#

+
+

Defined in Inflation (Docs, Source).

+
+
+
function getCurrentTimeSlot(
+) external view returns (
+    struct InflationTimeSlots.InflationTimeSlot);
+
+

Return the current time slot.

+

Expect library to revert if there is no current time slot.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]struct InflationTimeSlots.InflationTimeSlotThe inflation time slot state of the current time slot.
+
+
+
+

getCurrentTimeSlotId#

+
+

Defined in Inflation (Docs, Source).

+
+
+
function getCurrentTimeSlotId(
+) external view returns (
+    uint256);
+
+

Return current time slot id.

+

Expect library to revert if there is no current time slot.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Id of the current time slot.
+
+
+
+

getNextExpectedTopupTs#

+
+

Defined in Inflation (Docs, Source).

+
+
+
function getNextExpectedTopupTs(
+) external view returns (
+    uint256 _nextTopupTs);
+
+

Returns next expected inflation topup time stamp which is also inflation authorization time. +The returned time from this API is actually the time of the block in which the topup is requested. +The Actual topup will take place in the next block. +Expected diff is up to a few seconds (max is less then a minute).

+
+
+
+

getRewardServices#

+
+

Defined in Inflation (Docs, Source).

+
+
+
function getRewardServices(
+) external view returns (
+    struct InflationRewardServices.RewardService[]);
+
+

Return the structure of reward services.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]struct InflationRewardServices.RewardService[]Reward services structure.
+
+
+
+

getTimeSlot#

+
+

Defined in Inflation (Docs, Source).

+
+
+
function getTimeSlot(
+    uint256 _index
+) external view returns (
+    struct InflationTimeSlots.InflationTimeSlot);
+
+

Given an index, return the time slot at that index.

+

Expect library to revert if index not found.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_indexuint256The index of the time slot to fetch.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]struct InflationTimeSlots.InflationTimeSlotThe inflation time slot state.
+
+
+
+

getTopupConfiguration#

+
+

Defined in Inflation (Docs, Source).

+
+
+
function getTopupConfiguration(
+    contract IIInflationReceiver _inflationReceiver
+) external view returns (
+    struct TopupConfiguration _topupConfiguration);
+
+

Given an inflation receiver, get the topup configuration.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_inflationReceivercontract IIInflationReceiverThe reward service.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_topupConfigurationstruct TopupConfigurationThe configuration of how the topup requests are calculated for a given reward service.
+
+
+
+

getTotals#

+
+

Defined in Inflation (Docs, Source).

+
+
+
function getTotals(
+) external view returns (
+    uint256 _totalAuthorizedInflationWei,
+    uint256 _totalInflationTopupRequestedWei,
+    uint256 _totalInflationTopupDistributedWei,
+    uint256 _totalRecognizedInflationWei);
+
+

Get a tuple of totals across inflation time slots.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_totalAuthorizedInflationWeiuint256Total inflation authorized to be mintable
_totalInflationTopupRequestedWeiuint256Total inflation requested to be topped up for rewarding
_totalInflationTopupDistributedWeiuint256Total inflation received for funding reward services
_totalRecognizedInflationWeiuint256Total inflation recognized for rewarding
+
+
+
+

governance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function governance(
+) public view returns (
+    address);
+
+

Returns the current effective governance address.

+
+
+
+

receiveMinting#

+
+

Defined in Inflation (Docs, Source).

+
+
+
function receiveMinting(
+) external payable;
+
+

Receive newly minted native tokens from the FlareDaemon.

+

Assume that the received amount will be >= last topup requested across all services. +If there is not enough balance sent to cover the topup request, expect the library method to revert. +Also assume that any received balance greater than the calculated topup request +came from self-destructor sending a balance to this contract.

+
+
+
+

setInitialData#

+
+

Defined in Inflation (Docs, Source).

+
+
+
function setInitialData(
+    contract IIInflationV1 _oldInflation,
+    uint256 _noOfAnnums
+) external;
+
+

Used to copy data from old inflation contract.

+

Only governance can call.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_oldInflationcontract IIInflationV1Address of old inflation.
_noOfAnnumsuint256Number of annums in old inflation.
+
+
+
+

setPreInflationCalculation#

+
+

Defined in Inflation (Docs, Source).

+
+
+
function setPreInflationCalculation(
+    contract IIPreInflationCalculation _preInflationCalculation
+) external;
+
+

Set contract that should be triggered before new inflation is calculated (it can be address(0))

+

Only governance can call.

+
+
+
+

setTopupConfiguration#

+
+

Defined in Inflation (Docs, Source).

+
+
+
function setTopupConfiguration(
+    contract IIInflationReceiver _inflationReceiver,
+    enum TopupType _topupType,
+    uint256 _topupFactorX100
+) external;
+
+

Set the topup configuration for a reward service.

+

Only governance can call.

+

Topup factor, if _topupType == FACTOROFDAILYAUTHORIZED, must be greater than 100.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_inflationReceivercontract IIInflationReceiverThe reward service to receive the inflation funds for distribution.
_topupTypeenum TopupTypeThe type to signal how the topup amounts are to be calculated. FACTOROFDAILYAUTHORIZED = Use a factor of last daily authorized to set a target balance for a reward service to maintain as a reserve for claiming. ALLAUTHORIZED = Mint enough native tokens to topup reward service contract to hold all authorized but unrequested rewards.
_topupFactorX100uint256If _topupType == FACTOROFDAILYAUTHORIZED, then this factor (times 100) is multiplied by last daily authorized inflation to obtain the maximum balance that a reward service can hold at any given time. If it holds less, then this max amount is used to compute the mint request topup required to bring the reward service contract native token balance up to that amount.
+
+
+
+

switchToFallbackMode#

+
+

Defined in Inflation (Docs, Source).

+
+
+
function switchToFallbackMode(
+) external view returns (
+    bool);
+
+

This function will be called after an error is caught in daemonize. +It will switch the contract to a simpler fallback mode, which hopefully works when full mode doesn't. +Not every contract needs to support fallback mode (FtsoManager does), so this method may be empty. +Switching back to normal mode is left to the contract (typically a governed method call). +This function may be called due to low-gas error, so it shouldn't use more than ~30.000 gas.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]boolTrue if switched to fallback mode, false if already in fallback mode or if fallback mode is not supported.
+
+
+
+

switchToProductionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function switchToProductionMode(
+) external;
+
+

Enter the production mode after all the initial governance settings have been set. +This enables timelocks and the governance can be obtained afterward by calling +governanceSettings.getGovernanceAddress(). +Emits GovernedProductionModeEntered.

+
+
+
+

updateContractAddresses#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
function updateContractAddresses(
+    bytes32[] _contractNameHashes,
+    address[] _contractAddresses
+) external;
+
+

External method called from AddressUpdater only.

+
+
+
+
+

Modifiers#

+
+

notZero#

+
+

Defined in Inflation (Docs, Source).

+
+
+
modifier notZero(    address _address)
+
+
+
+
+

onlyAddressUpdater#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
modifier onlyAddressUpdater()
+
+

Only the AdressUpdater contract can call this method. +Its address is set at construction time but it can also update itself.

+
+
+
+

onlyFlareDaemon#

+
+

Defined in GovernedAndFlareDaemonized (Docs, Source).

+
+
+
modifier onlyFlareDaemon()
+
+

Only the flareDaemon can call this method.

+
+
+
+

onlyGovernance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
modifier onlyGovernance()
+
+
+
+
+

onlyImmediateGovernance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
modifier onlyImmediateGovernance()
+
+
+
+
+
+

Variables#

+
+

flareDaemon#

+
+

Defined in GovernedAndFlareDaemonized (Docs, Source).

+
+
+
    contract FlareDaemon flareDaemon
+
+

The FlareDaemon contract, set at construction time.

+
+
+
+

governanceSettings#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    contract IGovernanceSettings governanceSettings
+
+

Governance Settings.

+
+
+
+

inflationAllocation#

+
+

Defined in Inflation (Docs, Source).

+
+
+
    contract IIInflationAllocation inflationAllocation
+
+
+
+
+

lastAuthorizationTs#

+
+

Defined in Inflation (Docs, Source).

+
+
+
    uint256 lastAuthorizationTs
+
+

The last time inflation was authorized.

+
+
+
+

preInflationCalculation#

+
+

Defined in Inflation (Docs, Source).

+
+
+
    contract IIPreInflationCalculation preInflationCalculation
+
+
+
+
+

productionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    bool productionMode
+
+

When true, governance is enabled and cannot be disabled. See switchToProductionMode.

+
+
+
+

rewardEpochStartTs#

+
+

Defined in Inflation (Docs, Source).

+
+
+
    uint256 rewardEpochStartTs
+
+

Do not start inflation time slots before this, in seconds after UNIX epoch.

+
+
+
+

rewardEpochStartedTs#

+
+

Defined in Inflation (Docs, Source).

+
+
+
    uint256 rewardEpochStartedTs
+
+

When the first reward epoch was started, in seconds after UNIX epoch.

+
+
+
+

supply#

+
+

Defined in Inflation (Docs, Source).

+
+
+
    contract IISupply supply
+
+
+
+
+

timelockedCalls#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    mapping(bytes4 => struct GovernedBase.TimelockedCall) timelockedCalls
+
+

List of pending timelocked governance calls.

+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/PriceSubmitter/index.html b/apis/smart-contracts/PriceSubmitter/index.html new file mode 100644 index 000000000..6d9b492c8 --- /dev/null +++ b/apis/smart-contracts/PriceSubmitter/index.html @@ -0,0 +1,5083 @@ + + + + + + + + + + + + + + + + + + PriceSubmitter - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + +

PriceSubmitter#

+ +
+

Receives prices from FTSO data providers.

+

It then forwards the submissions to the appropriate FTSO contract, +allowing data providers to perform all required operations in a single transaction +per price epoch.

+
+
+

Functions#

+
+

cancelGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function cancelGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Cancel a timelocked governance call before it has been executed.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector.
+
+
+
+

constructor#

+
+

Defined in PriceSubmitter (Docs, Source).

+
+
+
constructor(
+) public;
+
+

This constructor should contain no code as this contract is pre-loaded into the genesis block. + The super constructors are called for testing convenience.

+
+
+
+

executeGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function executeGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Execute the timelocked governance calls once the timelock period expires.

+

Only executor can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector (only one timelocked call per method is stored).
+
+
+
+

getAddressUpdater#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
function getAddressUpdater(
+) public view returns (
+    address _addressUpdater);
+
+

Returns the configured address updater.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_addressUpdateraddressThe AddresUpdater contract that can update our contract address list, as a response to a governance call.
+
+
+
+

getCurrentRandom#

+
+

Defined in PriceSubmitter (Docs, Source).

+
+
+
function getCurrentRandom(
+) external view returns (
+    uint256);
+
+

Returns the random number for the previous epoch, obtained from the random numbers +provided by all data providers along with their data submissions. +Note that the random number for the previous epoch keeps updating as new submissions are revealed.

+

It never reverts.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Random number calculated from all data provider's submissions.
+
+
+
+

getFtsoManager#

+
+

Defined in PriceSubmitter (Docs, Source).

+
+
+
function getFtsoManager(
+) external view returns (
+    contract IFtsoManagerGenesis);
+
+

Returns the address of the FtsoManager contract.

+
+
+
+

getFtsoRegistry#

+
+

Defined in PriceSubmitter (Docs, Source).

+
+
+
function getFtsoRegistry(
+) external view returns (
+    contract IFtsoRegistryGenesis);
+
+

Returns the address of the FtsoRegistry contract.

+
+
+
+

getRandom#

+
+

Defined in PriceSubmitter (Docs, Source).

+
+
+
function getRandom(
+    uint256 _epochId
+) external view returns (
+    uint256);
+
+

Returns the random number used in a specific past epoch, obtained from the random numbers +provided by all data providers along with their data submissions.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_epochIduint256ID of the queried epoch. Current epoch cannot be queried, and the previous epoch is constantly updated as data providers reveal their prices and random numbers. Note that only the last 50 epochs can be queried and there is no bounds checking for this parameter. Out-of-bounds queries return undefined values.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The random number used in that epoch.
+
+
+
+

getTrustedAddresses#

+
+

Defined in PriceSubmitter (Docs, Source).

+
+
+
function getTrustedAddresses(
+) external view returns (
+    address[]);
+
+

Returns the list of trusted addresses that are always allowed to submit and reveal.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]address[]address[] Array of trusted voter addresses.
+
+
+
+

getVoterWhitelister#

+
+

Defined in PriceSubmitter (Docs, Source).

+
+
+
function getVoterWhitelister(
+) external view returns (
+    address);
+
+

Returns the address of the VoterWhitelister contract managing the data provider whitelist.

+
+
+
+

governance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function governance(
+) public view returns (
+    address);
+
+

Returns the current effective governance address.

+
+
+
+

initialise#

+
+

Defined in GovernedAtGenesis (Docs, Source).

+
+
+
function initialise(
+    address _governance
+) public pure;
+
+

Disallow initialise to be called.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_governanceaddressThe governance address for initial claiming.
+
+
+
+

revealPrices#

+
+

Defined in PriceSubmitter (Docs, Source).

+
+
+
function revealPrices(
+    uint256 _epochId,
+    uint256[] _ftsoIndices,
+    uint256[] _prices,
+    uint256 _random
+) external;
+
+

Reveals submitted prices during the epoch reveal period. +The hash of FTSO indices, prices, random number, and voter address must be equal +to the hash previously submitted with submitHash. +Emits a PricesRevealed event.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_epochIduint256ID of the epoch to which the price hashes are submitted.
_ftsoIndicesuint256[]List of FTSO indices in ascending order.
_pricesuint256[]List of submitted prices in USD.
_randomuint256Submitted random number.
+
+
+
+

setAddressUpdater#

+
+

Defined in PriceSubmitter (Docs, Source).

+
+
+
function setAddressUpdater(
+    address _addressUpdater
+) external;
+
+

Sets the address updater contract. +Only governance cal call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_addressUpdateraddressAddress of the AddressUpdater contract.
+
+
+
+

setTrustedAddresses#

+
+

Defined in PriceSubmitter (Docs, Source).

+
+
+
function setTrustedAddresses(
+    address[] _trustedAddresses
+) external;
+
+

Set the trusted addresses that are always allowed to submit and reveal. +Trusted addresses are used, for example, in fallback mode. +Only FTSO Manager can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_trustedAddressesaddress[]Array of FTSO data provider addresses (voters). The previous list of trusted addresses is discarded.
+
+
+
+

submitHash#

+
+

Defined in PriceSubmitter (Docs, Source).

+
+
+
function submitHash(
+    uint256 _epochId,
+    bytes32 _hash
+) external;
+
+

Submits a hash for the current epoch. Can only be called by FTSO data providers +whitelisted through the VoterWhitelisted contract. +Emits the HashSubmitted event.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_epochIduint256ID of the target epoch to which the hash is submitted.
_hashbytes32A hash of the FTSO indices, prices, random number, and voter address.
+
+
+
+

switchToProductionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function switchToProductionMode(
+) external;
+
+

Enter the production mode after all the initial governance settings have been set. +This enables timelocks and the governance can be obtained afterward by calling +governanceSettings.getGovernanceAddress(). +Emits GovernedProductionModeEntered.

+
+
+
+

updateContractAddresses#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
function updateContractAddresses(
+    bytes32[] _contractNameHashes,
+    address[] _contractAddresses
+) external;
+
+

External method called from AddressUpdater only.

+
+
+
+

voterWhitelistBitmap#

+
+

Defined in PriceSubmitter (Docs, Source).

+
+
+
function voterWhitelistBitmap(
+    address _voter
+) external view returns (
+    uint256);
+
+

Returns a bitmap of all FTSOs for which a data provider is allowed to submit prices or hashes.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_voteraddressAddress of the voter.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256If a data provider is allowed to vote for a given FTSO index, the corresponding bit in the result is 1.
+
+
+
+

voterWhitelisted#

+
+

Defined in PriceSubmitter (Docs, Source).

+
+
+
function voterWhitelisted(
+    address _voter,
+    uint256 _ftsoIndex
+) external;
+
+

Called from the VoterWhitelister contract when a new voter has been whitelisted.

+

Only the VoterWhitelister contract can call this method.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_voteraddressVoter address that has been added to the whitelist.
_ftsoIndexuint256Index of the FTSO to which the voter has registered. Each FTSO has its own whitelist.
+
+
+
+

votersRemovedFromWhitelist#

+
+

Defined in PriceSubmitter (Docs, Source).

+
+
+
function votersRemovedFromWhitelist(
+    address[] _removedVoters,
+    uint256 _ftsoIndex
+) external;
+
+

Called from the VoterWhitelister contract when one or more voters have been removed.

+

Only the VoterWhitelister contract can call this method.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_removedVotersaddress[]
_ftsoIndexuint256Index of the FTSO to which the voters were registered. Each FTSO has its own whitelist.
+
+
+
+
+

Modifiers#

+
+

onlyAddressUpdater#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
modifier onlyAddressUpdater()
+
+

Only the AdressUpdater contract can call this method. +Its address is set at construction time but it can also update itself.

+
+
+
+

onlyFtsoManager#

+
+

Defined in PriceSubmitter (Docs, Source).

+
+
+
modifier onlyFtsoManager()
+
+

Only the ftsoManager can call this method.

+
+
+
+

onlyGovernance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
modifier onlyGovernance()
+
+
+
+
+

onlyImmediateGovernance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
modifier onlyImmediateGovernance()
+
+
+
+
+

onlyWhitelister#

+
+

Defined in PriceSubmitter (Docs, Source).

+
+
+
modifier onlyWhitelister()
+
+

Only the voterWhitelister can call this method.

+
+
+
+
+

Variables#

+
+

MINIMAL_RANDOM#

+
+

Defined in PriceSubmitter (Docs, Source).

+
+
+
    uint256 MINIMAL_RANDOM
+
+

Minimal random value accepted along price submissions. +Submitted random values below this threshold will revert.

+
+
+
+

RANDOM_EPOCH_CYCLIC_BUFFER_SIZE#

+
+

Defined in PriceSubmitter (Docs, Source).

+
+
+
    uint256 RANDOM_EPOCH_CYCLIC_BUFFER_SIZE
+
+

Number of past random numbers remembered.

+
+
+
+

governanceSettings#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    contract IGovernanceSettings governanceSettings
+
+

Governance Settings.

+
+
+
+

productionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    bool productionMode
+
+

When true, governance is enabled and cannot be disabled. See switchToProductionMode.

+
+
+
+

timelockedCalls#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    mapping(bytes4 => struct GovernedBase.TimelockedCall) timelockedCalls
+
+

List of pending timelocked governance calls.

+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/RevertErrorTracking/index.html b/apis/smart-contracts/RevertErrorTracking/index.html new file mode 100644 index 000000000..d0040c6c2 --- /dev/null +++ b/apis/smart-contracts/RevertErrorTracking/index.html @@ -0,0 +1,4272 @@ + + + + + + + + + + + + + + + + + + RevertErrorTracking - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

RevertErrorTracking#

+
+

Source

+
+
+

Revert error tracking contract.

+

A contract to track and store revert errors.

+
+
+

Events#

+
+

ContractRevertError#

+
+

Defined in RevertErrorTracking (Docs, Source).

+
+
+
event ContractRevertError(
+    address theContract,
+    uint256 atBlock,
+    string theMessage
+)
+
+

Emitted when a contract reverts.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
theContractaddressThe culprit's address.
atBlockuint256Block number where the error happened.
theMessagestringReason for the revert, as reported by the contract.
+
+
+
+
+

Functions#

+
+

showLastRevertedError#

+
+

Defined in RevertErrorTracking (Docs, Source).

+
+
+
function showLastRevertedError(
+) external view returns (
+    uint256[] _lastErrorBlock,
+    uint256[] _numErrors,
+    string[] _errorString,
+    address[] _erroringContract,
+    uint256 _totalRevertedErrors);
+
+

Returns latest error information. All arrays will contain only one entry.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_lastErrorBlockuint256[]Array of block numbers where the errors occurred.
_numErrorsuint256[]Array of number of times same error with same contract address has been reverted.
_errorStringstring[]Array of revert error messages.
_erroringContractaddress[]Array of addresses of the reverting contracts.
_totalRevertedErrorsuint256Total number of revert errors across all contracts.
+
+
+
+

showRevertedErrors#

+
+

Defined in RevertErrorTracking (Docs, Source).

+
+
+
function showRevertedErrors(
+    uint256 startIndex,
+    uint256 numErrorTypesToShow
+) public view returns (
+    uint256[] _lastErrorBlock,
+    uint256[] _numErrors,
+    string[] _errorString,
+    address[] _erroringContract,
+    uint256 _totalRevertedErrors);
+
+

Returns latest errors.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
startIndexuint256Starting index in the error list array.
numErrorTypesToShowuint256Number of errors to show. The total amount can be found in errorData.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_lastErrorBlockuint256[]Array of block numbers where the errors occurred.
_numErrorsuint256[]Array of number of times same error with same contract address has been reverted.
_errorStringstring[]Array of revert error messages.
_erroringContractaddress[]Array of addresses of the reverting contracts.
_totalRevertedErrorsuint256Total number of revert errors across all contracts.
+
+
+
+
+

Structures#

+
+

LastErrorData#

+
+

Defined in RevertErrorTracking (Docs, Source).

+
+
+
struct LastErrorData {
+  uint192 totalRevertedErrors;
+  uint64 lastErrorTypeIndex;
+}
+
+
+
+

RevertedError#

+
+

Defined in RevertErrorTracking (Docs, Source).

+
+
+
struct RevertedError {
+  uint192 lastErrorBlock;
+  uint64 numErrors;
+  address fromContract;
+  uint64 errorTypeIndex;
+  string errorMessage;
+}
+
+
+
+
+

Variables#

+
+

errorData#

+
+

Defined in RevertErrorTracking (Docs, Source).

+
+
+
    struct RevertErrorTracking.LastErrorData errorData
+
+

Most recent error information.

+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/VPContract/index.html b/apis/smart-contracts/VPContract/index.html new file mode 100644 index 000000000..fc9fbdc65 --- /dev/null +++ b/apis/smart-contracts/VPContract/index.html @@ -0,0 +1,5956 @@ + + + + + + + + + + + + + + + + + + VPContract - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + +

VPContract#

+
+

Source | Inherits from IIVPContract, Delegatable

+
+
+

Helper contract handling all the vote power and delegation functionality for an associated VPToken.

+
+
+

Functions#

+
+

batchVotePowerOfAt#

+
+

Defined in VPContract (Docs, Source).

+
+
+
function batchVotePowerOfAt(
+    address[] _owners,
+    uint256 _blockNumber
+) external view returns (
+    uint256[] _votePowers);
+
+

Get the vote power of a set of addresses at a given block number.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_ownersaddress[]The list of addresses being queried.
_blockNumberuint256The block number being queried.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_votePowersuint256[]Vote power of each address at _blockNumber, including any delegation received.
+
+
+
+

cleanupBlockNumber#

+
+

Defined in VPContract (Docs, Source).

+
+
+
function cleanupBlockNumber(
+) external view returns (
+    uint256);
+
+

Get the current cleanup block number set with setCleanupBlockNumber.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The currently set cleanup block number.
+
+
+
+

constructor#

+
+

Defined in VPContract (Docs, Source).

+
+
+
constructor(
+    contract IVPToken _ownerToken,
+    bool _isReplacement
+) public;
+
+

Construct VPContract for given VPToken.

+
+
+
+

delegate#

+
+

Defined in VPContract (Docs, Source).

+
+
+
function delegate(
+    address _from,
+    address _to,
+    uint256 _balance,
+    uint256 _bips
+) external;
+
+

Delegate _bips percentage of voting power from a delegator address to a delegatee address.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressThe address of the delegator.
_toaddressThe address of the delegatee.
_balanceuint256The delegator's current balance
_bipsuint256The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: every call resets the delegation value (and a value of 0 revokes delegation).
+
+
+
+

delegateExplicit#

+
+

Defined in VPContract (Docs, Source).

+
+
+
function delegateExplicit(
+    address _from,
+    address _to,
+    uint256 _balance,
+    uint256 _amount
+) external;
+
+

Explicitly delegate _amount tokens of voting power from a delegator address to a delegatee address.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressThe address of the delegator.
_toaddressThe address of the delegatee.
_balanceuint256The delegator's current balance.
_amountuint256An explicit vote power amount to be delegated. Not cumulative: every call resets the delegation value (and a value of 0 undelegates _to).
+
+
+
+

delegatesOf#

+
+

Defined in VPContract (Docs, Source).

+
+
+
function delegatesOf(
+    address _owner
+) external view returns (
+    address[] _delegateAddresses,
+    uint256[] _bips,
+    uint256 _count,
+    uint256 _delegationMode);
+
+

Get the percentages and addresses being delegated to by a vote power delegator.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address of the delegator being queried.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_delegateAddressesaddress[]Array of delegatee addresses.
_bipsuint256[]Array of delegation percents specified in basis points (1/100 or 1 percent), for each delegatee.
_countuint256The number of returned delegatees.
_delegationModeuint256The mode of the delegation (NOTSET=0, PERCENTAGE=1, AMOUNT=2). See Delegatable.DelegationMode.
+
+
+
+

delegatesOfAt#

+
+

Defined in VPContract (Docs, Source).

+
+
+
function delegatesOfAt(
+    address _owner,
+    uint256 _blockNumber
+) public view returns (
+    address[] _delegateAddresses,
+    uint256[] _bips,
+    uint256 _count,
+    uint256 _delegationMode);
+
+

Get the percentages and addresses being delegated to by a vote power delegator, +at a given block.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address of the delegator being queried.
_blockNumberuint256The block number being queried.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_delegateAddressesaddress[]Array of delegatee addresses.
_bipsuint256[]Array of delegation percents specified in basis points (1/100 or 1 percent), for each delegatee.
_countuint256The number of returned delegatees.
_delegationModeuint256The mode of the delegation (NOTSET=0, PERCENTAGE=1, AMOUNT=2). See Delegatable.DelegationMode.
+
+
+
+

delegationModeOf#

+
+

Defined in VPContract (Docs, Source).

+
+
+
function delegationModeOf(
+    address _who
+) external view returns (
+    uint256);
+
+

Get the delegation mode of an address. This mode determines whether vote power is +allocated by percentage or by explicit value and cannot be changed once set with +delegate or delegateExplicit.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address being queried.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Delegation mode (NOTSET=0, PERCENTAGE=1, AMOUNT=2). See Delegatable.DelegationMode.
+
+
+
+

explicitDelegationHistoryCleanup#

+
+

Defined in Delegatable (Docs, Source).

+
+
+
function explicitDelegationHistoryCleanup(
+    address _from,
+    address _to,
+    uint256 _count
+) external returns (
+    uint256);
+
+

Delete explicit delegation checkpoints that expired (i.e. are before cleanupBlockNumber). +Method can only be called from the cleanerContract (which may be a proxy to external cleaners).

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressDelegator address.
_toaddressDelegatee address.
_countuint256Maximum number of checkpoints to delete.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Number of checkpoints deleted.
+
+
+
+

isReplacement#

+
+

Defined in IIVPContract (Docs, Source).

+
+
+
function isReplacement(
+) external view returns (
+    bool);
+
+

Return true if this IIVPContract is configured to be used as a replacement for other contract. +It means that vote powers are not necessarily correct at the initialization, therefore +every method that reads vote power must check whether it is initialized for that address and block.

+
+
+
+

ownerToken#

+
+

Defined in IIVPContract (Docs, Source).

+
+
+
function ownerToken(
+) external view returns (
+    contract IVPToken);
+
+

The VPToken (or some other contract) that owns this VPContract. +All state changing methods may be called only from this address. +This is because original msg.sender is typically sent in a parameter +and we must make sure that it cannot be faked by directly calling +IIVPContract methods. +Owner token is also used in case of replacement to recover vote powers from balances.

+
+
+
+

percentageDelegationHistoryCleanup#

+
+

Defined in Delegatable (Docs, Source).

+
+
+
function percentageDelegationHistoryCleanup(
+    address _owner,
+    uint256 _count
+) external returns (
+    uint256);
+
+

Delete percentage delegation checkpoints that expired (i.e. are before cleanupBlockNumber). +Method can only be called from the cleanerContract (which may be a proxy to external cleaners).

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressBalance owner account address.
_countuint256Maximum number of checkpoints to delete.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Number of deleted checkpoints.
+
+
+
+

revocationCleanup#

+
+

Defined in Delegatable (Docs, Source).

+
+
+
function revocationCleanup(
+    address _from,
+    address _to,
+    uint256 _blockNumber
+) external returns (
+    uint256);
+
+

Delete revocation entry that expired (i.e. is before cleanupBlockNumber). +Method can only be called from the cleanerContract (which may be a proxy to external cleaners).

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressDelegator address.
_toaddressDelegatee address.
_blockNumberuint256Block number for which total supply value was cached.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Number of revocation entries deleted (always 0 or 1).
+
+
+
+

revokeDelegationAt#

+
+

Defined in VPContract (Docs, Source).

+
+
+
function revokeDelegationAt(
+    address _from,
+    address _to,
+    uint256 _balance,
+    uint256 _blockNumber
+) external;
+
+

Revoke all vote power delegation from a delegator address to a delegatee address at a given block. +Only affects the reads via votePowerOfAtCached in the block _blockNumber. +This method should be used only to prevent rogue delegate voting in the current voting block. +To stop delegating use delegate or delegateExplicit with value of 0, +or undelegateAll/ undelegateAllExplicit.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressThe address of the delegator.
_toaddressAddress of the delegatee.
_balanceuint256The delegator's current balance.
_blockNumberuint256The block number at which to revoke delegation. Must be in the past.
+
+
+
+

setCleanerContract#

+
+

Defined in VPContract (Docs, Source).

+
+
+
function setCleanerContract(
+    address _cleanerContract
+) external;
+
+

Set the contract that is allowed to call history cleaning methods.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_cleanerContractaddressAddress of the cleanup contract. Usually this will be an instance of CleanupBlockNumberManager.
+
+
+
+

setCleanupBlockNumber#

+
+

Defined in VPContract (Docs, Source).

+
+
+
function setCleanupBlockNumber(
+    uint256 _blockNumber
+) external;
+
+

Set the cleanup block number. +Historic data for the blocks before cleanupBlockNumber can be erased. +History before that block should never be used since it can be inconsistent. +In particular, cleanup block number must be lower than the current vote power block.

+

The method can be called only by the owner token.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockNumberuint256The new cleanup block number.
+
+
+
+

undelegateAll#

+
+

Defined in VPContract (Docs, Source).

+
+
+
function undelegateAll(
+    address _from,
+    uint256 _balance
+) external;
+
+

Undelegate all voting power for a delegator address. +Can only be used with percentage delegation. +Does not reset delegation mode back to NOTSET.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressThe address of the delegator.
_balanceuint256The delegator's current balance.
+
+
+
+

undelegateAllExplicit#

+
+

Defined in VPContract (Docs, Source).

+
+
+
function undelegateAllExplicit(
+    address _from,
+    address[] _delegateAddresses
+) external returns (
+    uint256);
+
+

Undelegate all explicit vote power by amount for a delegator address. +Can only be used with explicit delegation. +Does not reset delegation mode back to NOTSET.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressThe address of the delegator.
_delegateAddressesaddress[]Explicit delegation does not store delegatees' addresses, so the caller must supply them.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The amount still delegated (in case the list of delegates was incomplete).
+
+
+
+

undelegatedVotePowerOf#

+
+

Defined in VPContract (Docs, Source).

+
+
+
function undelegatedVotePowerOf(
+    address _owner,
+    uint256 _balance
+) external view returns (
+    uint256);
+
+

Compute the current undelegated vote power of an address.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address being queried.
_balanceuint256Current balance of that address.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The unallocated vote power of _owner, this is, the amount of vote power currently not being delegated to other addresses.
+
+
+
+

undelegatedVotePowerOfAt#

+
+

Defined in VPContract (Docs, Source).

+
+
+
function undelegatedVotePowerOfAt(
+    address _owner,
+    uint256 _balance,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Compute the undelegated vote power of an address at a given block.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address being queried.
_balanceuint256
_blockNumberuint256The block number being queried.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The unallocated vote power of _owner, this is, the amount of vote power that was not being delegated to other addresses at that block number.
+
+
+
+

updateAtTokenTransfer#

+
+

Defined in VPContract (Docs, Source).

+
+
+
function updateAtTokenTransfer(
+    address _from,
+    address _to,
+    uint256 _fromBalance,
+    uint256 _toBalance,
+    uint256 _amount
+) external;
+
+

Update vote powers when tokens are transferred. +Also update delegated vote powers for percentage delegation +and check for enough funds for explicit delegations.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressSource account of the transfer.
_toaddressDestination account of the transfer.
_fromBalanceuint256Balance of the source account before the transfer.
_toBalanceuint256Balance of the destination account before the transfer.
_amountuint256Amount that has been transferred.
+
+
+
+

votePowerCacheCleanup#

+
+

Defined in Delegatable (Docs, Source).

+
+
+
function votePowerCacheCleanup(
+    address _owner,
+    uint256 _blockNumber
+) external returns (
+    uint256);
+
+

Delete vote power cache entry that expired (i.e. is before cleanupBlockNumber). +Method can only be called from the cleanerContract (which may be a proxy to external cleaners).

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressVote power owner account address.
_blockNumberuint256Block number for which total supply value was cached.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Number of deleted cache entries (always 0 or 1).
+
+
+
+

votePowerFromTo#

+
+

Defined in VPContract (Docs, Source).

+
+
+
function votePowerFromTo(
+    address _from,
+    address _to,
+    uint256 _balance
+) external view returns (
+    uint256);
+
+

Get current delegated vote power from a delegator to a delegatee.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressAddress of the delegator.
_toaddressAddress of the delegatee.
_balanceuint256The delegator's current balance.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The delegated vote power.
+
+
+
+

votePowerFromToAt#

+
+

Defined in VPContract (Docs, Source).

+
+
+
function votePowerFromToAt(
+    address _from,
+    address _to,
+    uint256 _balance,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Get delegated the vote power from a delegator to a delegatee at a given block number.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressAddress of the delegator.
_toaddressAddress of the delegatee.
_balanceuint256The delegator's current balance.
_blockNumberuint256The block number being queried.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The delegated vote power.
+
+
+
+

votePowerHistoryCleanup#

+
+

Defined in Delegatable (Docs, Source).

+
+
+
function votePowerHistoryCleanup(
+    address _owner,
+    uint256 _count
+) external returns (
+    uint256);
+
+

Delete vote power checkpoints that expired (i.e. are before cleanupBlockNumber). +Method can only be called from the cleanerContract (which may be a proxy to external cleaners).

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressVote power owner account address.
_countuint256Maximum number of checkpoints to delete.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Number of deleted checkpoints.
+
+
+
+

votePowerOf#

+
+

Defined in VPContract (Docs, Source).

+
+
+
function votePowerOf(
+    address _who
+) external view returns (
+    uint256);
+
+

Get the current vote power of an address.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address being queried.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Current vote power of _who, including any delegation received.
+
+
+
+

votePowerOfAt#

+
+

Defined in VPContract (Docs, Source).

+
+
+
function votePowerOfAt(
+    address _who,
+    uint256 _blockNumber
+) public view returns (
+    uint256);
+
+

Get the vote power of an address at a given block number

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address being queried.
_blockNumberuint256The block number being queried.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Vote power of _who at _blockNumber, including any delegation received.
+
+
+
+

votePowerOfAtCached#

+
+

Defined in VPContract (Docs, Source).

+
+
+
function votePowerOfAtCached(
+    address _who,
+    uint256 _blockNumber
+) external returns (
+    uint256);
+
+

Get the vote power of an address at a given block number. +Reads/updates cache and upholds revocations.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address being queried.
_blockNumberuint256The block number being queried.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Vote power of _who at _blockNumber, including any delegation received.
+
+
+
+

votePowerOfAtIgnoringRevocation#

+
+

Defined in VPContract (Docs, Source).

+
+
+
function votePowerOfAtIgnoringRevocation(
+    address _who,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Get the vote power of an address at a given block number, ignoring revocation information and cache.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address being queried.
_blockNumberuint256The block number being queried.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Vote power of _who at _blockNumber, including any delegation received. Result doesn't change if vote power is revoked.
+
+
+
+
+

Modifiers#

+
+

notBeforeCleanupBlock#

+
+

Defined in Delegatable (Docs, Source).

+
+
+
modifier notBeforeCleanupBlock(    uint256 _blockNumber)
+
+

Reading from history is not allowed before cleanupBlockNumber, since data before that +might have been deleted and is thus unreliable.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockNumberuint256The block number being checked for validity.
+
+
+
+

onlyCleaner#

+
+

Defined in Delegatable (Docs, Source).

+
+
+
modifier onlyCleaner()
+
+

History cleaning methods can be called only from cleanerContract.

+
+
+
+

onlyExplicit#

+
+

Defined in VPContract (Docs, Source).

+
+
+
modifier onlyExplicit(    address sender)
+
+

If a delegate cannot be added by explicit amount, revert.

+
+
+
+

onlyOwnerToken#

+
+

Defined in VPContract (Docs, Source).

+
+
+
modifier onlyOwnerToken()
+
+

All external methods in VPContract can only be executed by the owner token.

+
+
+
+

onlyPercent#

+
+

Defined in VPContract (Docs, Source).

+
+
+
modifier onlyPercent(    address sender)
+
+

If a delegate cannot be added by percentage, revert.

+
+
+
+
+

Variables#

+
+

cleanerContract#

+
+

Defined in Delegatable (Docs, Source).

+
+
+
    address cleanerContract
+
+

Address of the contract that is allowed to call methods for history cleaning.

+
+
+
+

isReplacement#

+
+

Defined in VPContract (Docs, Source).

+
+
+
    bool isReplacement
+
+

Return true if this IIVPContract is configured to be used as a replacement for other contract. +It means that vote powers are not necessarily correct at the initialization, therefore +every method that reads vote power must check whether it is initialized for that address and block.

+
+
+
+

ownerToken#

+
+

Defined in VPContract (Docs, Source).

+
+
+
    contract IVPToken ownerToken
+
+

The VPToken (or some other contract) that owns this VPContract. +All state changing methods may be called only from this address. +This is because original msg.sender is typically sent in a parameter +and we must make sure that it cannot be faked by directly calling +IIVPContract methods. +Owner token is also used in case of replacement to recover vote powers from balances.

+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/VPToken/index.html b/apis/smart-contracts/VPToken/index.html new file mode 100644 index 000000000..7892cbf87 --- /dev/null +++ b/apis/smart-contracts/VPToken/index.html @@ -0,0 +1,6890 @@ + + + + + + + + + + + + + + + + + + VPToken - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

VPToken#

+
+

Source | Inherits from IIVPToken, ERC20, CheckPointable, Governed

+
+
+

Vote power token.

+

An ERC20 token that enables the holder to delegate a voting power +equal to their balance, with history tracking by block height. +Actual vote power and delegation functionality is implemented in an associated VPContract.

+
+
+

Events#

+
+

Approval#

+
+

Defined in IERC20 (Source).

+
+
+
event Approval(
+    address owner,
+    address spender,
+    uint256 value
+)
+
+

Emitted when the allowance of a spender for an owner is set by +a call to approve. value is the new allowance.

+
+
+
+

CreatedTotalSupplyCache#

+
+

Defined in CheckPointable (Docs, Source).

+
+
+
event CreatedTotalSupplyCache(
+    uint256 _blockNumber
+)
+
+

Emitted when a total supply cache entry is created. +Allows history cleaners to track total supply cache cleanup opportunities off-chain.

+
+
+
+

GovernanceCallTimelocked#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event GovernanceCallTimelocked(
+    bytes4 selector,
+    uint256 allowedAfterTimestamp,
+    bytes encodedCall
+)
+
+

Emitted when a new governance call has been recorded and is now waiting for the time lock to expire.

+
+
+
+

GovernanceInitialised#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event GovernanceInitialised(
+    address initialGovernance
+)
+
+

Emitted when the governance address is initialized. +This address will be used until production mode is entered (see GovernedProductionModeEntered). +At that point the governance address is taken from GovernanceSettings.

+
+
+
+

GovernedProductionModeEntered#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event GovernedProductionModeEntered(
+    address governanceSettings
+)
+
+

Emitted when governance is enabled and the governance address cannot be changed anymore +(only through a network fork).

+
+
+
+

TimelockedGovernanceCallCanceled#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event TimelockedGovernanceCallCanceled(
+    bytes4 selector,
+    uint256 timestamp
+)
+
+

Emitted when a timelocked governance call is canceled before execution.

+
+
+
+

TimelockedGovernanceCallExecuted#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event TimelockedGovernanceCallExecuted(
+    bytes4 selector,
+    uint256 timestamp
+)
+
+

Emitted when a timelocked governance call is executed.

+
+
+
+

Transfer#

+
+

Defined in IERC20 (Source).

+
+
+
event Transfer(
+    address from,
+    address to,
+    uint256 value
+)
+
+

Emitted when value tokens are moved from one account (from) to +another (to).

+

Note that value may be zero.

+
+
+
+

VotePowerContractChanged#

+
+

Defined in VPToken (Docs, Source).

+
+
+
event VotePowerContractChanged(
+    uint256 _contractType,
+    address _oldContractAddress,
+    address _newContractAddress
+)
+
+

Emitted when one of the vote power contracts is changed.

+

It is used to track the history of VPToken -> VPContract / GovernanceVotePower +associations (e.g. by external cleaners).

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_contractTypeuint2560 = Read VPContract, 1 = Write VPContract, 2 = Governance vote power.
_oldContractAddressaddressContract address before change.
_newContractAddressaddressContract address after change.
+
+
+
+
+

Functions#

+
+

allowance#

+
+

Defined in IERC20 (Source).

+
+
+
function allowance(
+    address owner,
+    address spender
+) external view returns (
+    uint256);
+
+

Returns the remaining number of tokens that spender will be +allowed to spend on behalf of owner through transferFrom. This is +zero by default.

+

This value changes when approve or transferFrom are called.

+
+
+
+

approve#

+
+

Defined in IERC20 (Source).

+
+
+
function approve(
+    address spender,
+    uint256 amount
+) external returns (
+    bool);
+
+

Sets amount as the allowance of spender over the caller's tokens.

+

Returns a boolean value indicating whether the operation succeeded.

+

IMPORTANT: Beware that changing an allowance with this method brings the risk +that someone may use both the old and the new allowance by unfortunate +transaction ordering. One possible solution to mitigate this race +condition is to first reduce the spender's allowance to 0 and set the +desired value afterwards: +https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729

+

Emits an Approval event.

+
+
+
+

balanceHistoryCleanup#

+
+

Defined in CheckPointable (Docs, Source).

+
+
+
function balanceHistoryCleanup(
+    address _owner,
+    uint256 _count
+) external returns (
+    uint256);
+
+

Delete balance checkpoints that expired (i.e. are before cleanupBlockNumber). +Method can only be called from the cleanerContract (which may be a proxy to external cleaners).

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressbalance owner account address
_countuint256maximum number of checkpoints to delete
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256the number of checkpoints deleted
+
+
+
+

balanceOf#

+
+

Defined in IERC20 (Source).

+
+
+
function balanceOf(
+    address account
+) external view returns (
+    uint256);
+
+

Returns the amount of tokens owned by account.

+
+
+
+

balanceOfAt#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function balanceOfAt(
+    address _owner,
+    uint256 _blockNumber
+) public view returns (
+    uint256);
+
+

Queries the token balance of _owner at a specific _blockNumber.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address from which the balance will be retrieved.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256
+
+
+
+

batchDelegate#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function batchDelegate(
+    address[] _delegatees,
+    uint256[] _bips
+) external;
+
+

Undelegate all percentage delegations from the sender and then delegate corresponding + _bips percentage of voting power from the sender to each member of the _delegatees array.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_delegateesaddress[]The addresses of the new recipients.
_bipsuint256[]The percentages of voting power to be delegated expressed in basis points (1/100 of one percent). The sum of all _bips values must be at most 10000 (100%).
+
+
+
+

batchVotePowerOfAt#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function batchVotePowerOfAt(
+    address[] _owners,
+    uint256 _blockNumber
+) external view returns (
+    uint256[]);
+
+

Return the vote power for several addresses.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_ownersaddress[]The list of addresses to query.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256[]Array of vote power for each queried address.
+
+
+
+

cancelGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function cancelGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Cancel a timelocked governance call before it has been executed.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector.
+
+
+
+

cleanupBlockNumber#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function cleanupBlockNumber(
+) external view returns (
+    uint256);
+
+

Get the current cleanup block number set with setCleanupBlockNumber.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The currently set cleanup block number.
+
+
+
+

constructor#

+
+

Defined in VPToken (Docs, Source).

+
+
+
constructor(
+    address _governance,
+    string _name,
+    string _symbol
+) public;
+
+
+
+
+

constructor#

+
+

Defined in Governed (Docs, Source).

+
+
+
constructor(
+    address _governance
+) public;
+
+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_governanceaddressGovernance contract. Must not be zero.
+
+
+
+

constructor#

+
+

Defined in ERC20 (Source).

+
+
+
constructor(
+    string name_,
+    string symbol_
+) public;
+
+

Sets the values for name and symbol, initializes decimals with +a default value of 18.

+

To select a different value for decimals, use _setupDecimals.

+

All three of these values are immutable: they can only be set once during +construction.

+
+
+
+

decimals#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function decimals(
+) public view returns (
+    uint8);
+
+

Returns the number of decimals used to get its user representation. +For example, if decimals equals 2, a balance of 505 tokens should +be displayed to a user as 5.05 (505 / 102).

+

Tokens usually opt for a value of 18, imitating the relationship between +Ether and wei. This is the default value returned by this function, unless +it's overridden.

+

NOTE: This information is only used for display purposes: it in +no way affects any of the arithmetic of the contract, including +balanceOf and transfer.

+

Should be compatible with ERC20 method.

+
+
+
+

delegate#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function delegate(
+    address _to,
+    uint256 _bips
+) external;
+
+

Delegate voting power to account _to from msg.sender, by percentage.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_toaddressThe address of the recipient.
_bipsuint256The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: every call resets the delegation value (and a value of 0 revokes all previous delegations).
+
+
+
+

delegateExplicit#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function delegateExplicit(
+    address _to,
+    uint256 _amount
+) external;
+
+

Explicitly delegate _amount voting power to account _to from msg.sender. +Compare with delegate which delegates by percentage.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_toaddressThe address of the recipient.
_amountuint256An explicit vote power amount to be delegated. Not cumulative: every call resets the delegation value (and a value of 0 revokes all previous delegations).
+
+
+
+

delegatesOf#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function delegatesOf(
+    address _owner
+) external view returns (
+    address[] _delegateAddresses,
+    uint256[] _bips,
+    uint256 _count,
+    uint256 _delegationMode);
+
+

Get the list of addresses to which _who is delegating, and their percentages.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddress
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_delegateAddressesaddress[]Positional array of addresses being delegated to.
_bipsuint256[]Positional array of delegation percents specified in basis points (1/100 of 1 percent). Each one matches the address in the same position in the _delegateAddresses array.
_countuint256The number of delegates.
_delegationModeuint256Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).
+
+
+
+

delegatesOfAt#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function delegatesOfAt(
+    address _owner,
+    uint256 _blockNumber
+) external view returns (
+    address[] _delegateAddresses,
+    uint256[] _bips,
+    uint256 _count,
+    uint256 _delegationMode);
+
+

Get the list of addresses to which _who is delegating, and their percentages, at the given block.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddress
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_delegateAddressesaddress[]Positional array of addresses being delegated to.
_bipsuint256[]Positional array of delegation percents specified in basis points (1/100 of 1 percent). Each one matches the address in the same position in the _delegateAddresses array.
_countuint256The number of delegates.
_delegationModeuint256Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).
+
+
+
+

delegationModeOf#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function delegationModeOf(
+    address _who
+) external view returns (
+    uint256);
+
+

Get the delegation mode for account '_who'. This mode determines whether vote power is +allocated by percentage or by explicit amount. Once the delegation mode is set, +it can never be changed, even if all delegations are removed.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address to get delegation mode.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).
+
+
+
+

executeGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function executeGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Execute the timelocked governance calls once the timelock period expires.

+

Only executor can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector (only one timelocked call per method is stored).
+
+
+
+

governance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function governance(
+) public view returns (
+    address);
+
+

Returns the current effective governance address.

+
+
+
+

governanceVotePower#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function governanceVotePower(
+) external view returns (
+    contract IGovernanceVotePower);
+
+

When set, allows token owners to participate in governance voting +and delegate governance vote power.

+
+
+
+

name#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function name(
+) public view returns (
+    string);
+
+

Returns the name of the token.

+

Should be compatible with ERC20 method.

+
+
+
+

readVotePowerContract#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function readVotePowerContract(
+) external view returns (
+    contract IVPContractEvents);
+
+

Returns VPContract event interface used for read-only operations (view methods). +The only non-view method that might be called on it is revokeDelegationAt.

+

readVotePowerContract is almost always equal to writeVotePowerContract +except during an upgrade from one VPContract to a new version (which should happen +rarely or never and will be announced beforehand).

+

Do not call any methods on VPContract directly. +State changing methods are forbidden from direct calls. +All methods are exposed via VPToken. +This is the reason that this method returns IVPContractEvents. +Use it only for listening to events and revoking.

+
+
+
+

revokeDelegationAt#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function revokeDelegationAt(
+    address _who,
+    uint256 _blockNumber
+) public;
+
+

Revoke all delegation from sender to _who at given block. +Only affects the reads via votePowerOfAtCached in the block _blockNumber. +Block _blockNumber must be in the past. +This method should be used only to prevent rogue delegate voting in the current voting block. +To stop delegating use delegate / delegateExplicit with value of 0 or undelegateAll / undelegateAllExplicit.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressAddress of the delegatee.
_blockNumberuint256The block number at which to revoke delegation..
+
+
+
+

setCleanerContract#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function setCleanerContract(
+    address _cleanerContract
+) external;
+
+

Set the contract that is allowed to call history cleaning methods.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_cleanerContractaddressAddress of the cleanup contract. Usually this will be an instance of CleanupBlockNumberManager.
+
+
+
+

setCleanupBlockNumber#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function setCleanupBlockNumber(
+    uint256 _blockNumber
+) external;
+
+

Set the cleanup block number. +Historic data for the blocks before cleanupBlockNumber can be erased. +History before that block should never be used since it can be inconsistent. +In particular, cleanup block number must be lower than the current vote power block.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockNumberuint256The new cleanup block number.
+
+
+
+

setCleanupBlockNumberManager#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function setCleanupBlockNumberManager(
+    address _cleanupBlockNumberManager
+) external;
+
+

Set the contract that is allowed to set cleanupBlockNumber. +Usually this will be an instance of CleanupBlockNumberManager.

+
+
+
+

setGovernanceVotePower#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function setGovernanceVotePower(
+    contract IIGovernanceVotePower _governanceVotePower
+) external;
+
+

Sets new governance vote power contract that allows token owners to participate in governance voting +and delegate governance vote power.

+
+
+
+

setReadVpContract#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function setReadVpContract(
+    contract IIVPContract _vpContract
+) external;
+
+

Call from governance to set read VpContract on token, e.g. +vpToken.setReadVpContract(new VPContract(vpToken)).

+

Read VPContract must be set before any of the VPToken delegation or vote power reading methods are called, +otherwise they will revert.

+

NOTE: If readVpContract differs from writeVpContract all reads will be "frozen" and will not reflect +changes (not even revokes; they may or may not reflect balance transfers).

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_vpContractcontract IIVPContractRead vote power contract to be used by this token.
+
+
+
+

setWriteVpContract#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function setWriteVpContract(
+    contract IIVPContract _vpContract
+) external;
+
+

Call from governance to set write VpContract on token, e.g. +vpToken.setWriteVpContract(new VPContract(vpToken)).

+

Write VPContract must be set before any of the VPToken delegation modifying methods are called, +otherwise they will revert.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_vpContractcontract IIVPContractWrite vote power contract to be used by this token.
+
+
+
+

switchToProductionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function switchToProductionMode(
+) external;
+
+

Enter the production mode after all the initial governance settings have been set. +This enables timelocks and the governance can be obtained afterward by calling +governanceSettings.getGovernanceAddress(). +Emits GovernedProductionModeEntered.

+
+
+
+

symbol#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function symbol(
+) public view returns (
+    string);
+
+

Returns the symbol of the token, usually a shorter version of the name.

+

Should be compatible with ERC20 method.

+
+
+
+

totalSupply#

+
+

Defined in IERC20 (Source).

+
+
+
function totalSupply(
+) external view returns (
+    uint256);
+
+

Returns the amount of tokens in existence.

+
+
+
+

totalSupplyAt#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function totalSupplyAt(
+    uint256 _blockNumber
+) public view returns (
+    uint256);
+
+

Total amount of tokens at a specific _blockNumber.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockNumberuint256The block number when the _totalSupply is queried
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256
+
+
+
+

totalSupplyCacheCleanup#

+
+

Defined in CheckPointable (Docs, Source).

+
+
+
function totalSupplyCacheCleanup(
+    uint256 _blockNumber
+) external returns (
+    uint256);
+
+

Delete total supply cache entry that expired (i.e. is before cleanupBlockNumber). +Method can only be called from the cleanerContract (which may be a proxy to external cleaners).

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockNumberuint256the block number for which total supply value was cached
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256the number of cache entries deleted (always 0 or 1)
+
+
+
+

totalSupplyHistoryCleanup#

+
+

Defined in CheckPointable (Docs, Source).

+
+
+
function totalSupplyHistoryCleanup(
+    uint256 _count
+) external returns (
+    uint256);
+
+

Delete total supply checkpoints that expired (i.e. are before cleanupBlockNumber). +Method can only be called from the cleanerContract (which may be a proxy to external cleaners).

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_countuint256maximum number of checkpoints to delete
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256the number of checkpoints deleted
+
+
+
+

totalVotePower#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function totalVotePower(
+) external view returns (
+    uint256);
+
+

Get the current total vote power.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The current total vote power (sum of all accounts' vote power).
+
+
+
+

totalVotePowerAt#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function totalVotePowerAt(
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Get the total vote power at block _blockNumber.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The total vote power at the queried block (sum of all accounts' vote powers).
+
+
+
+

totalVotePowerAtCached#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function totalVotePowerAtCached(
+    uint256 _blockNumber
+) public returns (
+    uint256);
+
+

Get the total vote power at block _blockNumber using cache. + It tries to read the cached value and if it is not found, reads the actual value and stores it in the cache. + Can only be used if _blockNumber is in the past, otherwise reverts.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The total vote power at the queried block (sum of all accounts' vote powers).
+
+
+
+

transfer#

+
+

Defined in IERC20 (Source).

+
+
+
function transfer(
+    address recipient,
+    uint256 amount
+) external returns (
+    bool);
+
+

Moves amount tokens from the caller's account to recipient.

+

Returns a boolean value indicating whether the operation succeeded.

+

Emits a Transfer event.

+
+
+
+

transferFrom#

+
+

Defined in IERC20 (Source).

+
+
+
function transferFrom(
+    address sender,
+    address recipient,
+    uint256 amount
+) external returns (
+    bool);
+
+

Moves amount tokens from sender to recipient using the +allowance mechanism. amount is then deducted from the caller's +allowance.

+

Returns a boolean value indicating whether the operation succeeded.

+

Emits a Transfer event.

+
+
+
+

undelegateAll#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function undelegateAll(
+) external;
+
+

Undelegate all voting power of msg.sender. This effectively revokes all previous delegations. +Can only be used with percentage delegation. +Does not reset delegation mode back to NOT SET.

+
+
+
+

undelegateAllExplicit#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function undelegateAllExplicit(
+    address[] _delegateAddresses
+) external returns (
+    uint256 _remainingDelegation);
+
+

Undelegate all explicit vote power by amount of msg.sender. +Can only be used with explicit delegation. +Does not reset delegation mode back to NOT SET.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_delegateAddressesaddress[]Explicit delegation does not store delegatees' addresses, so the caller must supply them.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_remainingDelegationuint256The amount still delegated (in case the list of delegates was incomplete).
+
+
+
+

undelegatedVotePowerOf#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function undelegatedVotePowerOf(
+    address _owner
+) external view returns (
+    uint256);
+
+

Compute the current undelegated vote power of the _owner account.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The unallocated vote power of _owner.
+
+
+
+

undelegatedVotePowerOfAt#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function undelegatedVotePowerOfAt(
+    address _owner,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Get the undelegated vote power of the _owner account at a given block number.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address to query.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The unallocated vote power of _owner.
+
+
+
+

votePowerFromTo#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function votePowerFromTo(
+    address _from,
+    address _to
+) external view returns (
+    uint256);
+
+

Get current delegated vote power from delegator _from to delegatee _to.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressAddress of delegator.
_toaddressAddress of delegatee.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256votePower The delegated vote power.
+
+
+
+

votePowerFromToAt#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function votePowerFromToAt(
+    address _from,
+    address _to,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Get delegated vote power from delegator _from to delegatee _to at _blockNumber.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressAddress of delegator.
_toaddressAddress of delegatee.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The delegated vote power.
+
+
+
+

votePowerOf#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function votePowerOf(
+    address _owner
+) external view returns (
+    uint256);
+
+

Get the current vote power of _owner.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Current vote power of _owner.
+
+
+
+

votePowerOfAt#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function votePowerOfAt(
+    address _owner,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Get the vote power of _owner at block _blockNumber

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address to query.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Vote power of _owner at block number _blockNumber.
+
+
+
+

votePowerOfAtCached#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function votePowerOfAtCached(
+    address _owner,
+    uint256 _blockNumber
+) public returns (
+    uint256);
+
+

Get the vote power of _owner at block _blockNumber using cache. + It tries to read the cached value and if it is not found, reads the actual value and stores it in the cache. + Can only be used if _blockNumber is in the past, otherwise reverts.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address to query.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Vote power of _owner at _blockNumber.
+
+
+
+

votePowerOfAtIgnoringRevocation#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function votePowerOfAtIgnoringRevocation(
+    address _owner,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Get the vote power of _owner at block _blockNumber, ignoring revocation information (and cache).

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address to query.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Vote power of _owner at block number _blockNumber. Result doesn't change if vote power is revoked.
+
+
+
+

writeVotePowerContract#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function writeVotePowerContract(
+) external view returns (
+    contract IVPContractEvents);
+
+

Returns VPContract event interface used for state-changing operations (non-view methods). +The only non-view method that might be called on it is revokeDelegationAt.

+

writeVotePowerContract is almost always equal to readVotePowerContract, +except during upgrade from one VPContract to a new version (which should happen +rarely or never and will be announced beforehand). +In the case of an upgrade, writeVotePowerContract is replaced first to establish delegations. +After some period (e.g., after a reward epoch ends), readVotePowerContract is set equal to it.

+

Do not call any methods on VPContract directly. +State changing methods are forbidden from direct calls. +All are exposed via VPToken. +This is the reason that this method returns IVPContractEvents +Use it only for listening to events, delegating, and revoking.

+
+
+
+
+

Variables#

+
+

cleanerContract#

+
+

Defined in CheckPointable (Docs, Source).

+
+
+
    address cleanerContract
+
+

Address of the contract that is allowed to call methods for history cleaning.

+
+
+
+

cleanupBlockNumberManager#

+
+

Defined in VPToken (Docs, Source).

+
+
+
    address cleanupBlockNumberManager
+
+

The contract that is allowed to set cleanupBlockNumber. +Usually this will be an instance of CleanupBlockNumberManager.

+
+
+
+

governanceSettings#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    contract IGovernanceSettings governanceSettings
+
+

Governance Settings.

+
+
+
+

productionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    bool productionMode
+
+

When true, governance is enabled and cannot be disabled. See switchToProductionMode.

+
+
+
+

timelockedCalls#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    mapping(bytes4 => struct GovernedBase.TimelockedCall) timelockedCalls
+
+

List of pending timelocked governance calls.

+
+
+
+

vpContractInitialized#

+
+

Defined in VPToken (Docs, Source).

+
+
+
    bool vpContractInitialized
+
+

When true, the argument to setWriteVpContract must be a vpContract +with isReplacement set to true. To be used for creating the correct VPContract.

+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/VoterWhitelister/index.html b/apis/smart-contracts/VoterWhitelister/index.html new file mode 100644 index 000000000..b126be48b --- /dev/null +++ b/apis/smart-contracts/VoterWhitelister/index.html @@ -0,0 +1,5445 @@ + + + + + + + + + + + + + + + + + + VoterWhitelister - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + +

VoterWhitelister#

+ +
+

Manager of the FTSO whitelist.

+

Only addresses registered in this contract can submit data to the FTSO system.

+
+
+

Functions#

+
+

addFtso#

+
+

Defined in VoterWhitelister (Docs, Source).

+
+
+
function addFtso(
+    uint256 _ftsoIndex
+) external;
+
+

Create an empty whitelist with default size for a new FTSO.

+

Only ftsoManager can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsoIndexuint256Index of the new FTSO.
+
+
+
+

cancelGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function cancelGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Cancel a timelocked governance call before it has been executed.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector.
+
+
+
+

chillVoter#

+
+

Defined in VoterWhitelister (Docs, Source).

+
+
+
function chillVoter(
+    address _voter,
+    uint256 _noOfRewardEpochs,
+    uint256[] _ftsoIndices
+) external returns (
+    bool[] _removed,
+    uint256 _untilRewardEpoch);
+
+

Used to chill a data provider, this is, remove it from the whitelist for a +specified number of reward epochs.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_voteraddressData provider being chilled.
_noOfRewardEpochsuint256Number of epochs to chill the provider for.
_ftsoIndicesuint256[]Array of indices of the FTSOs that will not allow this provider to submit data.
+
+
+
+

chilledUntilRewardEpoch#

+
+

Defined in IVoterWhitelister (Docs, Source).

+
+
+
function chilledUntilRewardEpoch(
+    address _voter
+) external view returns (
+    uint256);
+
+

In case of providing bad prices (e.g. collusion), the voter can be chilled for a few reward epochs. +A voter can whitelist again from a returned reward epoch onwards.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_voteraddressAddress of the queried data provider.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256uint256 ID of the epoch where the data provider can start submitting prices again.
+
+
+
+

constructor#

+
+

Defined in VoterWhitelister (Docs, Source).

+
+
+
constructor(
+    address _governance,
+    address _addressUpdater,
+    contract IIPriceSubmitter _priceSubmitter,
+    uint256 _defaultMaxVotersForFtso,
+    contract IVoterWhitelister _oldVoterWhitelister
+) public;
+
+
+
+
+

constructor#

+
+

Defined in Governed (Docs, Source).

+
+
+
constructor(
+    address _governance
+) public;
+
+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_governanceaddressGovernance contract. Must not be zero.
+
+
+
+

copyWhitelist#

+
+

Defined in VoterWhitelister (Docs, Source).

+
+
+
function copyWhitelist(
+    uint256 _ftsoIndex
+) external;
+
+

Copy whitelist data from oldVoterWhitelister for a specific FTSO. +Can only be called by governance.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsoIndexuint256Index of the FTSO whose whitelist is to be copied.
+
+
+
+

defaultMaxVotersForFtso#

+
+

Defined in IVoterWhitelister (Docs, Source).

+
+
+
function defaultMaxVotersForFtso(
+) external view returns (
+    uint256);
+
+

Maximum number of voters in the whitelist for a new FTSO.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256uint256 Default maximum allowed voters.
+
+
+
+

executeGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function executeGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Execute the timelocked governance calls once the timelock period expires.

+

Only executor can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector (only one timelocked call per method is stored).
+
+
+
+

getAddressUpdater#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
function getAddressUpdater(
+) public view returns (
+    address _addressUpdater);
+
+

Returns the configured address updater.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_addressUpdateraddressThe AddresUpdater contract that can update our contract address list, as a response to a governance call.
+
+
+
+

getFtsoWhitelistedPriceProviders#

+
+

Defined in VoterWhitelister (Docs, Source).

+
+
+
function getFtsoWhitelistedPriceProviders(
+    uint256 _ftsoIndex
+) public view returns (
+    address[]);
+
+

Gets whitelisted price providers for the FTSO at a given index.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsoIndexuint256Queried index.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]address[]Array of addresses of the whitelisted data providers.
+
+
+
+

getFtsoWhitelistedPriceProvidersBySymbol#

+
+

Defined in VoterWhitelister (Docs, Source).

+
+
+
function getFtsoWhitelistedPriceProvidersBySymbol(
+    string _symbol
+) external view returns (
+    address[]);
+
+

Gets whitelisted price providers for the FTSO with a specified symbol.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_symbolstringQueried symbol.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]address[]Array of addresses of the whitelisted data providers.
+
+
+
+

governance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function governance(
+) public view returns (
+    address);
+
+

Returns the current effective governance address.

+
+
+
+

maxVotersForFtso#

+
+

Defined in IVoterWhitelister (Docs, Source).

+
+
+
function maxVotersForFtso(
+    uint256 _ftsoIndex
+) external view returns (
+    uint256);
+
+

Maximum number of voters in the whitelist for a specific FTSO. +Adjustable separately for each index.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsoIndexuint256Index of the FTSO.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256uint256 Maximum allowed voters.
+
+
+
+

removeFtso#

+
+

Defined in VoterWhitelister (Docs, Source).

+
+
+
function removeFtso(
+    uint256 _ftsoIndex
+) external;
+
+

Clear whitelist for a removed FTSO.

+

Only ftsoManager can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsoIndexuint256Index of the removed FTSO.
+
+
+
+

removeTrustedAddressFromWhitelist#

+
+

Defined in VoterWhitelister (Docs, Source).

+
+
+
function removeTrustedAddressFromWhitelist(
+    address _trustedAddress,
+    uint256 _ftsoIndex
+) external;
+
+

Remove a trusted address from whitelist.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_trustedAddressaddressAddress to remove.
_ftsoIndexuint256Index of the FTSO being modified.
+
+
+
+

requestFullVoterWhitelisting#

+
+

Defined in VoterWhitelister (Docs, Source).

+
+
+
function requestFullVoterWhitelisting(
+    address _voter
+) external returns (
+    uint256[] _supportedIndices,
+    bool[] _success);
+
+

Requests whitelisting an account to act as a data provider for all active FTSOs. +May be called by any address, including the voter itself.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_voteraddressAddress of the voter to be whitelisted.
+ + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_supportedIndicesuint256[]Array of currently supported FTSO indices.
_successbool[]Array of success flags by FTSO index.
+
+
+
+

requestWhitelistingVoter#

+
+

Defined in VoterWhitelister (Docs, Source).

+
+
+
function requestWhitelistingVoter(
+    address _voter,
+    uint256 _ftsoIndex
+) external;
+
+

Requests whitelisting an account to act as a data provider for a specific FTSO. +Reverts if the vote power of the account is too low. +May be called by any address, including the voter itself.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_voteraddressAddress of the voter to be whitelisted.
_ftsoIndexuint256Index of the FTSO.
+
+
+
+

setDefaultMaxVotersForFtso#

+
+

Defined in VoterWhitelister (Docs, Source).

+
+
+
function setDefaultMaxVotersForFtso(
+    uint256 _defaultMaxVotersForFtso
+) external;
+
+

Set the maximum number of voters in the whitelist for a new FTSOs.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_defaultMaxVotersForFtsouint256New maximum default value.
+
+
+
+

setMaxVotersForFtso#

+
+

Defined in VoterWhitelister (Docs, Source).

+
+
+
function setMaxVotersForFtso(
+    uint256 _ftsoIndex,
+    uint256 _newMaxVoters
+) external;
+
+

Set the maximum number of voters in the whitelist for a specific FTSO. +Can remove voters with the least votepower from the whitelist.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_ftsoIndexuint256Index of the FTSO to modify.
_newMaxVotersuint256New size of the whitelist.
+
+
+
+

switchToProductionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function switchToProductionMode(
+) external;
+
+

Enter the production mode after all the initial governance settings have been set. +This enables timelocks and the governance can be obtained afterward by calling +governanceSettings.getGovernanceAddress(). +Emits GovernedProductionModeEntered.

+
+
+
+

turnOffCopyMode#

+
+

Defined in VoterWhitelister (Docs, Source).

+
+
+
function turnOffCopyMode(
+) external;
+
+

Turn off copy mode. +Can only be called by governance.

+
+
+
+

updateContractAddresses#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
function updateContractAddresses(
+    bytes32[] _contractNameHashes,
+    address[] _contractAddresses
+) external;
+
+

External method called from AddressUpdater only.

+
+
+
+
+

Modifiers#

+
+

notInCopyMode#

+
+

Defined in VoterWhitelister (Docs, Source).

+
+
+
modifier notInCopyMode()
+
+

Only callable when not in copy mode.

+
+
+
+

onlyAddressUpdater#

+
+

Defined in AddressUpdatable (Docs, Source).

+
+
+
modifier onlyAddressUpdater()
+
+

Only the AdressUpdater contract can call this method. +Its address is set at construction time but it can also update itself.

+
+
+
+

onlyFtsoManager#

+
+

Defined in VoterWhitelister (Docs, Source).

+
+
+
modifier onlyFtsoManager()
+
+

Only the ftsoManager can call this method.

+
+
+
+

onlyGovernance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
modifier onlyGovernance()
+
+
+
+
+

onlyImmediateGovernance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
modifier onlyImmediateGovernance()
+
+
+
+
+

voterNotChilled#

+
+

Defined in VoterWhitelister (Docs, Source).

+
+
+
modifier voterNotChilled(    address _voter)
+
+

Only data providers that have not been chilled can perform this action.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_voteraddressAddress of the data provider performing the action.
+
+
+
+
+

Variables#

+
+

chilledUntilRewardEpoch#

+
+

Defined in VoterWhitelister (Docs, Source).

+
+
+
    mapping(address => uint256) chilledUntilRewardEpoch
+
+

In case of providing bad prices (e.g. collusion), the voter can be chilled for a few reward epochs. +A voter can whitelist again from a returned reward epoch onwards.

+
+
+
+

copyMode#

+
+

Defined in VoterWhitelister (Docs, Source).

+
+
+
    bool copyMode
+
+
+
+
+

defaultMaxVotersForFtso#

+
+

Defined in VoterWhitelister (Docs, Source).

+
+
+
    uint256 defaultMaxVotersForFtso
+
+

Maximum number of voters in the whitelist for a new FTSO.

+
+
+
+

ftsoManager#

+
+

Defined in VoterWhitelister (Docs, Source).

+
+
+
    contract IFtsoManager ftsoManager
+
+

Address of the FtsoManager contract.

+
+
+
+

ftsoRegistry#

+
+

Defined in VoterWhitelister (Docs, Source).

+
+
+
    contract IFtsoRegistry ftsoRegistry
+
+

Address of the FtsoRegistry contract.

+
+
+
+

governanceSettings#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    contract IGovernanceSettings governanceSettings
+
+

Governance Settings.

+
+
+
+

maxVotersForFtso#

+
+

Defined in VoterWhitelister (Docs, Source).

+
+
+
    mapping(uint256 => uint256) maxVotersForFtso
+
+

Maximum number of voters in the whitelist for a specific FTSO. +Adjustable separately for each index.

+
+
+
+

oldVoterWhitelister#

+
+

Defined in VoterWhitelister (Docs, Source).

+
+
+
    contract IVoterWhitelister oldVoterWhitelister
+
+

Previous VoterWhitelister contract, set at construction time. +Necessary to allow copying the previous whitelist onto a new contract.

+
+
+
+

priceSubmitter#

+
+

Defined in VoterWhitelister (Docs, Source).

+
+
+
    contract IIPriceSubmitter priceSubmitter
+
+

Address of the PriceSubmitter contract set at construction time.

+
+
+
+

productionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    bool productionMode
+
+

When true, governance is enabled and cannot be disabled. See switchToProductionMode.

+
+
+
+

timelockedCalls#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
    mapping(bytes4 => struct GovernedBase.TimelockedCall) timelockedCalls
+
+

List of pending timelocked governance calls.

+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/WNat/index.html b/apis/smart-contracts/WNat/index.html new file mode 100644 index 000000000..90368b6c1 --- /dev/null +++ b/apis/smart-contracts/WNat/index.html @@ -0,0 +1,6944 @@ + + + + + + + + + + + + + + + + + + WNat - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + + + +

WNat#

+
+

Source | Inherits from VPToken, IWNat

+
+
+

Wrapped native token.

+

This contract converts native tokens into WNAT (wrapped native) tokens and vice versa. +WNAT tokens are a one-to-one ERC20 +representation of native tokens, which are minted and burned as needed by this contract.

+

The wrapped versions of the native FLR and SGB tokens are called WFLR and WSGB respectively.

+

Besides the standard ERC20 operations, this contract supports +FTSO delegation and +governance vote delegation.

+

Code attribution: WETH9.

+
+
+

Events#

+
+

Approval#

+
+

Defined in IERC20 (Source).

+
+
+
event Approval(
+    address owner,
+    address spender,
+    uint256 value
+)
+
+

Emitted when the allowance of a spender for an owner is set by +a call to approve. value is the new allowance.

+
+
+
+

CreatedTotalSupplyCache#

+
+

Defined in CheckPointable (Docs, Source).

+
+
+
event CreatedTotalSupplyCache(
+    uint256 _blockNumber
+)
+
+

Emitted when a total supply cache entry is created. +Allows history cleaners to track total supply cache cleanup opportunities off-chain.

+
+
+
+

Deposit#

+
+

Defined in WNat (Docs, Source).

+
+
+
event Deposit(
+    address dst,
+    uint256 amount
+)
+
+

Emitted when tokens have been wrapped.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
dstaddressThe account that received the wrapped tokens.
amountuint256The amount that was wrapped.
+
+
+
+

GovernanceCallTimelocked#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event GovernanceCallTimelocked(
+    bytes4 selector,
+    uint256 allowedAfterTimestamp,
+    bytes encodedCall
+)
+
+

Emitted when a new governance call has been recorded and is now waiting for the time lock to expire.

+
+
+
+

GovernanceInitialised#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event GovernanceInitialised(
+    address initialGovernance
+)
+
+

Emitted when the governance address is initialized. +This address will be used until production mode is entered (see GovernedProductionModeEntered). +At that point the governance address is taken from GovernanceSettings.

+
+
+
+

GovernedProductionModeEntered#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event GovernedProductionModeEntered(
+    address governanceSettings
+)
+
+

Emitted when governance is enabled and the governance address cannot be changed anymore +(only through a network fork).

+
+
+
+

TimelockedGovernanceCallCanceled#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event TimelockedGovernanceCallCanceled(
+    bytes4 selector,
+    uint256 timestamp
+)
+
+

Emitted when a timelocked governance call is canceled before execution.

+
+
+
+

TimelockedGovernanceCallExecuted#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
event TimelockedGovernanceCallExecuted(
+    bytes4 selector,
+    uint256 timestamp
+)
+
+

Emitted when a timelocked governance call is executed.

+
+
+
+

Transfer#

+
+

Defined in IERC20 (Source).

+
+
+
event Transfer(
+    address from,
+    address to,
+    uint256 value
+)
+
+

Emitted when value tokens are moved from one account (from) to +another (to).

+

Note that value may be zero.

+
+
+
+

VotePowerContractChanged#

+
+

Defined in VPToken (Docs, Source).

+
+
+
event VotePowerContractChanged(
+    uint256 _contractType,
+    address _oldContractAddress,
+    address _newContractAddress
+)
+
+

Emitted when one of the vote power contracts is changed.

+

It is used to track the history of VPToken -> VPContract / GovernanceVotePower +associations (e.g. by external cleaners).

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_contractTypeuint2560 = Read VPContract, 1 = Write VPContract, 2 = Governance vote power.
_oldContractAddressaddressContract address before change.
_newContractAddressaddressContract address after change.
+
+
+
+

Withdrawal#

+
+

Defined in WNat (Docs, Source).

+
+
+
event Withdrawal(
+    address src,
+    uint256 amount
+)
+
+

Emitted when tokens have been unwrapped.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
srcaddressThe account that received the unwrapped tokens.
amountuint256The amount that was unwrapped.
+
+
+
+
+

Functions#

+
+

allowance#

+
+

Defined in IERC20 (Source).

+
+
+
function allowance(
+    address owner,
+    address spender
+) external view returns (
+    uint256);
+
+

Returns the remaining number of tokens that spender will be +allowed to spend on behalf of owner through transferFrom. This is +zero by default.

+

This value changes when approve or transferFrom are called.

+
+
+
+

approve#

+
+

Defined in IERC20 (Source).

+
+
+
function approve(
+    address spender,
+    uint256 amount
+) external returns (
+    bool);
+
+

Sets amount as the allowance of spender over the caller's tokens.

+

Returns a boolean value indicating whether the operation succeeded.

+

IMPORTANT: Beware that changing an allowance with this method brings the risk +that someone may use both the old and the new allowance by unfortunate +transaction ordering. One possible solution to mitigate this race +condition is to first reduce the spender's allowance to 0 and set the +desired value afterwards: +https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729

+

Emits an Approval event.

+
+
+
+

balanceHistoryCleanup#

+
+

Defined in CheckPointable (Docs, Source).

+
+
+
function balanceHistoryCleanup(
+    address _owner,
+    uint256 _count
+) external returns (
+    uint256);
+
+

Delete balance checkpoints that expired (i.e. are before cleanupBlockNumber). +Method can only be called from the cleanerContract (which may be a proxy to external cleaners).

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressbalance owner account address
_countuint256maximum number of checkpoints to delete
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256the number of checkpoints deleted
+
+
+
+

balanceOf#

+
+

Defined in IERC20 (Source).

+
+
+
function balanceOf(
+    address account
+) external view returns (
+    uint256);
+
+

Returns the amount of tokens owned by account.

+
+
+
+

balanceOfAt#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function balanceOfAt(
+    address _owner,
+    uint256 _blockNumber
+) public view returns (
+    uint256);
+
+

Queries the token balance of _owner at a specific _blockNumber.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address from which the balance will be retrieved.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256
+
+
+
+

batchDelegate#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function batchDelegate(
+    address[] _delegatees,
+    uint256[] _bips
+) external;
+
+

Undelegate all percentage delegations from the sender and then delegate corresponding + _bips percentage of voting power from the sender to each member of the _delegatees array.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_delegateesaddress[]The addresses of the new recipients.
_bipsuint256[]The percentages of voting power to be delegated expressed in basis points (1/100 of one percent). The sum of all _bips values must be at most 10000 (100%).
+
+
+
+

batchVotePowerOfAt#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function batchVotePowerOfAt(
+    address[] _owners,
+    uint256 _blockNumber
+) external view returns (
+    uint256[]);
+
+

Return the vote power for several addresses.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_ownersaddress[]The list of addresses to query.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256[]Array of vote power for each queried address.
+
+
+
+

cancelGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function cancelGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Cancel a timelocked governance call before it has been executed.

+

Only governance can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector.
+
+
+
+

cleanupBlockNumber#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function cleanupBlockNumber(
+) external view returns (
+    uint256);
+
+

Get the current cleanup block number set with setCleanupBlockNumber.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The currently set cleanup block number.
+
+
+
+

constructor#

+
+

Defined in WNat (Docs, Source).

+
+
+
constructor(
+    address _governance,
+    string _name,
+    string _symbol
+) public;
+
+

Construct an ERC20 token.

+
+
+
+

decimals#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function decimals(
+) public view returns (
+    uint8);
+
+

Returns the number of decimals used to get its user representation. +For example, if decimals equals 2, a balance of 505 tokens should +be displayed to a user as 5.05 (505 / 102).

+

Tokens usually opt for a value of 18, imitating the relationship between +Ether and wei. This is the default value returned by this function, unless +it's overridden.

+

NOTE: This information is only used for display purposes: it in +no way affects any of the arithmetic of the contract, including +balanceOf and transfer.

+

Should be compatible with ERC20 method.

+
+
+
+

delegate#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function delegate(
+    address _to,
+    uint256 _bips
+) external;
+
+

Delegate voting power to account _to from msg.sender, by percentage.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_toaddressThe address of the recipient.
_bipsuint256The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: every call resets the delegation value (and a value of 0 revokes all previous delegations).
+
+
+
+

delegateExplicit#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function delegateExplicit(
+    address _to,
+    uint256 _amount
+) external;
+
+

Explicitly delegate _amount voting power to account _to from msg.sender. +Compare with delegate which delegates by percentage.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_toaddressThe address of the recipient.
_amountuint256An explicit vote power amount to be delegated. Not cumulative: every call resets the delegation value (and a value of 0 revokes all previous delegations).
+
+
+
+

delegatesOf#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function delegatesOf(
+    address _owner
+) external view returns (
+    address[] _delegateAddresses,
+    uint256[] _bips,
+    uint256 _count,
+    uint256 _delegationMode);
+
+

Get the list of addresses to which _who is delegating, and their percentages.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddress
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_delegateAddressesaddress[]Positional array of addresses being delegated to.
_bipsuint256[]Positional array of delegation percents specified in basis points (1/100 of 1 percent). Each one matches the address in the same position in the _delegateAddresses array.
_countuint256The number of delegates.
_delegationModeuint256Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).
+
+
+
+

delegatesOfAt#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function delegatesOfAt(
+    address _owner,
+    uint256 _blockNumber
+) external view returns (
+    address[] _delegateAddresses,
+    uint256[] _bips,
+    uint256 _count,
+    uint256 _delegationMode);
+
+

Get the list of addresses to which _who is delegating, and their percentages, at the given block.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddress
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReturnsTypeDescription
_delegateAddressesaddress[]Positional array of addresses being delegated to.
_bipsuint256[]Positional array of delegation percents specified in basis points (1/100 of 1 percent). Each one matches the address in the same position in the _delegateAddresses array.
_countuint256The number of delegates.
_delegationModeuint256Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).
+
+
+
+

delegationModeOf#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function delegationModeOf(
+    address _who
+) external view returns (
+    uint256);
+
+

Get the delegation mode for account '_who'. This mode determines whether vote power is +allocated by percentage or by explicit amount. Once the delegation mode is set, +it can never be changed, even if all delegations are removed.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressThe address to get delegation mode.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).
+
+
+
+

deposit#

+
+

Defined in WNat (Docs, Source).

+
+
+
function deposit(
+) public payable;
+
+

Deposits native tokens and mints the same amount of WNAT tokens, +which are added to the msg.sender's balance. +This operation is commonly known as "wrapping".

+

Emits a Deposit event.

+
+
+
+

depositTo#

+
+

Defined in WNat (Docs, Source).

+
+
+
function depositTo(
+    address _recipient
+) external payable;
+
+

Deposits native tokens and mints the same amount of WNAT tokens, +which are added to _recipient's balance. +This operation is commonly known as "wrapping".

+

This is equivalent to using deposit followed by transfer.

+

Emits a Deposit event.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_recipientaddressThe address to receive the minted WNAT.
+
+
+
+

executeGovernanceCall#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function executeGovernanceCall(
+    bytes4 _selector
+) external;
+
+

Execute the timelocked governance calls once the timelock period expires.

+

Only executor can call this method.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_selectorbytes4The method selector (only one timelocked call per method is stored).
+
+
+
+

governance#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function governance(
+) public view returns (
+    address);
+
+

Returns the current effective governance address.

+
+
+
+

governanceVotePower#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function governanceVotePower(
+) external view returns (
+    contract IGovernanceVotePower);
+
+

When set, allows token owners to participate in governance voting +and delegate governance vote power.

+
+
+
+

name#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function name(
+) public view returns (
+    string);
+
+

Returns the name of the token.

+

Should be compatible with ERC20 method.

+
+
+
+

readVotePowerContract#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function readVotePowerContract(
+) external view returns (
+    contract IVPContractEvents);
+
+

Returns VPContract event interface used for read-only operations (view methods). +The only non-view method that might be called on it is revokeDelegationAt.

+

readVotePowerContract is almost always equal to writeVotePowerContract +except during an upgrade from one VPContract to a new version (which should happen +rarely or never and will be announced beforehand).

+

Do not call any methods on VPContract directly. +State changing methods are forbidden from direct calls. +All methods are exposed via VPToken. +This is the reason that this method returns IVPContractEvents. +Use it only for listening to events and revoking.

+
+
+
+

receive#

+
+

Defined in WNat (Docs, Source).

+
+
+
receive(
+) external payable;
+
+

A proxy for the deposit method.

+
+
+
+

revokeDelegationAt#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function revokeDelegationAt(
+    address _who,
+    uint256 _blockNumber
+) public;
+
+

Revoke all delegation from sender to _who at given block. +Only affects the reads via votePowerOfAtCached in the block _blockNumber. +Block _blockNumber must be in the past. +This method should be used only to prevent rogue delegate voting in the current voting block. +To stop delegating use delegate / delegateExplicit with value of 0 or undelegateAll / undelegateAllExplicit.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_whoaddressAddress of the delegatee.
_blockNumberuint256The block number at which to revoke delegation..
+
+
+
+

setCleanerContract#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function setCleanerContract(
+    address _cleanerContract
+) external;
+
+

Set the contract that is allowed to call history cleaning methods.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_cleanerContractaddressAddress of the cleanup contract. Usually this will be an instance of CleanupBlockNumberManager.
+
+
+
+

setCleanupBlockNumber#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function setCleanupBlockNumber(
+    uint256 _blockNumber
+) external;
+
+

Set the cleanup block number. +Historic data for the blocks before cleanupBlockNumber can be erased. +History before that block should never be used since it can be inconsistent. +In particular, cleanup block number must be lower than the current vote power block.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockNumberuint256The new cleanup block number.
+
+
+
+

setCleanupBlockNumberManager#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function setCleanupBlockNumberManager(
+    address _cleanupBlockNumberManager
+) external;
+
+

Set the contract that is allowed to set cleanupBlockNumber. +Usually this will be an instance of CleanupBlockNumberManager.

+
+
+
+

setGovernanceVotePower#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function setGovernanceVotePower(
+    contract IIGovernanceVotePower _governanceVotePower
+) external;
+
+

Sets new governance vote power contract that allows token owners to participate in governance voting +and delegate governance vote power.

+
+
+
+

setReadVpContract#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function setReadVpContract(
+    contract IIVPContract _vpContract
+) external;
+
+

Call from governance to set read VpContract on token, e.g. +vpToken.setReadVpContract(new VPContract(vpToken)).

+

Read VPContract must be set before any of the VPToken delegation or vote power reading methods are called, +otherwise they will revert.

+

NOTE: If readVpContract differs from writeVpContract all reads will be "frozen" and will not reflect +changes (not even revokes; they may or may not reflect balance transfers).

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_vpContractcontract IIVPContractRead vote power contract to be used by this token.
+
+
+
+

setWriteVpContract#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function setWriteVpContract(
+    contract IIVPContract _vpContract
+) external;
+
+

Call from governance to set write VpContract on token, e.g. +vpToken.setWriteVpContract(new VPContract(vpToken)).

+

Write VPContract must be set before any of the VPToken delegation modifying methods are called, +otherwise they will revert.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_vpContractcontract IIVPContractWrite vote power contract to be used by this token.
+
+
+
+

switchToProductionMode#

+
+

Defined in GovernedBase (Docs, Source).

+
+
+
function switchToProductionMode(
+) external;
+
+

Enter the production mode after all the initial governance settings have been set. +This enables timelocks and the governance can be obtained afterward by calling +governanceSettings.getGovernanceAddress(). +Emits GovernedProductionModeEntered.

+
+
+
+

symbol#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function symbol(
+) public view returns (
+    string);
+
+

Returns the symbol of the token, usually a shorter version of the name.

+

Should be compatible with ERC20 method.

+
+
+
+

totalSupply#

+
+

Defined in IERC20 (Source).

+
+
+
function totalSupply(
+) external view returns (
+    uint256);
+
+

Returns the amount of tokens in existence.

+
+
+
+

totalSupplyAt#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function totalSupplyAt(
+    uint256 _blockNumber
+) public view returns (
+    uint256);
+
+

Total amount of tokens at a specific _blockNumber.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockNumberuint256The block number when the _totalSupply is queried
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256
+
+
+
+

totalSupplyCacheCleanup#

+
+

Defined in CheckPointable (Docs, Source).

+
+
+
function totalSupplyCacheCleanup(
+    uint256 _blockNumber
+) external returns (
+    uint256);
+
+

Delete total supply cache entry that expired (i.e. is before cleanupBlockNumber). +Method can only be called from the cleanerContract (which may be a proxy to external cleaners).

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockNumberuint256the block number for which total supply value was cached
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256the number of cache entries deleted (always 0 or 1)
+
+
+
+

totalSupplyHistoryCleanup#

+
+

Defined in CheckPointable (Docs, Source).

+
+
+
function totalSupplyHistoryCleanup(
+    uint256 _count
+) external returns (
+    uint256);
+
+

Delete total supply checkpoints that expired (i.e. are before cleanupBlockNumber). +Method can only be called from the cleanerContract (which may be a proxy to external cleaners).

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_countuint256maximum number of checkpoints to delete
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256the number of checkpoints deleted
+
+
+
+

totalVotePower#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function totalVotePower(
+) external view returns (
+    uint256);
+
+

Get the current total vote power.

+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The current total vote power (sum of all accounts' vote power).
+
+
+
+

totalVotePowerAt#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function totalVotePowerAt(
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Get the total vote power at block _blockNumber.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The total vote power at the queried block (sum of all accounts' vote powers).
+
+
+
+

totalVotePowerAtCached#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function totalVotePowerAtCached(
+    uint256 _blockNumber
+) public returns (
+    uint256);
+
+

Get the total vote power at block _blockNumber using cache. + It tries to read the cached value and if it is not found, reads the actual value and stores it in the cache. + Can only be used if _blockNumber is in the past, otherwise reverts.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The total vote power at the queried block (sum of all accounts' vote powers).
+
+
+
+

transfer#

+
+

Defined in IERC20 (Source).

+
+
+
function transfer(
+    address recipient,
+    uint256 amount
+) external returns (
+    bool);
+
+

Moves amount tokens from the caller's account to recipient.

+

Returns a boolean value indicating whether the operation succeeded.

+

Emits a Transfer event.

+
+
+
+

transferFrom#

+
+

Defined in IERC20 (Source).

+
+
+
function transferFrom(
+    address sender,
+    address recipient,
+    uint256 amount
+) external returns (
+    bool);
+
+

Moves amount tokens from sender to recipient using the +allowance mechanism. amount is then deducted from the caller's +allowance.

+

Returns a boolean value indicating whether the operation succeeded.

+

Emits a Transfer event.

+
+
+
+

undelegateAll#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function undelegateAll(
+) external;
+
+

Undelegate all voting power of msg.sender. This effectively revokes all previous delegations. +Can only be used with percentage delegation. +Does not reset delegation mode back to NOT SET.

+
+
+
+

undelegateAllExplicit#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function undelegateAllExplicit(
+    address[] _delegateAddresses
+) external returns (
+    uint256 _remainingDelegation);
+
+

Undelegate all explicit vote power by amount of msg.sender. +Can only be used with explicit delegation. +Does not reset delegation mode back to NOT SET.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_delegateAddressesaddress[]Explicit delegation does not store delegatees' addresses, so the caller must supply them.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
_remainingDelegationuint256The amount still delegated (in case the list of delegates was incomplete).
+
+
+
+

undelegatedVotePowerOf#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function undelegatedVotePowerOf(
+    address _owner
+) external view returns (
+    uint256);
+
+

Compute the current undelegated vote power of the _owner account.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The unallocated vote power of _owner.
+
+
+
+

undelegatedVotePowerOfAt#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function undelegatedVotePowerOfAt(
+    address _owner,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Get the undelegated vote power of the _owner account at a given block number.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address to query.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The unallocated vote power of _owner.
+
+
+
+

votePowerFromTo#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function votePowerFromTo(
+    address _from,
+    address _to
+) external view returns (
+    uint256);
+
+

Get current delegated vote power from delegator _from to delegatee _to.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressAddress of delegator.
_toaddressAddress of delegatee.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256votePower The delegated vote power.
+
+
+
+

votePowerFromToAt#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function votePowerFromToAt(
+    address _from,
+    address _to,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Get delegated vote power from delegator _from to delegatee _to at _blockNumber.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_fromaddressAddress of delegator.
_toaddressAddress of delegatee.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256The delegated vote power.
+
+
+
+

votePowerOf#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function votePowerOf(
+    address _owner
+) external view returns (
+    uint256);
+
+

Get the current vote power of _owner.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Current vote power of _owner.
+
+
+
+

votePowerOfAt#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function votePowerOfAt(
+    address _owner,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Get the vote power of _owner at block _blockNumber

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address to query.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Vote power of _owner at block number _blockNumber.
+
+
+
+

votePowerOfAtCached#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function votePowerOfAtCached(
+    address _owner,
+    uint256 _blockNumber
+) public returns (
+    uint256);
+
+

Get the vote power of _owner at block _blockNumber using cache. + It tries to read the cached value and if it is not found, reads the actual value and stores it in the cache. + Can only be used if _blockNumber is in the past, otherwise reverts.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address to query.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Vote power of _owner at _blockNumber.
+
+
+
+

votePowerOfAtIgnoringRevocation#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function votePowerOfAtIgnoringRevocation(
+    address _owner,
+    uint256 _blockNumber
+) external view returns (
+    uint256);
+
+

Get the vote power of _owner at block _blockNumber, ignoring revocation information (and cache).

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address to query.
_blockNumberuint256The block number to query.
+ + + + + + + + + + + + + + + +
ReturnsTypeDescription
[0]uint256Vote power of _owner at block number _blockNumber. Result doesn't change if vote power is revoked.
+
+
+
+

withdraw#

+
+

Defined in WNat (Docs, Source).

+
+
+
function withdraw(
+    uint256 _amount
+) external;
+
+

Burns _amount of WNAT tokens from msg.sender's WNAT balance and +transfers the same amount of native tokens to msg.sender. +This operation is commonly known as "unwrapping".

+

Reverts if _amount is higher than msg.sender's WNAT balance.

+

Emits a Withdrawal event.

+ + + + + + + + + + + + + + + +
ParametersTypeDescription
_amountuint256The amount to withdraw.
+
+
+
+

withdrawFrom#

+
+

Defined in WNat (Docs, Source).

+
+
+
function withdrawFrom(
+    address _owner,
+    uint256 _amount
+) external;
+
+

Burns _amount of WNAT tokens from _owner's WNAT balance and +transfers the same amount of native tokens to msg.sender. +This operation is commonly known as "unwrapping".

+

msg.sender must have been authorized to withdraw from _owner's account +through ERC-20's approve mechanism.

+

Reverts if _amount is higher than _owners's WNAT balance or than +msg.sender's allowance over _owner's tokens.

+

Emits a Withdrawal event.

+ + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
_owneraddressThe address containing the tokens to withdraw.
_amountuint256The amount to withdraw.
+
+
+
+

writeVotePowerContract#

+
+

Defined in VPToken (Docs, Source).

+
+
+
function writeVotePowerContract(
+) external view returns (
+    contract IVPContractEvents);
+
+

Returns VPContract event interface used for state-changing operations (non-view methods). +The only non-view method that might be called on it is revokeDelegationAt.

+

writeVotePowerContract is almost always equal to readVotePowerContract, +except during upgrade from one VPContract to a new version (which should happen +rarely or never and will be announced beforehand). +In the case of an upgrade, writeVotePowerContract is replaced first to establish delegations. +After some period (e.g., after a reward epoch ends), readVotePowerContract is set equal to it.

+

Do not call any methods on VPContract directly. +State changing methods are forbidden from direct calls. +All are exposed via VPToken. +This is the reason that this method returns IVPContractEvents +Use it only for listening to events, delegating, and revoking.

+
+
+
+ +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/smart-contracts/index.html b/apis/smart-contracts/index.html new file mode 100644 index 000000000..a56bc81c2 --- /dev/null +++ b/apis/smart-contracts/index.html @@ -0,0 +1,4116 @@ + + + + + + + + + + + + + + + + + + Smart Contracts API - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + + +

Smart Contracts API#

+ + +

List of Flare smart contracts.

+

Contracts#

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescription
AddressUpdatableAbstract base class for contracts that depend on other contracts whose addresses can change.
AddressUpdaterKeeps track of the current address for all unique and special platform contracts.
CheckPointableCheck-Pointable ERC20 Behavior.
ClaimSetupManagerManages automation of operations related to reward claiming.
CleanupBlockNumberManagerToken history cleanup manager.
CloneFactorySimple clone contract factory.
DelegatableDelegatable ERC20 behavior.
FlareContractRegistryThe Flare contract registry.
FlareDaemonFlare Daemon contract.
FtsoFlare Time Series Oracle contract.
FtsoManagerFTSO Manager contract.
FtsoRegistryHandles registration of assets to the FTSO system.
FtsoRewardManagerHandles reward distribution and claiming related to the FTSO system.
GovernanceSettingsA special contract that holds the Flare governance address and its timelock.
GovernanceVotePowerContract managing governance vote power and its delegation.
GovernedDefines behaviors for governed contracts that must have a governor set at construction-time.
GovernedAndFlareDaemonizedBase class for contracts that are governed and triggered from the FlareDaemon.
GovernedAtGenesisDefines behaviors for governed contracts that have their governor set at genesis.
GovernedBaseAbstract base class that defines behaviors for governed contracts.
InflationRecognizes, authorizes, mints, and funds native tokens to Flare services that are rewardable through inflation.
PriceSubmitterReceives prices from FTSO data providers.
RevertErrorTrackingRevert error tracking contract.
VoterWhitelisterManager of the FTSO whitelist.
VPContractHelper contract handling all the vote power and delegation functionality for an associated VPToken.
VPTokenVote power token.
WNatWrapped native token.
+

Interfaces#

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescription
IClaimSetupManagerPublic interface for the ClaimSetupManager contract.
IFlareContractRegistryInterface for the FlareContractRegistry.
IFlareDaemonizeInterface for contracts that receive triggers from the FlareDaemon contract.
IFtsoInterface for each of the FTSO contracts that handles an asset.
IFtsoGenesisPortion of the IFtso interface that is available to contracts deployed at genesis.
IFtsoManagerInterface for the FtsoManager contract.
IFtsoManagerGenesisPortion of the IFtsoManager interface that is available to contracts deployed at genesis.
IFtsoRegistryInterface for the FtsoRegistry contract.
IFtsoRegistryGenesisPortion of the IFtsoRegistry interface that is available to contracts deployed at genesis.
IFtsoRewardManagerInterface for the FtsoRewardManager contract.
IGovernanceSettingsInterface for the GovernanceSettings that hold the Flare governance address and its timelock.
IGovernanceVotePowerInterface for contracts delegating their governance vote power.
IInflationGenesisPortion of the Inflation contract that is available to contracts deployed at genesis.
IPriceSubmitterInterface for the PriceSubmitter contract.
IVoterWhitelisterInterface for managers of the FTSO whitelist.
IVPContractEventsEvents interface for vote-power related operations.
IVPTokenVote power token interface.
IWNatWrapped native token interface.
+

Internal Interfaces#

+

For platform development, not application.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescription
IIAddressUpdatableInternal interface for contracts that depend on other contracts whose addresses can change.
IIAddressUpdaterInternal interface for AddressUpdater.
IIClaimSetupManagerInternal interface for the ClaimSetupManager contract.
IICleanableInternal interface for entities that can have their block history cleaned.
IIFtsoInternal interface for each of the FTSO contracts that handles an asset.
IIFtsoManagerInternal interface for the FtsoManager contract.
IIFtsoRegistryInternal interface for the FtsoRegistry contract.
IIFtsoRewardManagerInternal interface for the FtsoRewardManager.
IIGovernanceVotePowerInternal interface for contracts delegating their governance vote power.
IIInflationReceiverInternal interface for contracts that can receive inflation.
IIPriceSubmitterInternal interface for the PriceSubmitter contract.
IITokenPoolInternal interface for token pools.
IIVoterWhitelisterInternal interface for managers of the FTSO whitelist.
IIVPContractInternal interface for helper contracts handling functionality for an associated VPToken.
IIVPTokenVote power token internal interface.
+ + +
+
+ + + Last update: + 2023-10-04 + + +
+ + + + + + + + +
+ + + +
+
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/SC-CCCR-overlapped.png b/assets/SC-CCCR-overlapped.png new file mode 100644 index 000000000..f4d325750 Binary files /dev/null and b/assets/SC-CCCR-overlapped.png differ diff --git a/assets/SC-CCCR.png b/assets/SC-CCCR.png new file mode 100644 index 000000000..ba22a7f01 Binary files /dev/null and b/assets/SC-CCCR.png differ diff --git a/assets/SC-architecture.png b/assets/SC-architecture.png new file mode 100644 index 000000000..43bd163e3 Binary files /dev/null and b/assets/SC-architecture.png differ diff --git a/assets/SC-attestation-provider.png b/assets/SC-attestation-provider.png new file mode 100644 index 000000000..77854145e Binary files /dev/null and b/assets/SC-attestation-provider.png differ diff --git a/assets/SC-branching-resolution-1.png b/assets/SC-branching-resolution-1.png new file mode 100644 index 000000000..0894bad44 Binary files /dev/null and b/assets/SC-branching-resolution-1.png differ diff --git a/assets/SC-branching-resolution-2.png b/assets/SC-branching-resolution-2.png new file mode 100644 index 000000000..11ce3cea8 Binary files /dev/null and b/assets/SC-branching-resolution-2.png differ diff --git a/assets/SC-branching.png b/assets/SC-branching.png new file mode 100644 index 000000000..8c1852275 Binary files /dev/null and b/assets/SC-branching.png differ diff --git a/assets/SC-intro.png b/assets/SC-intro.png new file mode 100644 index 000000000..e03f93f89 Binary files /dev/null and b/assets/SC-intro.png differ diff --git a/assets/SC-local-AP-1.png b/assets/SC-local-AP-1.png new file mode 100644 index 000000000..ad756d5e8 Binary files /dev/null and b/assets/SC-local-AP-1.png differ diff --git a/assets/SC-local-AP-2.png b/assets/SC-local-AP-2.png new file mode 100644 index 000000000..dd4646c1a Binary files /dev/null and b/assets/SC-local-AP-2.png differ diff --git a/assets/SC-proof-unpacking.png b/assets/SC-proof-unpacking.png new file mode 100644 index 000000000..fb33817ac Binary files /dev/null and b/assets/SC-proof-unpacking.png differ diff --git a/assets/block-explorer-balance.png b/assets/block-explorer-balance.png new file mode 100644 index 000000000..44ff1b017 Binary files /dev/null and b/assets/block-explorer-balance.png differ diff --git a/assets/block-explorer-blocks.png b/assets/block-explorer-blocks.png new file mode 100644 index 000000000..9fae2b343 Binary files /dev/null and b/assets/block-explorer-blocks.png differ diff --git a/assets/block-explorer-current-epoch.png b/assets/block-explorer-current-epoch.png new file mode 100644 index 000000000..8491731c3 Binary files /dev/null and b/assets/block-explorer-current-epoch.png differ diff --git a/assets/block-explorer-dashboard.png b/assets/block-explorer-dashboard.png new file mode 100644 index 000000000..14d3711cc Binary files /dev/null and b/assets/block-explorer-dashboard.png differ diff --git a/assets/block-explorer-history.png b/assets/block-explorer-history.png new file mode 100644 index 000000000..2fdbfca0c Binary files /dev/null and b/assets/block-explorer-history.png differ diff --git a/assets/block-explorer-internal-tx.png b/assets/block-explorer-internal-tx.png new file mode 100644 index 000000000..ef5069f8e Binary files /dev/null and b/assets/block-explorer-internal-tx.png differ diff --git a/assets/block-explorer-internal.png b/assets/block-explorer-internal.png new file mode 100644 index 000000000..6d530e5d8 Binary files /dev/null and b/assets/block-explorer-internal.png differ diff --git a/assets/block-explorer-logs.png b/assets/block-explorer-logs.png new file mode 100644 index 000000000..5427729be Binary files /dev/null and b/assets/block-explorer-logs.png differ diff --git a/assets/block-explorer-raw-trace.png b/assets/block-explorer-raw-trace.png new file mode 100644 index 000000000..d9bcf72ea Binary files /dev/null and b/assets/block-explorer-raw-trace.png differ diff --git a/assets/block-explorer-read-wallet.png b/assets/block-explorer-read-wallet.png new file mode 100644 index 000000000..1a84dd067 Binary files /dev/null and b/assets/block-explorer-read-wallet.png differ diff --git a/assets/block-explorer-tokens.png b/assets/block-explorer-tokens.png new file mode 100644 index 000000000..92593b3e6 Binary files /dev/null and b/assets/block-explorer-tokens.png differ diff --git a/assets/block-explorer-transaction-types.png b/assets/block-explorer-transaction-types.png new file mode 100644 index 000000000..76faa56fe Binary files /dev/null and b/assets/block-explorer-transaction-types.png differ diff --git a/assets/block-explorer-transactions.png b/assets/block-explorer-transactions.png new file mode 100644 index 000000000..2e69b334e Binary files /dev/null and b/assets/block-explorer-transactions.png differ diff --git a/assets/block-explorer-transfers.png b/assets/block-explorer-transfers.png new file mode 100644 index 000000000..5f527f510 Binary files /dev/null and b/assets/block-explorer-transfers.png differ diff --git a/assets/block-explorer-tx-details.png b/assets/block-explorer-tx-details.png new file mode 100644 index 000000000..6b83dbdf2 Binary files /dev/null and b/assets/block-explorer-tx-details.png differ diff --git a/assets/block-explorer-tx-hash.png b/assets/block-explorer-tx-hash.png new file mode 100644 index 000000000..1fc08873f Binary files /dev/null and b/assets/block-explorer-tx-hash.png differ diff --git a/assets/block-explorer-vp-snapshot.png b/assets/block-explorer-vp-snapshot.png new file mode 100644 index 000000000..ae71129c8 Binary files /dev/null and b/assets/block-explorer-vp-snapshot.png differ diff --git a/assets/block-explorer-write-wallet.png b/assets/block-explorer-write-wallet.png new file mode 100644 index 000000000..b1892b43b Binary files /dev/null and b/assets/block-explorer-write-wallet.png differ diff --git a/assets/collusion-tool-dashboard.png b/assets/collusion-tool-dashboard.png new file mode 100644 index 000000000..d01397e52 Binary files /dev/null and b/assets/collusion-tool-dashboard.png differ diff --git a/assets/collusion-tool-weighted.png b/assets/collusion-tool-weighted.png new file mode 100644 index 000000000..e073d6d82 Binary files /dev/null and b/assets/collusion-tool-weighted.png differ diff --git a/assets/delegation-portal-connect.png b/assets/delegation-portal-connect.png new file mode 100644 index 000000000..1b7aadb0d Binary files /dev/null and b/assets/delegation-portal-connect.png differ diff --git a/assets/delegation-portal-main.png b/assets/delegation-portal-main.png new file mode 100644 index 000000000..477d06485 Binary files /dev/null and b/assets/delegation-portal-main.png differ diff --git a/assets/delegation-portal-providers.png b/assets/delegation-portal-providers.png new file mode 100644 index 000000000..a298ef44b Binary files /dev/null and b/assets/delegation-portal-providers.png differ diff --git a/assets/dev/foundry1.png b/assets/dev/foundry1.png new file mode 100644 index 000000000..734e54459 Binary files /dev/null and b/assets/dev/foundry1.png differ diff --git a/assets/dev/foundry2.png b/assets/dev/foundry2.png new file mode 100644 index 000000000..ff10b978f Binary files /dev/null and b/assets/dev/foundry2.png differ diff --git a/assets/dev/foundry3.png b/assets/dev/foundry3.png new file mode 100644 index 000000000..24e20866a Binary files /dev/null and b/assets/dev/foundry3.png differ diff --git a/assets/dev/hardhat1.png b/assets/dev/hardhat1.png new file mode 100644 index 000000000..70ce58cf6 Binary files /dev/null and b/assets/dev/hardhat1.png differ diff --git a/assets/dev/hardhat2.png b/assets/dev/hardhat2.png new file mode 100644 index 000000000..48947fef9 Binary files /dev/null and b/assets/dev/hardhat2.png differ diff --git a/assets/dev/remix1.png b/assets/dev/remix1.png new file mode 100644 index 000000000..c7eade41b Binary files /dev/null and b/assets/dev/remix1.png differ diff --git a/assets/dev/remix2.png b/assets/dev/remix2.png new file mode 100644 index 000000000..dd0e809e7 Binary files /dev/null and b/assets/dev/remix2.png differ diff --git a/assets/dev/remix3.png b/assets/dev/remix3.png new file mode 100644 index 000000000..94a8ae239 Binary files /dev/null and b/assets/dev/remix3.png differ diff --git a/assets/dev/remix4.png b/assets/dev/remix4.png new file mode 100644 index 000000000..222d45980 Binary files /dev/null and b/assets/dev/remix4.png differ diff --git a/assets/dev/remix5.png b/assets/dev/remix5.png new file mode 100644 index 000000000..58ba1ecdf Binary files /dev/null and b/assets/dev/remix5.png differ diff --git a/assets/dev/truffle1.png b/assets/dev/truffle1.png new file mode 100644 index 000000000..bac369aab Binary files /dev/null and b/assets/dev/truffle1.png differ diff --git a/assets/dev/truffle2.png b/assets/dev/truffle2.png new file mode 100644 index 000000000..6e2a3934f Binary files /dev/null and b/assets/dev/truffle2.png differ diff --git a/assets/dev/truffle3.png b/assets/dev/truffle3.png new file mode 100644 index 000000000..06ce14aab Binary files /dev/null and b/assets/dev/truffle3.png differ diff --git a/assets/dev/truffle4.png b/assets/dev/truffle4.png new file mode 100644 index 000000000..a0784463c Binary files /dev/null and b/assets/dev/truffle4.png differ diff --git a/assets/exchanges-deposits.png b/assets/exchanges-deposits.png new file mode 100644 index 000000000..684a68c78 Binary files /dev/null and b/assets/exchanges-deposits.png differ diff --git a/assets/exchanges-general.png b/assets/exchanges-general.png new file mode 100644 index 000000000..0ded26231 Binary files /dev/null and b/assets/exchanges-general.png differ diff --git a/assets/exchanges-withdrawals.png b/assets/exchanges-withdrawals.png new file mode 100644 index 000000000..85773752b Binary files /dev/null and b/assets/exchanges-withdrawals.png differ diff --git a/assets/executor-portal-claim-rewards-detail.png b/assets/executor-portal-claim-rewards-detail.png new file mode 100644 index 000000000..e57d36bc4 Binary files /dev/null and b/assets/executor-portal-claim-rewards-detail.png differ diff --git a/assets/executor-portal-confirmed.png b/assets/executor-portal-confirmed.png new file mode 100644 index 000000000..a57061732 Binary files /dev/null and b/assets/executor-portal-confirmed.png differ diff --git a/assets/executor-portal-main.png b/assets/executor-portal-main.png new file mode 100644 index 000000000..9cf39340a Binary files /dev/null and b/assets/executor-portal-main.png differ diff --git a/assets/executor-portal-preset.png b/assets/executor-portal-preset.png new file mode 100644 index 000000000..63a8664fc Binary files /dev/null and b/assets/executor-portal-preset.png differ diff --git a/assets/executor-process-with.png b/assets/executor-process-with.png new file mode 100644 index 000000000..81083afe4 Binary files /dev/null and b/assets/executor-process-with.png differ diff --git a/assets/executor-process-without.png b/assets/executor-process-without.png new file mode 100644 index 000000000..52f6dace7 Binary files /dev/null and b/assets/executor-process-without.png differ diff --git a/assets/favicon.png b/assets/favicon.png new file mode 100644 index 000000000..8bdd138a7 Binary files /dev/null and b/assets/favicon.png differ diff --git a/assets/flare-network-types.png b/assets/flare-network-types.png new file mode 100644 index 000000000..056f7cfb3 Binary files /dev/null and b/assets/flare-network-types.png differ diff --git a/assets/flaredrop-average-of-3-weeks.png b/assets/flaredrop-average-of-3-weeks.png new file mode 100644 index 000000000..8be36eaae Binary files /dev/null and b/assets/flaredrop-average-of-3-weeks.png differ diff --git a/assets/flaredrop-claim-confirmation.png b/assets/flaredrop-claim-confirmation.png new file mode 100644 index 000000000..c02893875 Binary files /dev/null and b/assets/flaredrop-claim-confirmation.png differ diff --git a/assets/flaredrop-claim-distribution.png b/assets/flaredrop-claim-distribution.png new file mode 100644 index 000000000..cf20d78f5 Binary files /dev/null and b/assets/flaredrop-claim-distribution.png differ diff --git a/assets/flaredrop-distribution-dates.png b/assets/flaredrop-distribution-dates.png new file mode 100644 index 000000000..fe06bc75f Binary files /dev/null and b/assets/flaredrop-distribution-dates.png differ diff --git a/assets/ftso-delegation.png b/assets/ftso-delegation.png new file mode 100644 index 000000000..424cb29d6 Binary files /dev/null and b/assets/ftso-delegation.png differ diff --git a/assets/ftso-price.png b/assets/ftso-price.png new file mode 100644 index 000000000..81b9e6fe2 Binary files /dev/null and b/assets/ftso-price.png differ diff --git a/assets/ftso-summary.png b/assets/ftso-summary.png new file mode 100644 index 000000000..81ac99412 Binary files /dev/null and b/assets/ftso-summary.png differ diff --git a/assets/ftso-system.png b/assets/ftso-system.png new file mode 100644 index 000000000..eb18e31e9 Binary files /dev/null and b/assets/ftso-system.png differ diff --git a/assets/ftso-weight.png b/assets/ftso-weight.png new file mode 100644 index 000000000..b1380d215 Binary files /dev/null and b/assets/ftso-weight.png differ diff --git a/assets/ftso-workflow.png b/assets/ftso-workflow.png new file mode 100644 index 000000000..806ddd93d Binary files /dev/null and b/assets/ftso-workflow.png differ diff --git a/assets/gov-changes-in-number-of-votes.png b/assets/gov-changes-in-number-of-votes.png new file mode 100644 index 000000000..1b8a16a32 Binary files /dev/null and b/assets/gov-changes-in-number-of-votes.png differ diff --git a/assets/gov-voting-process.png b/assets/gov-voting-process.png new file mode 100644 index 000000000..a24d51569 Binary files /dev/null and b/assets/gov-voting-process.png differ diff --git a/assets/images/favicon.png b/assets/images/favicon.png new file mode 100644 index 000000000..1cf13b9f9 Binary files /dev/null and b/assets/images/favicon.png differ diff --git a/assets/javascripts/bundle.9c69f0bc.min.js b/assets/javascripts/bundle.9c69f0bc.min.js new file mode 100644 index 000000000..91fc7b5d0 --- /dev/null +++ b/assets/javascripts/bundle.9c69f0bc.min.js @@ -0,0 +1,29 @@ +"use strict";(()=>{var oa=Object.create;var xr=Object.defineProperty;var ia=Object.getOwnPropertyDescriptor;var aa=Object.getOwnPropertyNames,kt=Object.getOwnPropertySymbols,sa=Object.getPrototypeOf,Sr=Object.prototype.hasOwnProperty,sn=Object.prototype.propertyIsEnumerable;var an=(e,t,r)=>t in e?xr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,H=(e,t)=>{for(var r in t||(t={}))Sr.call(t,r)&&an(e,r,t[r]);if(kt)for(var r of kt(t))sn.call(t,r)&&an(e,r,t[r]);return e};var cn=(e,t)=>{var r={};for(var n in e)Sr.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(e!=null&&kt)for(var n of kt(e))t.indexOf(n)<0&&sn.call(e,n)&&(r[n]=e[n]);return r};var yt=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var ca=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of aa(t))!Sr.call(e,o)&&o!==r&&xr(e,o,{get:()=>t[o],enumerable:!(n=ia(t,o))||n.enumerable});return e};var Ye=(e,t,r)=>(r=e!=null?oa(sa(e)):{},ca(t||!e||!e.__esModule?xr(r,"default",{value:e,enumerable:!0}):r,e));var fn=yt((wr,un)=>{(function(e,t){typeof wr=="object"&&typeof un!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(wr,function(){"use strict";function e(r){var n=!0,o=!1,i=null,a={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function s(O){return!!(O&&O!==document&&O.nodeName!=="HTML"&&O.nodeName!=="BODY"&&"classList"in O&&"contains"in O.classList)}function c(O){var Ue=O.type,He=O.tagName;return!!(He==="INPUT"&&a[Ue]&&!O.readOnly||He==="TEXTAREA"&&!O.readOnly||O.isContentEditable)}function u(O){O.classList.contains("focus-visible")||(O.classList.add("focus-visible"),O.setAttribute("data-focus-visible-added",""))}function f(O){!O.hasAttribute("data-focus-visible-added")||(O.classList.remove("focus-visible"),O.removeAttribute("data-focus-visible-added"))}function p(O){O.metaKey||O.altKey||O.ctrlKey||(s(r.activeElement)&&u(r.activeElement),n=!0)}function l(O){n=!1}function d(O){!s(O.target)||(n||c(O.target))&&u(O.target)}function h(O){!s(O.target)||(O.target.classList.contains("focus-visible")||O.target.hasAttribute("data-focus-visible-added"))&&(o=!0,window.clearTimeout(i),i=window.setTimeout(function(){o=!1},100),f(O.target))}function b(O){document.visibilityState==="hidden"&&(o&&(n=!0),U())}function U(){document.addEventListener("mousemove",W),document.addEventListener("mousedown",W),document.addEventListener("mouseup",W),document.addEventListener("pointermove",W),document.addEventListener("pointerdown",W),document.addEventListener("pointerup",W),document.addEventListener("touchmove",W),document.addEventListener("touchstart",W),document.addEventListener("touchend",W)}function G(){document.removeEventListener("mousemove",W),document.removeEventListener("mousedown",W),document.removeEventListener("mouseup",W),document.removeEventListener("pointermove",W),document.removeEventListener("pointerdown",W),document.removeEventListener("pointerup",W),document.removeEventListener("touchmove",W),document.removeEventListener("touchstart",W),document.removeEventListener("touchend",W)}function W(O){O.target.nodeName&&O.target.nodeName.toLowerCase()==="html"||(n=!1,G())}document.addEventListener("keydown",p,!0),document.addEventListener("mousedown",l,!0),document.addEventListener("pointerdown",l,!0),document.addEventListener("touchstart",l,!0),document.addEventListener("visibilitychange",b,!0),U(),r.addEventListener("focus",d,!0),r.addEventListener("blur",h,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var pn=yt(Er=>{(function(e){var t=function(){try{return!!Symbol.iterator}catch(u){return!1}},r=t(),n=function(u){var f={next:function(){var p=u.shift();return{done:p===void 0,value:p}}};return r&&(f[Symbol.iterator]=function(){return f}),f},o=function(u){return encodeURIComponent(u).replace(/%20/g,"+")},i=function(u){return decodeURIComponent(String(u).replace(/\+/g," "))},a=function(){var u=function(p){Object.defineProperty(this,"_entries",{writable:!0,value:{}});var l=typeof p;if(l!=="undefined")if(l==="string")p!==""&&this._fromString(p);else if(p instanceof u){var d=this;p.forEach(function(G,W){d.append(W,G)})}else if(p!==null&&l==="object")if(Object.prototype.toString.call(p)==="[object Array]")for(var h=0;hd[0]?1:0}),u._entries&&(u._entries={});for(var p=0;p1?i(d[1]):"")}})})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:Er);(function(e){var t=function(){try{var o=new e.URL("b","http://a");return o.pathname="c d",o.href==="http://a/c%20d"&&o.searchParams}catch(i){return!1}},r=function(){var o=e.URL,i=function(c,u){typeof c!="string"&&(c=String(c)),u&&typeof u!="string"&&(u=String(u));var f=document,p;if(u&&(e.location===void 0||u!==e.location.href)){u=u.toLowerCase(),f=document.implementation.createHTMLDocument(""),p=f.createElement("base"),p.href=u,f.head.appendChild(p);try{if(p.href.indexOf(u)!==0)throw new Error(p.href)}catch(O){throw new Error("URL unable to set base "+u+" due to "+O)}}var l=f.createElement("a");l.href=c,p&&(f.body.appendChild(l),l.href=l.href);var d=f.createElement("input");if(d.type="url",d.value=c,l.protocol===":"||!/:/.test(l.href)||!d.checkValidity()&&!u)throw new TypeError("Invalid URL");Object.defineProperty(this,"_anchorElement",{value:l});var h=new e.URLSearchParams(this.search),b=!0,U=!0,G=this;["append","delete","set"].forEach(function(O){var Ue=h[O];h[O]=function(){Ue.apply(h,arguments),b&&(U=!1,G.search=h.toString(),U=!0)}}),Object.defineProperty(this,"searchParams",{value:h,enumerable:!0});var W=void 0;Object.defineProperty(this,"_updateSearchParams",{enumerable:!1,configurable:!1,writable:!1,value:function(){this.search!==W&&(W=this.search,U&&(b=!1,this.searchParams._fromString(this.search),b=!0))}})},a=i.prototype,s=function(c){Object.defineProperty(a,c,{get:function(){return this._anchorElement[c]},set:function(u){this._anchorElement[c]=u},enumerable:!0})};["hash","host","hostname","port","protocol"].forEach(function(c){s(c)}),Object.defineProperty(a,"search",{get:function(){return this._anchorElement.search},set:function(c){this._anchorElement.search=c,this._updateSearchParams()},enumerable:!0}),Object.defineProperties(a,{toString:{get:function(){var c=this;return function(){return c.href}}},href:{get:function(){return this._anchorElement.href.replace(/\?$/,"")},set:function(c){this._anchorElement.href=c,this._updateSearchParams()},enumerable:!0},pathname:{get:function(){return this._anchorElement.pathname.replace(/(^\/?)/,"/")},set:function(c){this._anchorElement.pathname=c},enumerable:!0},origin:{get:function(){var c={"http:":80,"https:":443,"ftp:":21}[this._anchorElement.protocol],u=this._anchorElement.port!=c&&this._anchorElement.port!=="";return this._anchorElement.protocol+"//"+this._anchorElement.hostname+(u?":"+this._anchorElement.port:"")},enumerable:!0},password:{get:function(){return""},set:function(c){},enumerable:!0},username:{get:function(){return""},set:function(c){},enumerable:!0}}),i.createObjectURL=function(c){return o.createObjectURL.apply(o,arguments)},i.revokeObjectURL=function(c){return o.revokeObjectURL.apply(o,arguments)},e.URL=i};if(t()||r(),e.location!==void 0&&!("origin"in e.location)){var n=function(){return e.location.protocol+"//"+e.location.hostname+(e.location.port?":"+e.location.port:"")};try{Object.defineProperty(e.location,"origin",{get:n,enumerable:!0})}catch(o){setInterval(function(){e.location.origin=n()},100)}}})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:Er)});var kn=yt((zs,It)=>{/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */var ln,mn,dn,hn,bn,vn,gn,yn,xn,Ht,Or,Sn,wn,En,rt,On,_n,Tn,Mn,Ln,An,Cn,Rn,Pt;(function(e){var t=typeof global=="object"?global:typeof self=="object"?self:typeof this=="object"?this:{};typeof define=="function"&&define.amd?define("tslib",["exports"],function(n){e(r(t,r(n)))}):typeof It=="object"&&typeof It.exports=="object"?e(r(t,r(It.exports))):e(r(t));function r(n,o){return n!==t&&(typeof Object.create=="function"?Object.defineProperty(n,"__esModule",{value:!0}):n.__esModule=!0),function(i,a){return n[i]=o?o(i,a):a}}})(function(e){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,o){n.__proto__=o}||function(n,o){for(var i in o)Object.prototype.hasOwnProperty.call(o,i)&&(n[i]=o[i])};ln=function(n,o){if(typeof o!="function"&&o!==null)throw new TypeError("Class extends value "+String(o)+" is not a constructor or null");t(n,o);function i(){this.constructor=n}n.prototype=o===null?Object.create(o):(i.prototype=o.prototype,new i)},mn=Object.assign||function(n){for(var o,i=1,a=arguments.length;i=0;f--)(u=n[f])&&(c=(s<3?u(c):s>3?u(o,i,c):u(o,i))||c);return s>3&&c&&Object.defineProperty(o,i,c),c},bn=function(n,o){return function(i,a){o(i,a,n)}},vn=function(n,o){if(typeof Reflect=="object"&&typeof Reflect.metadata=="function")return Reflect.metadata(n,o)},gn=function(n,o,i,a){function s(c){return c instanceof i?c:new i(function(u){u(c)})}return new(i||(i=Promise))(function(c,u){function f(d){try{l(a.next(d))}catch(h){u(h)}}function p(d){try{l(a.throw(d))}catch(h){u(h)}}function l(d){d.done?c(d.value):s(d.value).then(f,p)}l((a=a.apply(n,o||[])).next())})},yn=function(n,o){var i={label:0,sent:function(){if(c[0]&1)throw c[1];return c[1]},trys:[],ops:[]},a,s,c,u;return u={next:f(0),throw:f(1),return:f(2)},typeof Symbol=="function"&&(u[Symbol.iterator]=function(){return this}),u;function f(l){return function(d){return p([l,d])}}function p(l){if(a)throw new TypeError("Generator is already executing.");for(;i;)try{if(a=1,s&&(c=l[0]&2?s.return:l[0]?s.throw||((c=s.return)&&c.call(s),0):s.next)&&!(c=c.call(s,l[1])).done)return c;switch(s=0,c&&(l=[l[0]&2,c.value]),l[0]){case 0:case 1:c=l;break;case 4:return i.label++,{value:l[1],done:!1};case 5:i.label++,s=l[1],l=[0];continue;case 7:l=i.ops.pop(),i.trys.pop();continue;default:if(c=i.trys,!(c=c.length>0&&c[c.length-1])&&(l[0]===6||l[0]===2)){i=0;continue}if(l[0]===3&&(!c||l[1]>c[0]&&l[1]=n.length&&(n=void 0),{value:n&&n[a++],done:!n}}};throw new TypeError(o?"Object is not iterable.":"Symbol.iterator is not defined.")},Or=function(n,o){var i=typeof Symbol=="function"&&n[Symbol.iterator];if(!i)return n;var a=i.call(n),s,c=[],u;try{for(;(o===void 0||o-- >0)&&!(s=a.next()).done;)c.push(s.value)}catch(f){u={error:f}}finally{try{s&&!s.done&&(i=a.return)&&i.call(a)}finally{if(u)throw u.error}}return c},Sn=function(){for(var n=[],o=0;o1||f(b,U)})})}function f(b,U){try{p(a[b](U))}catch(G){h(c[0][3],G)}}function p(b){b.value instanceof rt?Promise.resolve(b.value.v).then(l,d):h(c[0][2],b)}function l(b){f("next",b)}function d(b){f("throw",b)}function h(b,U){b(U),c.shift(),c.length&&f(c[0][0],c[0][1])}},_n=function(n){var o,i;return o={},a("next"),a("throw",function(s){throw s}),a("return"),o[Symbol.iterator]=function(){return this},o;function a(s,c){o[s]=n[s]?function(u){return(i=!i)?{value:rt(n[s](u)),done:s==="return"}:c?c(u):u}:c}},Tn=function(n){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var o=n[Symbol.asyncIterator],i;return o?o.call(n):(n=typeof Ht=="function"?Ht(n):n[Symbol.iterator](),i={},a("next"),a("throw"),a("return"),i[Symbol.asyncIterator]=function(){return this},i);function a(c){i[c]=n[c]&&function(u){return new Promise(function(f,p){u=n[c](u),s(f,p,u.done,u.value)})}}function s(c,u,f,p){Promise.resolve(p).then(function(l){c({value:l,done:f})},u)}},Mn=function(n,o){return Object.defineProperty?Object.defineProperty(n,"raw",{value:o}):n.raw=o,n};var r=Object.create?function(n,o){Object.defineProperty(n,"default",{enumerable:!0,value:o})}:function(n,o){n.default=o};Ln=function(n){if(n&&n.__esModule)return n;var o={};if(n!=null)for(var i in n)i!=="default"&&Object.prototype.hasOwnProperty.call(n,i)&&Pt(o,n,i);return r(o,n),o},An=function(n){return n&&n.__esModule?n:{default:n}},Cn=function(n,o,i,a){if(i==="a"&&!a)throw new TypeError("Private accessor was defined without a getter");if(typeof o=="function"?n!==o||!a:!o.has(n))throw new TypeError("Cannot read private member from an object whose class did not declare it");return i==="m"?a:i==="a"?a.call(n):a?a.value:o.get(n)},Rn=function(n,o,i,a,s){if(a==="m")throw new TypeError("Private method is not writable");if(a==="a"&&!s)throw new TypeError("Private accessor was defined without a setter");if(typeof o=="function"?n!==o||!s:!o.has(n))throw new TypeError("Cannot write private member to an object whose class did not declare it");return a==="a"?s.call(n,i):s?s.value=i:o.set(n,i),i},e("__extends",ln),e("__assign",mn),e("__rest",dn),e("__decorate",hn),e("__param",bn),e("__metadata",vn),e("__awaiter",gn),e("__generator",yn),e("__exportStar",xn),e("__createBinding",Pt),e("__values",Ht),e("__read",Or),e("__spread",Sn),e("__spreadArrays",wn),e("__spreadArray",En),e("__await",rt),e("__asyncGenerator",On),e("__asyncDelegator",_n),e("__asyncValues",Tn),e("__makeTemplateObject",Mn),e("__importStar",Ln),e("__importDefault",An),e("__classPrivateFieldGet",Cn),e("__classPrivateFieldSet",Rn)})});var Kr=yt((At,Yr)=>{/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */(function(t,r){typeof At=="object"&&typeof Yr=="object"?Yr.exports=r():typeof define=="function"&&define.amd?define([],r):typeof At=="object"?At.ClipboardJS=r():t.ClipboardJS=r()})(At,function(){return function(){var e={686:function(n,o,i){"use strict";i.d(o,{default:function(){return na}});var a=i(279),s=i.n(a),c=i(370),u=i.n(c),f=i(817),p=i.n(f);function l(j){try{return document.execCommand(j)}catch(_){return!1}}var d=function(_){var E=p()(_);return l("cut"),E},h=d;function b(j){var _=document.documentElement.getAttribute("dir")==="rtl",E=document.createElement("textarea");E.style.fontSize="12pt",E.style.border="0",E.style.padding="0",E.style.margin="0",E.style.position="absolute",E.style[_?"right":"left"]="-9999px";var k=window.pageYOffset||document.documentElement.scrollTop;return E.style.top="".concat(k,"px"),E.setAttribute("readonly",""),E.value=j,E}var U=function(_,E){var k=b(_);E.container.appendChild(k);var I=p()(k);return l("copy"),k.remove(),I},G=function(_){var E=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},k="";return typeof _=="string"?k=U(_,E):_ instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(_==null?void 0:_.type)?k=U(_.value,E):(k=p()(_),l("copy")),k},W=G;function O(j){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?O=function(E){return typeof E}:O=function(E){return E&&typeof Symbol=="function"&&E.constructor===Symbol&&E!==Symbol.prototype?"symbol":typeof E},O(j)}var Ue=function(){var _=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},E=_.action,k=E===void 0?"copy":E,I=_.container,Q=_.target,Oe=_.text;if(k!=="copy"&&k!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(Q!==void 0)if(Q&&O(Q)==="object"&&Q.nodeType===1){if(k==="copy"&&Q.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(k==="cut"&&(Q.hasAttribute("readonly")||Q.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(Oe)return W(Oe,{container:I});if(Q)return k==="cut"?h(Q):W(Q,{container:I})},He=Ue;function Ce(j){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?Ce=function(E){return typeof E}:Ce=function(E){return E&&typeof Symbol=="function"&&E.constructor===Symbol&&E!==Symbol.prototype?"symbol":typeof E},Ce(j)}function Bi(j,_){if(!(j instanceof _))throw new TypeError("Cannot call a class as a function")}function on(j,_){for(var E=0;E<_.length;E++){var k=_[E];k.enumerable=k.enumerable||!1,k.configurable=!0,"value"in k&&(k.writable=!0),Object.defineProperty(j,k.key,k)}}function Gi(j,_,E){return _&&on(j.prototype,_),E&&on(j,E),j}function Ji(j,_){if(typeof _!="function"&&_!==null)throw new TypeError("Super expression must either be null or a function");j.prototype=Object.create(_&&_.prototype,{constructor:{value:j,writable:!0,configurable:!0}}),_&&gr(j,_)}function gr(j,_){return gr=Object.setPrototypeOf||function(k,I){return k.__proto__=I,k},gr(j,_)}function Xi(j){var _=ta();return function(){var k=Ct(j),I;if(_){var Q=Ct(this).constructor;I=Reflect.construct(k,arguments,Q)}else I=k.apply(this,arguments);return Zi(this,I)}}function Zi(j,_){return _&&(Ce(_)==="object"||typeof _=="function")?_:ea(j)}function ea(j){if(j===void 0)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return j}function ta(){if(typeof Reflect=="undefined"||!Reflect.construct||Reflect.construct.sham)return!1;if(typeof Proxy=="function")return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(j){return!1}}function Ct(j){return Ct=Object.setPrototypeOf?Object.getPrototypeOf:function(E){return E.__proto__||Object.getPrototypeOf(E)},Ct(j)}function yr(j,_){var E="data-clipboard-".concat(j);if(!!_.hasAttribute(E))return _.getAttribute(E)}var ra=function(j){Ji(E,j);var _=Xi(E);function E(k,I){var Q;return Bi(this,E),Q=_.call(this),Q.resolveOptions(I),Q.listenClick(k),Q}return Gi(E,[{key:"resolveOptions",value:function(){var I=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof I.action=="function"?I.action:this.defaultAction,this.target=typeof I.target=="function"?I.target:this.defaultTarget,this.text=typeof I.text=="function"?I.text:this.defaultText,this.container=Ce(I.container)==="object"?I.container:document.body}},{key:"listenClick",value:function(I){var Q=this;this.listener=u()(I,"click",function(Oe){return Q.onClick(Oe)})}},{key:"onClick",value:function(I){var Q=I.delegateTarget||I.currentTarget,Oe=this.action(Q)||"copy",Rt=He({action:Oe,container:this.container,target:this.target(Q),text:this.text(Q)});this.emit(Rt?"success":"error",{action:Oe,text:Rt,trigger:Q,clearSelection:function(){Q&&Q.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(I){return yr("action",I)}},{key:"defaultTarget",value:function(I){var Q=yr("target",I);if(Q)return document.querySelector(Q)}},{key:"defaultText",value:function(I){return yr("text",I)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(I){var Q=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return W(I,Q)}},{key:"cut",value:function(I){return h(I)}},{key:"isSupported",value:function(){var I=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],Q=typeof I=="string"?[I]:I,Oe=!!document.queryCommandSupported;return Q.forEach(function(Rt){Oe=Oe&&!!document.queryCommandSupported(Rt)}),Oe}}]),E}(s()),na=ra},828:function(n){var o=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function a(s,c){for(;s&&s.nodeType!==o;){if(typeof s.matches=="function"&&s.matches(c))return s;s=s.parentNode}}n.exports=a},438:function(n,o,i){var a=i(828);function s(f,p,l,d,h){var b=u.apply(this,arguments);return f.addEventListener(l,b,h),{destroy:function(){f.removeEventListener(l,b,h)}}}function c(f,p,l,d,h){return typeof f.addEventListener=="function"?s.apply(null,arguments):typeof l=="function"?s.bind(null,document).apply(null,arguments):(typeof f=="string"&&(f=document.querySelectorAll(f)),Array.prototype.map.call(f,function(b){return s(b,p,l,d,h)}))}function u(f,p,l,d){return function(h){h.delegateTarget=a(h.target,p),h.delegateTarget&&d.call(f,h)}}n.exports=c},879:function(n,o){o.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},o.nodeList=function(i){var a=Object.prototype.toString.call(i);return i!==void 0&&(a==="[object NodeList]"||a==="[object HTMLCollection]")&&"length"in i&&(i.length===0||o.node(i[0]))},o.string=function(i){return typeof i=="string"||i instanceof String},o.fn=function(i){var a=Object.prototype.toString.call(i);return a==="[object Function]"}},370:function(n,o,i){var a=i(879),s=i(438);function c(l,d,h){if(!l&&!d&&!h)throw new Error("Missing required arguments");if(!a.string(d))throw new TypeError("Second argument must be a String");if(!a.fn(h))throw new TypeError("Third argument must be a Function");if(a.node(l))return u(l,d,h);if(a.nodeList(l))return f(l,d,h);if(a.string(l))return p(l,d,h);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function u(l,d,h){return l.addEventListener(d,h),{destroy:function(){l.removeEventListener(d,h)}}}function f(l,d,h){return Array.prototype.forEach.call(l,function(b){b.addEventListener(d,h)}),{destroy:function(){Array.prototype.forEach.call(l,function(b){b.removeEventListener(d,h)})}}}function p(l,d,h){return s(document.body,l,d,h)}n.exports=c},817:function(n){function o(i){var a;if(i.nodeName==="SELECT")i.focus(),a=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var s=i.hasAttribute("readonly");s||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),s||i.removeAttribute("readonly"),a=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var c=window.getSelection(),u=document.createRange();u.selectNodeContents(i),c.removeAllRanges(),c.addRange(u),a=c.toString()}return a}n.exports=o},279:function(n){function o(){}o.prototype={on:function(i,a,s){var c=this.e||(this.e={});return(c[i]||(c[i]=[])).push({fn:a,ctx:s}),this},once:function(i,a,s){var c=this;function u(){c.off(i,u),a.apply(s,arguments)}return u._=a,this.on(i,u,s)},emit:function(i){var a=[].slice.call(arguments,1),s=((this.e||(this.e={}))[i]||[]).slice(),c=0,u=s.length;for(c;c{"use strict";/*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + */var _s=/["'&<>]/;Si.exports=Ts;function Ts(e){var t=""+e,r=_s.exec(t);if(!r)return t;var n,o="",i=0,a=0;for(i=r.index;i0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var n=this,o=this,i=o.hasError,a=o.isStopped,s=o.observers;return i||a?_r:(this.currentObservers=null,s.push(r),new Re(function(){n.currentObservers=null,Pe(s,r)}))},t.prototype._checkFinalizedStatuses=function(r){var n=this,o=n.hasError,i=n.thrownError,a=n.isStopped;o?r.error(i):a&&r.complete()},t.prototype.asObservable=function(){var r=new F;return r.source=this,r},t.create=function(r,n){return new qn(r,n)},t}(F);var qn=function(e){re(t,e);function t(r,n){var o=e.call(this)||this;return o.destination=r,o.source=n,o}return t.prototype.next=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.next)===null||o===void 0||o.call(n,r)},t.prototype.error=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.error)===null||o===void 0||o.call(n,r)},t.prototype.complete=function(){var r,n;(n=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||n===void 0||n.call(r)},t.prototype._subscribe=function(r){var n,o;return(o=(n=this.source)===null||n===void 0?void 0:n.subscribe(r))!==null&&o!==void 0?o:_r},t}(w);var St={now:function(){return(St.delegate||Date).now()},delegate:void 0};var wt=function(e){re(t,e);function t(r,n,o){r===void 0&&(r=1/0),n===void 0&&(n=1/0),o===void 0&&(o=St);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=n,i._timestampProvider=o,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=n===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,n),i}return t.prototype.next=function(r){var n=this,o=n.isStopped,i=n._buffer,a=n._infiniteTimeWindow,s=n._timestampProvider,c=n._windowTime;o||(i.push(r),!a&&i.push(s.now()+c)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var n=this._innerSubscribe(r),o=this,i=o._infiniteTimeWindow,a=o._buffer,s=a.slice(),c=0;c0?e.prototype.requestAsyncId.call(this,r,n,o):(r.actions.push(this),r._scheduled||(r._scheduled=at.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,n,o){if(o===void 0&&(o=0),o!=null&&o>0||o==null&&this.delay>0)return e.prototype.recycleAsyncId.call(this,r,n,o);r.actions.some(function(i){return i.id===n})||(at.cancelAnimationFrame(n),r._scheduled=void 0)},t}(Nt);var Kn=function(e){re(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var n=this._scheduled;this._scheduled=void 0;var o=this.actions,i;r=r||o.shift();do if(i=r.execute(r.state,r.delay))break;while((r=o[0])&&r.id===n&&o.shift());if(this._active=!1,i){for(;(r=o[0])&&r.id===n&&o.shift();)r.unsubscribe();throw i}},t}(zt);var Te=new Kn(Yn);var C=new F(function(e){return e.complete()});function qt(e){return e&&T(e.schedule)}function kr(e){return e[e.length-1]}function De(e){return T(kr(e))?e.pop():void 0}function ye(e){return qt(kr(e))?e.pop():void 0}function Qt(e,t){return typeof kr(e)=="number"?e.pop():t}var st=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function Yt(e){return T(e==null?void 0:e.then)}function Kt(e){return T(e[it])}function Bt(e){return Symbol.asyncIterator&&T(e==null?void 0:e[Symbol.asyncIterator])}function Gt(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function va(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var Jt=va();function Xt(e){return T(e==null?void 0:e[Jt])}function Zt(e){return In(this,arguments,function(){var r,n,o,i;return $t(this,function(a){switch(a.label){case 0:r=e.getReader(),a.label=1;case 1:a.trys.push([1,,9,10]),a.label=2;case 2:return[4,jt(r.read())];case 3:return n=a.sent(),o=n.value,i=n.done,i?[4,jt(void 0)]:[3,5];case 4:return[2,a.sent()];case 5:return[4,jt(o)];case 6:return[4,a.sent()];case 7:return a.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function er(e){return T(e==null?void 0:e.getReader)}function N(e){if(e instanceof F)return e;if(e!=null){if(Kt(e))return ga(e);if(st(e))return ya(e);if(Yt(e))return xa(e);if(Bt(e))return Bn(e);if(Xt(e))return Sa(e);if(er(e))return wa(e)}throw Gt(e)}function ga(e){return new F(function(t){var r=e[it]();if(T(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function ya(e){return new F(function(t){for(var r=0;r=2,!0))}function oe(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new w}:t,n=e.resetOnError,o=n===void 0?!0:n,i=e.resetOnComplete,a=i===void 0?!0:i,s=e.resetOnRefCountZero,c=s===void 0?!0:s;return function(u){var f,p,l,d=0,h=!1,b=!1,U=function(){p==null||p.unsubscribe(),p=void 0},G=function(){U(),f=l=void 0,h=b=!1},W=function(){var O=f;G(),O==null||O.unsubscribe()};return g(function(O,Ue){d++,!b&&!h&&U();var He=l=l!=null?l:r();Ue.add(function(){d--,d===0&&!b&&!h&&(p=Ur(W,c))}),He.subscribe(Ue),!f&&d>0&&(f=new Be({next:function(Ce){return He.next(Ce)},error:function(Ce){b=!0,U(),p=Ur(G,o,Ce),He.error(Ce)},complete:function(){h=!0,U(),p=Ur(G,a),He.complete()}}),N(O).subscribe(f))})(u)}}function Ur(e,t){for(var r=[],n=2;ne.next(document)),e}function B(e,t=document){return Array.from(t.querySelectorAll(e))}function z(e,t=document){let r=pe(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function pe(e,t=document){return t.querySelector(e)||void 0}function Ne(){return document.activeElement instanceof HTMLElement&&document.activeElement||void 0}function nr(e){return R(v(document.body,"focusin"),v(document.body,"focusout")).pipe(Ze(1),m(()=>{let t=Ne();return typeof t!="undefined"?e.contains(t):!1}),q(e===Ne()),K())}function ze(e){return{x:e.offsetLeft,y:e.offsetTop}}function vo(e){return R(v(window,"load"),v(window,"resize")).pipe($e(0,Te),m(()=>ze(e)),q(ze(e)))}function or(e){return{x:e.scrollLeft,y:e.scrollTop}}function pt(e){return R(v(e,"scroll"),v(window,"resize")).pipe($e(0,Te),m(()=>or(e)),q(or(e)))}var yo=function(){if(typeof Map!="undefined")return Map;function e(t,r){var n=-1;return t.some(function(o,i){return o[0]===r?(n=i,!0):!1}),n}return function(){function t(){this.__entries__=[]}return Object.defineProperty(t.prototype,"size",{get:function(){return this.__entries__.length},enumerable:!0,configurable:!0}),t.prototype.get=function(r){var n=e(this.__entries__,r),o=this.__entries__[n];return o&&o[1]},t.prototype.set=function(r,n){var o=e(this.__entries__,r);~o?this.__entries__[o][1]=n:this.__entries__.push([r,n])},t.prototype.delete=function(r){var n=this.__entries__,o=e(n,r);~o&&n.splice(o,1)},t.prototype.has=function(r){return!!~e(this.__entries__,r)},t.prototype.clear=function(){this.__entries__.splice(0)},t.prototype.forEach=function(r,n){n===void 0&&(n=null);for(var o=0,i=this.__entries__;o0},e.prototype.connect_=function(){!zr||this.connected_||(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),za?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},e.prototype.disconnect_=function(){!zr||!this.connected_||(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},e.prototype.onTransitionEnd_=function(t){var r=t.propertyName,n=r===void 0?"":r,o=Na.some(function(i){return!!~n.indexOf(i)});o&&this.refresh()},e.getInstance=function(){return this.instance_||(this.instance_=new e),this.instance_},e.instance_=null,e}(),xo=function(e,t){for(var r=0,n=Object.keys(t);r0},e}(),wo=typeof WeakMap!="undefined"?new WeakMap:new yo,Eo=function(){function e(t){if(!(this instanceof e))throw new TypeError("Cannot call a class as a function.");if(!arguments.length)throw new TypeError("1 argument required, but only 0 present.");var r=qa.getInstance(),n=new ts(t,r,this);wo.set(this,n)}return e}();["observe","unobserve","disconnect"].forEach(function(e){Eo.prototype[e]=function(){var t;return(t=wo.get(this))[e].apply(t,arguments)}});var rs=function(){return typeof ir.ResizeObserver!="undefined"?ir.ResizeObserver:Eo}(),Oo=rs;var _o=new w,ns=P(()=>$(new Oo(e=>{for(let t of e)_o.next(t)}))).pipe(S(e=>R(xe,$(e)).pipe(L(()=>e.disconnect()))),X(1));function Ae(e){return{width:e.offsetWidth,height:e.offsetHeight}}function de(e){return ns.pipe(x(t=>t.observe(e)),S(t=>_o.pipe(M(({target:r})=>r===e),L(()=>t.unobserve(e)),m(()=>Ae(e)))),q(Ae(e)))}function mt(e){return{width:e.scrollWidth,height:e.scrollHeight}}var To=new w,os=P(()=>$(new IntersectionObserver(e=>{for(let t of e)To.next(t)},{threshold:0}))).pipe(S(e=>R(xe,$(e)).pipe(L(()=>e.disconnect()))),X(1));function cr(e){return os.pipe(x(t=>t.observe(e)),S(t=>To.pipe(M(({target:r})=>r===e),L(()=>t.unobserve(e)),m(({isIntersecting:r})=>r))))}function Mo(e,t=16){return pt(e).pipe(m(({y:r})=>{let n=Ae(e),o=mt(e);return r>=o.height-n.height-t}),K())}var ur={drawer:z("[data-md-toggle=drawer]"),search:z("[data-md-toggle=search]")};function Lo(e){return ur[e].checked}function qe(e,t){ur[e].checked!==t&&ur[e].click()}function dt(e){let t=ur[e];return v(t,"change").pipe(m(()=>t.checked),q(t.checked))}function is(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function Ao(){return v(window,"keydown").pipe(M(e=>!(e.metaKey||e.ctrlKey)),m(e=>({mode:Lo("search")?"search":"global",type:e.key,claim(){e.preventDefault(),e.stopPropagation()}})),M(({mode:e,type:t})=>{if(e==="global"){let r=Ne();if(typeof r!="undefined")return!is(r,t)}return!0}),oe())}function Se(){return new URL(location.href)}function fr(e){location.href=e.href}function Co(){return new w}function Ro(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)Ro(e,r)}function A(e,t,...r){let n=document.createElement(e);if(t)for(let o of Object.keys(t))typeof t[o]!="undefined"&&(typeof t[o]!="boolean"?n.setAttribute(o,t[o]):n.setAttribute(o,""));for(let o of r)Ro(n,o);return n}function ko(e,t){let r=t;if(e.length>r){for(;e[r]!==" "&&--r>0;);return`${e.substring(0,r)}...`}return e}function pr(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function Ho(){return location.hash.substring(1)}function Po(e){let t=A("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function as(){return v(window,"hashchange").pipe(m(Ho),q(Ho()),M(e=>e.length>0),X(1))}function Io(){return as().pipe(m(e=>pe(`[id="${e}"]`)),M(e=>typeof e!="undefined"))}function qr(e){let t=matchMedia(e);return rr(r=>t.addListener(()=>r(t.matches))).pipe(q(t.matches))}function $o(){let e=matchMedia("print");return R(v(window,"beforeprint").pipe(m(()=>!0)),v(window,"afterprint").pipe(m(()=>!1))).pipe(q(e.matches))}function Qr(e,t){return e.pipe(S(r=>r?t():C))}function lr(e,t={credentials:"same-origin"}){return fe(fetch(`${e}`,t)).pipe(ae(()=>C),S(r=>r.status!==200?Ot(()=>new Error(r.statusText)):$(r)))}function ke(e,t){return lr(e,t).pipe(S(r=>r.json()),X(1))}function jo(e,t){let r=new DOMParser;return lr(e,t).pipe(S(n=>n.text()),m(n=>r.parseFromString(n,"text/xml")),X(1))}function Fo(e){let t=A("script",{src:e});return P(()=>(document.head.appendChild(t),R(v(t,"load"),v(t,"error").pipe(S(()=>Ot(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(m(()=>{}),L(()=>document.head.removeChild(t)),se(1))))}function Uo(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function Do(){return R(v(window,"scroll",{passive:!0}),v(window,"resize",{passive:!0})).pipe(m(Uo),q(Uo()))}function Wo(){return{width:innerWidth,height:innerHeight}}function Vo(){return v(window,"resize",{passive:!0}).pipe(m(Wo),q(Wo()))}function No(){return Y([Do(),Vo()]).pipe(m(([e,t])=>({offset:e,size:t})),X(1))}function mr(e,{viewport$:t,header$:r}){let n=t.pipe(J("size")),o=Y([n,r]).pipe(m(()=>ze(e)));return Y([r,t,o]).pipe(m(([{height:i},{offset:a,size:s},{x:c,y:u}])=>({offset:{x:a.x-c,y:a.y-u+i},size:s})))}function zo(e,{tx$:t}){let r=v(e,"message").pipe(m(({data:n})=>n));return t.pipe(Lt(()=>r,{leading:!0,trailing:!0}),x(n=>e.postMessage(n)),S(()=>r),oe())}var ss=z("#__config"),ht=JSON.parse(ss.textContent);ht.base=`${new URL(ht.base,Se())}`;function he(){return ht}function ee(e){return ht.features.includes(e)}function te(e,t){return typeof t!="undefined"?ht.translations[e].replace("#",t.toString()):ht.translations[e]}function we(e,t=document){return z(`[data-md-component=${e}]`,t)}function ne(e,t=document){return B(`[data-md-component=${e}]`,t)}function cs(e){let t=z(".md-typeset > :first-child",e);return v(t,"click",{once:!0}).pipe(m(()=>z(".md-typeset",e)),m(r=>({hash:__md_hash(r.innerHTML)})))}function qo(e){return!ee("announce.dismiss")||!e.childElementCount?C:P(()=>{let t=new w;return t.pipe(q({hash:__md_get("__announce")})).subscribe(({hash:r})=>{var n;r&&r===((n=__md_get("__announce"))!=null?n:r)&&(e.hidden=!0,__md_set("__announce",r))}),cs(e).pipe(x(r=>t.next(r)),L(()=>t.complete()),m(r=>H({ref:e},r)))})}function us(e,{target$:t}){return t.pipe(m(r=>({hidden:r!==e})))}function Qo(e,t){let r=new w;return r.subscribe(({hidden:n})=>{e.hidden=n}),us(e,t).pipe(x(n=>r.next(n)),L(()=>r.complete()),m(n=>H({ref:e},n)))}var ni=Ye(Kr());function Yo(e){return A("aside",{class:"md-annotation",tabIndex:0},A("div",{class:"md-annotation__inner md-tooltip"},A("div",{class:"md-tooltip__inner md-typeset"})),A("span",{class:"md-annotation__index"},A("span",{"data-md-annotation-id":e})))}function Ko(e){return A("button",{class:"md-clipboard md-icon",title:te("clipboard.copy"),"data-clipboard-target":`#${e} > code`})}function Br(e,t){let r=t&2,n=t&1,o=Object.keys(e.terms).filter(a=>!e.terms[a]).reduce((a,s)=>[...a,A("del",null,s)," "],[]).slice(0,-1),i=new URL(e.location);return ee("search.highlight")&&i.searchParams.set("h",Object.entries(e.terms).filter(([,a])=>a).reduce((a,[s])=>`${a} ${s}`.trim(),"")),A("a",{href:`${i}`,class:"md-search-result__link",tabIndex:-1},A("article",{class:["md-search-result__article",...r?["md-search-result__article--document"]:[]].join(" "),"data-md-score":e.score.toFixed(2)},r>0&&A("div",{class:"md-search-result__icon md-icon"}),A("h1",{class:"md-search-result__title"},e.title),n>0&&e.text.length>0&&A("p",{class:"md-search-result__teaser"},ko(e.text,320)),e.tags&&e.tags.map(a=>A("span",{class:"md-tag"},a)),n>0&&o.length>0&&A("p",{class:"md-search-result__terms"},te("search.result.term.missing"),": ",...o)))}function Bo(e){let t=e[0].score,r=[...e],n=r.findIndex(u=>!u.location.includes("#")),[o]=r.splice(n,1),i=r.findIndex(u=>u.scoreBr(u,1)),...s.length?[A("details",{class:"md-search-result__more"},A("summary",{tabIndex:-1},s.length>0&&s.length===1?te("search.result.more.one"):te("search.result.more.other",s.length)),...s.map(u=>Br(u,1)))]:[]];return A("li",{class:"md-search-result__item"},c)}function Go(e){return A("ul",{class:"md-source__facts"},Object.entries(e).map(([t,r])=>A("li",{class:`md-source__fact md-source__fact--${t}`},typeof r=="number"?pr(r):r)))}function Gr(e){let t=`tabbed-control tabbed-control--${e}`;return A("div",{class:t,hidden:!0},A("button",{class:"tabbed-button",tabIndex:-1}))}function Jo(e){return A("div",{class:"md-typeset__scrollwrap"},A("div",{class:"md-typeset__table"},e))}function fs(e){let t=he(),r=new URL(`../${e.version}/`,t.base);return A("li",{class:"md-version__item"},A("a",{href:`${r}`,class:"md-version__link"},e.title))}function Xo(e,t){return A("div",{class:"md-version"},A("button",{class:"md-version__current","aria-label":te("select.version.title")},t.title),A("ul",{class:"md-version__list"},e.map(fs)))}function ps(e,t){let r=P(()=>Y([vo(e),pt(t)])).pipe(m(([{x:n,y:o},i])=>{let{width:a}=Ae(e);return{x:n-i.x+a/2,y:o-i.y}}));return nr(e).pipe(S(n=>r.pipe(m(o=>({active:n,offset:o})),se(+!n||1/0))))}function Zo(e,t){return P(()=>{let r=new w;r.subscribe({next({offset:a}){e.style.setProperty("--md-tooltip-x",`${a.x}px`),e.style.setProperty("--md-tooltip-y",`${a.y}px`)},complete(){e.style.removeProperty("--md-tooltip-x"),e.style.removeProperty("--md-tooltip-y")}});let n=r.pipe(ce(1));cr(e).pipe(Z(n)).subscribe(a=>{e.toggleAttribute("data-md-visible",a)}),r.pipe(Vr(500,Te),m(()=>t.getBoundingClientRect()),m(({x:a})=>a)).subscribe({next(a){a?e.style.setProperty("--md-tooltip-0",`${-a}px`):e.style.removeProperty("--md-tooltip-0")},complete(){e.style.removeProperty("--md-tooltip-0")}});let o=z(":scope > :last-child",e),i=v(o,"mousedown",{once:!0});return r.pipe(S(({active:a})=>a?i:C),x(a=>a.preventDefault())).subscribe(()=>e.blur()),ps(e,t).pipe(x(a=>r.next(a)),L(()=>r.complete()),m(a=>H({ref:e},a)))})}function ls(e){let t=[];for(let r of B(".c, .c1, .cm",e)){let n,o=r.firstChild;if(o instanceof Text)for(;n=/\((\d+)\)/.exec(o.textContent);){let i=o.splitText(n.index);o=i.splitText(n[0].length),t.push(i)}}return t}function ei(e,t){t.append(...Array.from(e.childNodes))}function ti(e,t,{print$:r}){let n=new Map;for(let o of ls(t)){let[,i]=o.textContent.match(/\((\d+)\)/);pe(`li:nth-child(${i})`,e)&&(n.set(+i,Yo(+i)),o.replaceWith(n.get(+i)))}return n.size===0?C:P(()=>{let o=new w;return r.pipe(Z(o.pipe(ce(1)))).subscribe(i=>{e.hidden=!i;for(let[a,s]of n){let c=z(".md-typeset",s),u=z(`li:nth-child(${a})`,e);i?ei(c,u):ei(u,c)}}),R(...[...n].map(([,i])=>Zo(i,t))).pipe(L(()=>o.complete()),oe())})}var ms=0;function oi(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return oi(t)}}function ri(e){return de(e).pipe(m(({width:t})=>({scrollable:mt(e).width>t})),J("scrollable"))}function ii(e,t){let{matches:r}=matchMedia("(hover)"),n=P(()=>{let o=new w;if(o.subscribe(({scrollable:a})=>{a&&r?e.setAttribute("tabindex","0"):e.removeAttribute("tabindex")}),ni.default.isSupported()){let a=e.closest("pre");a.id=`__code_${++ms}`,a.insertBefore(Ko(a.id),e)}let i=e.closest(".highlight");if(i instanceof HTMLElement){let a=oi(i);if(typeof a!="undefined"&&(i.classList.contains("annotate")||ee("content.code.annotate"))){let s=ti(a,e,t);return ri(e).pipe(x(c=>o.next(c)),L(()=>o.complete()),m(c=>H({ref:e},c)),et(de(i).pipe(Z(o.pipe(ce(1))),m(({width:c,height:u})=>c&&u),K(),S(c=>c?s:C))))}}return ri(e).pipe(x(a=>o.next(a)),L(()=>o.complete()),m(a=>H({ref:e},a)))});return cr(e).pipe(M(o=>o),se(1),S(()=>n))}var ai=".node circle,.node ellipse,.node path,.node polygon,.node rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}marker{fill:var(--md-mermaid-edge-color)!important}.edgeLabel .label rect{fill:transparent}.label{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.label foreignObject{line-height:normal;overflow:visible}.label div .edgeLabel{color:var(--md-mermaid-label-fg-color)}.edgeLabel,.edgeLabel rect,.label div .edgeLabel{background-color:var(--md-mermaid-label-bg-color)}.edgeLabel,.edgeLabel rect{fill:var(--md-mermaid-label-bg-color);color:var(--md-mermaid-edge-color)}.edgePath .path,.flowchart-link{stroke:var(--md-mermaid-edge-color)}.edgePath .arrowheadPath{fill:var(--md-mermaid-edge-color);stroke:none}.cluster rect{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}.cluster span{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}defs #flowchart-circleEnd,defs #flowchart-circleStart,defs #flowchart-crossEnd,defs #flowchart-crossStart,defs #flowchart-pointEnd,defs #flowchart-pointStart{stroke:none}g.classGroup line,g.classGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.classGroup text{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.classLabel .box{fill:var(--md-mermaid-label-bg-color);background-color:var(--md-mermaid-label-bg-color);opacity:1}.classLabel .label{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node .divider{stroke:var(--md-mermaid-node-fg-color)}.relation{stroke:var(--md-mermaid-edge-color)}.cardinality{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.cardinality text{fill:inherit!important}defs #classDiagram-compositionEnd,defs #classDiagram-compositionStart,defs #classDiagram-dependencyEnd,defs #classDiagram-dependencyStart,defs #classDiagram-extensionEnd,defs #classDiagram-extensionStart{fill:var(--md-mermaid-edge-color)!important;stroke:var(--md-mermaid-edge-color)!important}defs #classDiagram-aggregationEnd,defs #classDiagram-aggregationStart{fill:var(--md-mermaid-label-bg-color)!important;stroke:var(--md-mermaid-edge-color)!important}g.stateGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.stateGroup .state-title{fill:var(--md-mermaid-label-fg-color)!important;font-family:var(--md-mermaid-font-family)}g.stateGroup .composit{fill:var(--md-mermaid-label-bg-color)}.nodeLabel{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node circle.state-end,.node circle.state-start,.start-state{fill:var(--md-mermaid-edge-color);stroke:none}.end-state-inner,.end-state-outer{fill:var(--md-mermaid-edge-color)}.end-state-inner,.node circle.state-end{stroke:var(--md-mermaid-label-bg-color)}.transition{stroke:var(--md-mermaid-edge-color)}[id^=state-fork] rect,[id^=state-join] rect{fill:var(--md-mermaid-edge-color)!important;stroke:none!important}.statediagram-cluster.statediagram-cluster .inner{fill:var(--md-default-bg-color)}.statediagram-cluster rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.statediagram-state rect.divider{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}defs #statediagram-barbEnd{stroke:var(--md-mermaid-edge-color)}.entityBox{fill:var(--md-mermaid-label-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityLabel{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.relationshipLabelBox{fill:var(--md-mermaid-label-bg-color);fill-opacity:1;background-color:var(--md-mermaid-label-bg-color);opacity:1}.relationshipLabel{fill:var(--md-mermaid-label-fg-color)}.relationshipLine{stroke:var(--md-mermaid-edge-color)}defs #ONE_OR_MORE_END *,defs #ONE_OR_MORE_START *,defs #ONLY_ONE_END *,defs #ONLY_ONE_START *,defs #ZERO_OR_MORE_END *,defs #ZERO_OR_MORE_START *,defs #ZERO_OR_ONE_END *,defs #ZERO_OR_ONE_START *{stroke:var(--md-mermaid-edge-color)!important}.actor,defs #ZERO_OR_MORE_END circle,defs #ZERO_OR_MORE_START circle{fill:var(--md-mermaid-label-bg-color)}.actor{stroke:var(--md-mermaid-node-fg-color)}text.actor>tspan{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}line{stroke:var(--md-default-fg-color--lighter)}.messageLine0,.messageLine1{stroke:var(--md-mermaid-edge-color)}.loopText>tspan,.messageText{font-family:var(--md-mermaid-font-family)!important}#arrowhead path,.loopText>tspan,.messageText{fill:var(--md-mermaid-edge-color);stroke:none}.loopLine{stroke:var(--md-mermaid-node-fg-color)}.labelBox,.loopLine{fill:var(--md-mermaid-node-bg-color)}.labelBox{stroke:none}.labelText,.labelText>span{fill:var(--md-mermaid-node-fg-color);font-family:var(--md-mermaid-font-family)}";var Jr,hs=0;function bs(){return typeof mermaid=="undefined"||mermaid instanceof Element?Fo("https://unpkg.com/mermaid@9.0.1/dist/mermaid.min.js"):$(void 0)}function si(e){return e.classList.remove("mermaid"),Jr||(Jr=bs().pipe(x(()=>mermaid.initialize({startOnLoad:!1,themeCSS:ai})),m(()=>{}),X(1))),Jr.subscribe(()=>{e.classList.add("mermaid");let t=`__mermaid_${hs++}`,r=A("div",{class:"mermaid"});mermaid.mermaidAPI.render(t,e.textContent,n=>{let o=r.attachShadow({mode:"closed"});o.innerHTML=n,e.replaceWith(r)})}),Jr.pipe(m(()=>({ref:e})))}function vs(e,{target$:t,print$:r}){let n=!0;return R(t.pipe(m(o=>o.closest("details:not([open])")),M(o=>e===o),m(()=>({action:"open",reveal:!0}))),r.pipe(M(o=>o||!n),x(()=>n=e.open),m(o=>({action:o?"open":"close"}))))}function ci(e,t){return P(()=>{let r=new w;return r.subscribe(({action:n,reveal:o})=>{n==="open"?e.setAttribute("open",""):e.removeAttribute("open"),o&&e.scrollIntoView()}),vs(e,t).pipe(x(n=>r.next(n)),L(()=>r.complete()),m(n=>H({ref:e},n)))})}var ui=A("table");function fi(e){return e.replaceWith(ui),ui.replaceWith(Jo(e)),$({ref:e})}function gs(e){let t=B(":scope > input",e),r=t.find(n=>n.checked)||t[0];return R(...t.map(n=>v(n,"change").pipe(m(()=>z(`label[for="${n.id}"]`))))).pipe(q(z(`label[for="${r.id}"]`)),m(n=>({active:n})))}function pi(e){let t=Gr("prev");e.append(t);let r=Gr("next");e.append(r);let n=z(".tabbed-labels",e);return P(()=>{let o=new w,i=o.pipe(ce(1));return Y([o,de(e)]).pipe($e(1,Te),Z(i)).subscribe({next([{active:a},s]){let c=ze(a),{width:u}=Ae(a);e.style.setProperty("--md-indicator-x",`${c.x}px`),e.style.setProperty("--md-indicator-width",`${u}px`);let f=or(n);(c.xf.x+s.width)&&n.scrollTo({left:Math.max(0,c.x-16),behavior:"smooth"})},complete(){e.style.removeProperty("--md-indicator-x"),e.style.removeProperty("--md-indicator-width")}}),Y([pt(n),de(n)]).pipe(Z(i)).subscribe(([a,s])=>{let c=mt(n);t.hidden=a.x<16,r.hidden=a.x>c.width-s.width-16}),R(v(t,"click").pipe(m(()=>-1)),v(r,"click").pipe(m(()=>1))).pipe(Z(i)).subscribe(a=>{let{width:s}=Ae(n);n.scrollBy({left:s*a,behavior:"smooth"})}),ee("content.tabs.link")&&o.pipe(Le(1)).subscribe(({active:a})=>{let s=a.innerText.trim();for(let u of B("[data-tabs]"))for(let f of B(":scope > input",u))if(z(`label[for="${f.id}"]`).innerText.trim()===s){f.click();break}let c=__md_get("__tabs")||[];__md_set("__tabs",[...new Set([s,...c])])}),gs(e).pipe(x(a=>o.next(a)),L(()=>o.complete()),m(a=>H({ref:e},a)))}).pipe(Ge(ue))}function li(e,{target$:t,print$:r}){return R(...B("pre:not(.mermaid) > code",e).map(n=>ii(n,{print$:r})),...B("pre.mermaid",e).map(n=>si(n)),...B("table:not([class])",e).map(n=>fi(n)),...B("details",e).map(n=>ci(n,{target$:t,print$:r})),...B("[data-tabs]",e).map(n=>pi(n)))}function ys(e,{alert$:t}){return t.pipe(S(r=>R($(!0),$(!1).pipe(Fe(2e3))).pipe(m(n=>({message:r,active:n})))))}function mi(e,t){let r=z(".md-typeset",e);return P(()=>{let n=new w;return n.subscribe(({message:o,active:i})=>{e.classList.toggle("md-dialog--active",i),r.textContent=o}),ys(e,t).pipe(x(o=>n.next(o)),L(()=>n.complete()),m(o=>H({ref:e},o)))})}function xs({viewport$:e}){if(!ee("header.autohide"))return $(!1);let t=e.pipe(m(({offset:{y:o}})=>o),Me(2,1),m(([o,i])=>[oMath.abs(i-o.y)>100),m(([,[o]])=>o),K()),n=dt("search");return Y([e,n]).pipe(m(([{offset:o},i])=>o.y>400&&!i),K(),S(o=>o?r:$(!1)),q(!1))}function di(e,t){return P(()=>Y([de(e),xs(t)])).pipe(m(([{height:r},n])=>({height:r,hidden:n})),K((r,n)=>r.height===n.height&&r.hidden===n.hidden),X(1))}function hi(e,{header$:t,main$:r}){return P(()=>{let n=new w,o=n.pipe(ce(1));return n.pipe(J("active"),Xe(t)).subscribe(([{active:i},{hidden:a}])=>{e.classList.toggle("md-header--shadow",i&&!a),e.hidden=a}),r.subscribe(n),t.pipe(Z(o),m(i=>H({ref:e},i)))})}function Ss(e,{viewport$:t,header$:r}){return mr(e,{viewport$:t,header$:r}).pipe(m(({offset:{y:n}})=>{let{height:o}=Ae(e);return{active:n>=o}}),J("active"))}function bi(e,t){return P(()=>{let r=new w;r.subscribe(({active:o})=>{e.classList.toggle("md-header__title--active",o)});let n=pe("article h1");return typeof n=="undefined"?C:Ss(n,t).pipe(x(o=>r.next(o)),L(()=>r.complete()),m(o=>H({ref:e},o)))})}function vi(e,{viewport$:t,header$:r}){let n=r.pipe(m(({height:i})=>i),K()),o=n.pipe(S(()=>de(e).pipe(m(({height:i})=>({top:e.offsetTop,bottom:e.offsetTop+i})),J("bottom"))));return Y([n,o,t]).pipe(m(([i,{top:a,bottom:s},{offset:{y:c},size:{height:u}}])=>(u=Math.max(0,u-Math.max(0,a-c,i)-Math.max(0,u+c-s)),{offset:a-i,height:u,active:a-i<=c})),K((i,a)=>i.offset===a.offset&&i.height===a.height&&i.active===a.active))}function ws(e){let t=__md_get("__palette")||{index:e.findIndex(r=>matchMedia(r.getAttribute("data-md-color-media")).matches)};return $(...e).pipe(ie(r=>v(r,"change").pipe(m(()=>r))),q(e[Math.max(0,t.index)]),m(r=>({index:e.indexOf(r),color:{scheme:r.getAttribute("data-md-color-scheme"),primary:r.getAttribute("data-md-color-primary"),accent:r.getAttribute("data-md-color-accent")}})),X(1))}function gi(e){return P(()=>{let t=new w;t.subscribe(n=>{document.body.setAttribute("data-md-color-switching","");for(let[o,i]of Object.entries(n.color))document.body.setAttribute(`data-md-color-${o}`,i);for(let o=0;o{document.body.removeAttribute("data-md-color-switching")});let r=B("input",e);return ws(r).pipe(x(n=>t.next(n)),L(()=>t.complete()),m(n=>H({ref:e},n)))})}var Xr=Ye(Kr());function Es(e){e.setAttribute("data-md-copying","");let t=e.innerText;return e.removeAttribute("data-md-copying"),t}function yi({alert$:e}){Xr.default.isSupported()&&new F(t=>{new Xr.default("[data-clipboard-target], [data-clipboard-text]",{text:r=>r.getAttribute("data-clipboard-text")||Es(z(r.getAttribute("data-clipboard-target")))}).on("success",r=>t.next(r))}).pipe(x(t=>{t.trigger.focus()}),m(()=>te("clipboard.copied"))).subscribe(e)}function Os(e){if(e.length<2)return[""];let[t,r]=[...e].sort((o,i)=>o.length-i.length).map(o=>o.replace(/[^/]+$/,"")),n=0;if(t===r)n=t.length;else for(;t.charCodeAt(n)===r.charCodeAt(n);)n++;return e.map(o=>o.replace(t.slice(0,n),""))}function dr(e){let t=__md_get("__sitemap",sessionStorage,e);if(t)return $(t);{let r=he();return jo(new URL("sitemap.xml",e||r.base)).pipe(m(n=>Os(B("loc",n).map(o=>o.textContent))),ae(()=>C),je([]),x(n=>__md_set("__sitemap",n,sessionStorage,e)))}}function xi({document$:e,location$:t,viewport$:r}){let n=he();if(location.protocol==="file:")return;"scrollRestoration"in history&&(history.scrollRestoration="manual",v(window,"beforeunload").subscribe(()=>{history.scrollRestoration="auto"}));let o=pe("link[rel=icon]");typeof o!="undefined"&&(o.href=o.href);let i=dr().pipe(m(u=>u.map(f=>`${new URL(f,n.base)}`)),S(u=>v(document.body,"click").pipe(M(f=>!f.metaKey&&!f.ctrlKey),S(f=>{if(f.target instanceof Element){let p=f.target.closest("a");if(p&&!p.target){let l=new URL(p.href);if(l.search="",l.hash="",l.pathname!==location.pathname&&u.includes(l.toString()))return f.preventDefault(),$({url:new URL(p.href)})}}return xe}))),oe()),a=v(window,"popstate").pipe(M(u=>u.state!==null),m(u=>({url:new URL(location.href),offset:u.state})),oe());R(i,a).pipe(K((u,f)=>u.url.href===f.url.href),m(({url:u})=>u)).subscribe(t);let s=t.pipe(J("pathname"),S(u=>lr(u.href).pipe(ae(()=>(fr(u),xe)))),oe());i.pipe(ft(s)).subscribe(({url:u})=>{history.pushState({},"",`${u}`)});let c=new DOMParser;s.pipe(S(u=>u.text()),m(u=>c.parseFromString(u,"text/html"))).subscribe(e),e.pipe(Le(1)).subscribe(u=>{for(let f of["title","link[rel=canonical]","meta[name=author]","meta[name=description]","[data-md-component=announce]","[data-md-component=container]","[data-md-component=header-topic]","[data-md-component=outdated]","[data-md-component=logo]","[data-md-component=skip]",...ee("navigation.tabs.sticky")?["[data-md-component=tabs]"]:[]]){let p=pe(f),l=pe(f,u);typeof p!="undefined"&&typeof l!="undefined"&&p.replaceWith(l)}}),e.pipe(Le(1),m(()=>we("container")),S(u=>B("script",u)),Ir(u=>{let f=A("script");if(u.src){for(let p of u.getAttributeNames())f.setAttribute(p,u.getAttribute(p));return u.replaceWith(f),new F(p=>{f.onload=()=>p.complete()})}else return f.textContent=u.textContent,u.replaceWith(f),C})).subscribe(),R(i,a).pipe(ft(e)).subscribe(({url:u,offset:f})=>{u.hash&&!f?Po(u.hash):window.scrollTo(0,(f==null?void 0:f.y)||0)}),r.pipe(Mt(i),Ze(250),J("offset")).subscribe(({offset:u})=>{history.replaceState(u,"")}),R(i,a).pipe(Me(2,1),M(([u,f])=>u.url.pathname===f.url.pathname),m(([,u])=>u)).subscribe(({offset:u})=>{window.scrollTo(0,(u==null?void 0:u.y)||0)})}var Ms=Ye(Zr());var wi=Ye(Zr());function en(e,t){let r=new RegExp(e.separator,"img"),n=(o,i,a)=>`${i}${a}`;return o=>{o=o.replace(/[\s*+\-:~^]+/g," ").trim();let i=new RegExp(`(^|${e.separator})(${o.replace(/[|\\{}()[\]^$+*?.-]/g,"\\$&").replace(r,"|")})`,"img");return a=>(t?(0,wi.default)(a):a).replace(i,n).replace(/<\/mark>(\s+)]*>/img,"$1")}}function Ei(e){return e.split(/"([^"]+)"/g).map((t,r)=>r&1?t.replace(/^\b|^(?![^\x00-\x7F]|$)|\s+/g," +"):t).join("").replace(/"|(?:^|\s+)[*+\-:^~]+(?=\s+|$)/g,"").trim()}function bt(e){return e.type===1}function Oi(e){return e.type===2}function vt(e){return e.type===3}function As({config:e,docs:t}){e.lang.length===1&&e.lang[0]==="en"&&(e.lang=[te("search.config.lang")]),e.separator==="[\\s\\-]+"&&(e.separator=te("search.config.separator"));let n={pipeline:te("search.config.pipeline").split(/\s*,\s*/).filter(Boolean),suggestions:ee("search.suggest")};return{config:e,docs:t,options:n}}function _i(e,t){let r=he(),n=new Worker(e),o=new w,i=zo(n,{tx$:o}).pipe(m(a=>{if(vt(a))for(let s of a.data.items)for(let c of s)c.location=`${new URL(c.location,r.base)}`;return a}),oe());return fe(t).pipe(m(a=>({type:0,data:As(a)}))).subscribe(o.next.bind(o)),{tx$:o,rx$:i}}function Ti({document$:e}){let t=he(),r=ke(new URL("../versions.json",t.base)).pipe(ae(()=>C)),n=r.pipe(m(o=>{let[,i]=t.base.match(/([^/]+)\/?$/);return o.find(({version:a,aliases:s})=>a===i||s.includes(i))||o[0]}));r.pipe(m(o=>new Map(o.map(i=>[`${new URL(`../${i.version}/`,t.base)}`,i]))),S(o=>v(document.body,"click").pipe(M(i=>!i.metaKey&&!i.ctrlKey),ge(n),S(([i,a])=>{if(i.target instanceof Element){let s=i.target.closest("a");if(s&&!s.target&&o.has(s.href)){let c=s.href;return!i.target.closest(".md-version")&&o.get(c)===a?C:(i.preventDefault(),$(c))}}return C}),S(i=>{let{version:a}=o.get(i);return dr(new URL(i)).pipe(m(s=>{let u=Se().href.replace(t.base,"");return s.includes(u)?new URL(`../${a}/${u}`,t.base):new URL(i)}))})))).subscribe(o=>fr(o)),Y([r,n]).subscribe(([o,i])=>{z(".md-header__topic").appendChild(Xo(o,i))}),e.pipe(S(()=>n)).subscribe(o=>{var a;let i=__md_get("__outdated",sessionStorage);if(i===null){let s=((a=t.version)==null?void 0:a.default)||"latest";i=!o.aliases.includes(s),__md_set("__outdated",i,sessionStorage)}if(i)for(let s of ne("outdated"))s.hidden=!1})}function Cs(e,{rx$:t}){let r=(__search==null?void 0:__search.transform)||Ei,{searchParams:n}=Se();n.has("q")&&qe("search",!0);let o=t.pipe(M(bt),se(1),m(()=>n.get("q")||""));dt("search").pipe(M(s=>!s),se(1)).subscribe(()=>{let s=new URL(location.href);s.searchParams.delete("q"),history.replaceState({},"",`${s}`)}),o.subscribe(s=>{s&&(e.value=s,e.focus())});let i=nr(e),a=R(v(e,"keyup"),v(e,"focus").pipe(Fe(1)),o).pipe(m(()=>r(e.value)),q(""),K());return Y([a,i]).pipe(m(([s,c])=>({value:s,focus:c})),X(1))}function Mi(e,{tx$:t,rx$:r}){let n=new w,o=n.pipe(ce(1));return n.pipe(J("value"),m(({value:i})=>({type:2,data:i}))).subscribe(t.next.bind(t)),n.pipe(J("focus")).subscribe(({focus:i})=>{i?(qe("search",i),e.placeholder=""):e.placeholder=te("search.placeholder")}),v(e.form,"reset").pipe(Z(o)).subscribe(()=>e.focus()),Cs(e,{tx$:t,rx$:r}).pipe(x(i=>n.next(i)),L(()=>n.complete()),m(i=>H({ref:e},i)),oe())}function Li(e,{rx$:t},{query$:r}){let n=new w,o=Mo(e.parentElement).pipe(M(Boolean)),i=z(":scope > :first-child",e),a=z(":scope > :last-child",e),s=t.pipe(M(bt),se(1));return n.pipe(ge(r),Mt(s)).subscribe(([{items:u},{value:f}])=>{if(f)switch(u.length){case 0:i.textContent=te("search.result.none");break;case 1:i.textContent=te("search.result.one");break;default:i.textContent=te("search.result.other",pr(u.length))}else i.textContent=te("search.result.placeholder")}),n.pipe(x(()=>a.innerHTML=""),S(({items:u})=>R($(...u.slice(0,10)),$(...u.slice(10)).pipe(Me(4),Nr(o),S(([f])=>f))))).subscribe(u=>a.appendChild(Bo(u))),t.pipe(M(vt),m(({data:u})=>u)).pipe(x(u=>n.next(u)),L(()=>n.complete()),m(u=>H({ref:e},u)))}function Rs(e,{query$:t}){return t.pipe(m(({value:r})=>{let n=Se();return n.hash="",n.searchParams.delete("h"),n.searchParams.set("q",r),{url:n}}))}function Ai(e,t){let r=new w;return r.subscribe(({url:n})=>{e.setAttribute("data-clipboard-text",e.href),e.href=`${n}`}),v(e,"click").subscribe(n=>n.preventDefault()),Rs(e,t).pipe(x(n=>r.next(n)),L(()=>r.complete()),m(n=>H({ref:e},n)))}function Ci(e,{rx$:t},{keyboard$:r}){let n=new w,o=we("search-query"),i=R(v(o,"keydown"),v(o,"focus")).pipe(Ie(ue),m(()=>o.value),K());return n.pipe(Xe(i),m(([{suggestions:s},c])=>{let u=c.split(/([\s-]+)/);if((s==null?void 0:s.length)&&u[u.length-1]){let f=s[s.length-1];f.startsWith(u[u.length-1])&&(u[u.length-1]=f)}else u.length=0;return u})).subscribe(s=>e.innerHTML=s.join("").replace(/\s/g," ")),r.pipe(M(({mode:s})=>s==="search")).subscribe(s=>{switch(s.type){case"ArrowRight":e.innerText.length&&o.selectionStart===o.value.length&&(o.value=e.innerText);break}}),t.pipe(M(vt),m(({data:s})=>s)).pipe(x(s=>n.next(s)),L(()=>n.complete()),m(()=>({ref:e})))}function Ri(e,{index$:t,keyboard$:r}){let n=he();try{let o=(__search==null?void 0:__search.worker)||n.search,i=_i(o,t),a=we("search-query",e),s=we("search-result",e),{tx$:c,rx$:u}=i;c.pipe(M(Oi),ft(u.pipe(M(bt))),se(1)).subscribe(c.next.bind(c)),r.pipe(M(({mode:l})=>l==="search")).subscribe(l=>{let d=Ne();switch(l.type){case"Enter":if(d===a){let h=new Map;for(let b of B(":first-child [href]",s)){let U=b.firstElementChild;h.set(b,parseFloat(U.getAttribute("data-md-score")))}if(h.size){let[[b]]=[...h].sort(([,U],[,G])=>G-U);b.click()}l.claim()}break;case"Escape":case"Tab":qe("search",!1),a.blur();break;case"ArrowUp":case"ArrowDown":if(typeof d=="undefined")a.focus();else{let h=[a,...B(":not(details) > [href], summary, details[open] [href]",s)],b=Math.max(0,(Math.max(0,h.indexOf(d))+h.length+(l.type==="ArrowUp"?-1:1))%h.length);h[b].focus()}l.claim();break;default:a!==Ne()&&a.focus()}}),r.pipe(M(({mode:l})=>l==="global")).subscribe(l=>{switch(l.type){case"f":case"s":case"/":a.focus(),a.select(),l.claim();break}});let f=Mi(a,i),p=Li(s,i,{query$:f});return R(f,p).pipe(et(...ne("search-share",e).map(l=>Ai(l,{query$:f})),...ne("search-suggest",e).map(l=>Ci(l,i,{keyboard$:r}))))}catch(o){return e.hidden=!0,xe}}function ki(e,{index$:t,location$:r}){return Y([t,r.pipe(q(Se()),M(n=>!!n.searchParams.get("h")))]).pipe(m(([n,o])=>en(n.config,!0)(o.searchParams.get("h"))),m(n=>{var a;let o=new Map,i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT);for(let s=i.nextNode();s;s=i.nextNode())if((a=s.parentElement)!=null&&a.offsetHeight){let c=s.textContent,u=n(c);u.length>c.length&&o.set(s,u)}for(let[s,c]of o){let{childNodes:u}=A("span",null,c);s.replaceWith(...Array.from(u))}return{ref:e,nodes:o}}))}function ks(e,{viewport$:t,main$:r}){let n=e.parentElement,o=n.offsetTop-n.parentElement.offsetTop;return Y([r,t]).pipe(m(([{offset:i,height:a},{offset:{y:s}}])=>(a=a+Math.min(o,Math.max(0,s-i))-o,{height:a,locked:s>=i+o})),K((i,a)=>i.height===a.height&&i.locked===a.locked))}function tn(e,n){var o=n,{header$:t}=o,r=cn(o,["header$"]);let i=z(".md-sidebar__scrollwrap",e),{y:a}=ze(i);return P(()=>{let s=new w;return s.pipe($e(0,Te),ge(t)).subscribe({next([{height:c},{height:u}]){i.style.height=`${c-2*a}px`,e.style.top=`${u}px`},complete(){i.style.height="",e.style.top=""}}),ks(e,r).pipe(x(c=>s.next(c)),L(()=>s.complete()),m(c=>H({ref:e},c)))})}function Hi(e,t){if(typeof t!="undefined"){let r=`https://api.github.com/repos/${e}/${t}`;return _t(ke(`${r}/releases/latest`).pipe(ae(()=>C),m(n=>({version:n.tag_name})),je({})),ke(r).pipe(ae(()=>C),m(n=>({stars:n.stargazers_count,forks:n.forks_count})),je({}))).pipe(m(([n,o])=>H(H({},n),o)))}else{let r=`https://api.github.com/users/${e}`;return ke(r).pipe(m(n=>({repositories:n.public_repos})),je({}))}}function Pi(e,t){let r=`https://${e}/api/v4/projects/${encodeURIComponent(t)}`;return ke(r).pipe(ae(()=>C),m(({star_count:n,forks_count:o})=>({stars:n,forks:o})),je({}))}function Ii(e){let[t]=e.match(/(git(?:hub|lab))/i)||[];switch(t.toLowerCase()){case"github":let[,r,n]=e.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i);return Hi(r,n);case"gitlab":let[,o,i]=e.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i);return Pi(o,i);default:return C}}var Hs;function Ps(e){return Hs||(Hs=P(()=>{let t=__md_get("__source",sessionStorage);return t?$(t):Ii(e.href).pipe(x(r=>__md_set("__source",r,sessionStorage)))}).pipe(ae(()=>C),M(t=>Object.keys(t).length>0),m(t=>({facts:t})),X(1)))}function $i(e){let t=z(":scope > :last-child",e);return P(()=>{let r=new w;return r.subscribe(({facts:n})=>{t.appendChild(Go(n)),t.classList.add("md-source__repository--active")}),Ps(e).pipe(x(n=>r.next(n)),L(()=>r.complete()),m(n=>H({ref:e},n)))})}function Is(e,{viewport$:t,header$:r}){return de(document.body).pipe(S(()=>mr(e,{header$:r,viewport$:t})),m(({offset:{y:n}})=>({hidden:n>=10})),J("hidden"))}function ji(e,t){return P(()=>{let r=new w;return r.subscribe({next({hidden:n}){e.hidden=n},complete(){e.hidden=!1}}),(ee("navigation.tabs.sticky")?$({hidden:!1}):Is(e,t)).pipe(x(n=>r.next(n)),L(()=>r.complete()),m(n=>H({ref:e},n)))})}function $s(e,{viewport$:t,header$:r}){let n=new Map,o=B("[href^=\\#]",e);for(let s of o){let c=decodeURIComponent(s.hash.substring(1)),u=pe(`[id="${c}"]`);typeof u!="undefined"&&n.set(s,u)}let i=r.pipe(J("height"),m(({height:s})=>{let c=we("main"),u=z(":scope > :first-child",c);return s+.8*(u.offsetTop-c.offsetTop)}),oe());return de(document.body).pipe(J("height"),S(s=>P(()=>{let c=[];return $([...n].reduce((u,[f,p])=>{for(;c.length&&n.get(c[c.length-1]).tagName>=p.tagName;)c.pop();let l=p.offsetTop;for(;!l&&p.parentElement;)p=p.parentElement,l=p.offsetTop;return u.set([...c=[...c,f]].reverse(),l)},new Map))}).pipe(m(c=>new Map([...c].sort(([,u],[,f])=>u-f))),Xe(i),S(([c,u])=>t.pipe(Fr(([f,p],{offset:{y:l},size:d})=>{let h=l+d.height>=Math.floor(s.height);for(;p.length;){let[,b]=p[0];if(b-u=l&&!h)p=[f.pop(),...p];else break}return[f,p]},[[],[...c]]),K((f,p)=>f[0]===p[0]&&f[1]===p[1])))))).pipe(m(([s,c])=>({prev:s.map(([u])=>u),next:c.map(([u])=>u)})),q({prev:[],next:[]}),Me(2,1),m(([s,c])=>s.prev.length{let o=new w,i=o.pipe(ce(1));return o.subscribe(({prev:a,next:s})=>{for(let[c]of s)c.classList.remove("md-nav__link--passed"),c.classList.remove("md-nav__link--active");for(let[c,[u]]of a.entries())u.classList.add("md-nav__link--passed"),u.classList.toggle("md-nav__link--active",c===a.length-1)}),ee("navigation.tracking")&&t.pipe(Z(i),J("offset"),Ze(250),Le(1),Z(n.pipe(Le(1))),Tt({delay:250}),ge(o)).subscribe(([,{prev:a}])=>{let s=Se(),c=a[a.length-1];if(c&&c.length){let[u]=c,{hash:f}=new URL(u.href);s.hash!==f&&(s.hash=f,history.replaceState({},"",`${s}`))}else s.hash="",history.replaceState({},"",`${s}`)}),$s(e,{viewport$:t,header$:r}).pipe(x(a=>o.next(a)),L(()=>o.complete()),m(a=>H({ref:e},a)))})}function js(e,{viewport$:t,main$:r,target$:n}){let o=t.pipe(m(({offset:{y:a}})=>a),Me(2,1),m(([a,s])=>a>s&&s>0),K()),i=r.pipe(m(({active:a})=>a));return Y([i,o]).pipe(m(([a,s])=>!(a&&s)),K(),Z(n.pipe(Le(1))),jr(!0),Tt({delay:250}),m(a=>({hidden:a})))}function Ui(e,{viewport$:t,header$:r,main$:n,target$:o}){let i=new w,a=i.pipe(ce(1));return i.subscribe({next({hidden:s}){e.hidden=s,s?(e.setAttribute("tabindex","-1"),e.blur()):e.removeAttribute("tabindex")},complete(){e.style.top="",e.hidden=!0,e.removeAttribute("tabindex")}}),r.pipe(Z(a),J("height")).subscribe(({height:s})=>{e.style.top=`${s+16}px`}),js(e,{viewport$:t,main$:n,target$:o}).pipe(x(s=>i.next(s)),L(()=>i.complete()),m(s=>H({ref:e},s)))}function Di({document$:e,tablet$:t}){e.pipe(S(()=>B(".md-toggle--indeterminate, [data-md-state=indeterminate]")),x(r=>{r.indeterminate=!0,r.checked=!1}),ie(r=>v(r,"change").pipe(Dr(()=>r.classList.contains("md-toggle--indeterminate")),m(()=>r))),ge(t)).subscribe(([r,n])=>{r.classList.remove("md-toggle--indeterminate"),n&&(r.checked=!1)})}function Fs(){return/(iPad|iPhone|iPod)/.test(navigator.userAgent)}function Wi({document$:e}){e.pipe(S(()=>B("[data-md-scrollfix]")),x(t=>t.removeAttribute("data-md-scrollfix")),M(Fs),ie(t=>v(t,"touchstart").pipe(m(()=>t)))).subscribe(t=>{let r=t.scrollTop;r===0?t.scrollTop=1:r+t.offsetHeight===t.scrollHeight&&(t.scrollTop=r-1)})}function Vi({viewport$:e,tablet$:t}){Y([dt("search"),t]).pipe(m(([r,n])=>r&&!n),S(r=>$(r).pipe(Fe(r?400:100))),ge(e)).subscribe(([r,{offset:{y:n}}])=>{if(r)document.body.setAttribute("data-md-scrolllock",""),document.body.style.top=`-${n}px`;else{let o=-1*parseInt(document.body.style.top,10);document.body.removeAttribute("data-md-scrolllock"),document.body.style.top="",o&&window.scrollTo(0,o)}})}Object.entries||(Object.entries=function(e){let t=[];for(let r of Object.keys(e))t.push([r,e[r]]);return t});Object.values||(Object.values=function(e){let t=[];for(let r of Object.keys(e))t.push(e[r]);return t});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(e,t){typeof e=="object"?(this.scrollLeft=e.left,this.scrollTop=e.top):(this.scrollLeft=e,this.scrollTop=t)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...e){let t=this.parentNode;if(t){e.length===0&&t.removeChild(this);for(let r=e.length-1;r>=0;r--){let n=e[r];typeof n!="object"?n=document.createTextNode(n):n.parentNode&&n.parentNode.removeChild(n),r?t.insertBefore(this.previousSibling,n):t.replaceChild(n,this)}}}));document.documentElement.classList.remove("no-js");document.documentElement.classList.add("js");var tt=bo(),br=Co(),gt=Io(),rn=Ao(),Ee=No(),vr=qr("(min-width: 960px)"),zi=qr("(min-width: 1220px)"),qi=$o(),Qi=he(),Yi=document.forms.namedItem("search")?(__search==null?void 0:__search.index)||ke(new URL("search/search_index.json",Qi.base)):xe,nn=new w;yi({alert$:nn});ee("navigation.instant")&&xi({document$:tt,location$:br,viewport$:Ee});var Ni;((Ni=Qi.version)==null?void 0:Ni.provider)==="mike"&&Ti({document$:tt});R(br,gt).pipe(Fe(125)).subscribe(()=>{qe("drawer",!1),qe("search",!1)});rn.pipe(M(({mode:e})=>e==="global")).subscribe(e=>{switch(e.type){case"p":case",":let t=pe("[href][rel=prev]");typeof t!="undefined"&&t.click();break;case"n":case".":let r=pe("[href][rel=next]");typeof r!="undefined"&&r.click();break}});Di({document$:tt,tablet$:vr});Wi({document$:tt});Vi({viewport$:Ee,tablet$:vr});var Qe=di(we("header"),{viewport$:Ee}),hr=tt.pipe(m(()=>we("main")),S(e=>vi(e,{viewport$:Ee,header$:Qe})),X(1)),Us=R(...ne("consent").map(e=>Qo(e,{target$:gt})),...ne("dialog").map(e=>mi(e,{alert$:nn})),...ne("header").map(e=>hi(e,{viewport$:Ee,header$:Qe,main$:hr})),...ne("palette").map(e=>gi(e)),...ne("search").map(e=>Ri(e,{index$:Yi,keyboard$:rn})),...ne("source").map(e=>$i(e))),Ds=P(()=>R(...ne("announce").map(e=>qo(e)),...ne("content").map(e=>li(e,{target$:gt,print$:qi})),...ne("content").map(e=>ee("search.highlight")?ki(e,{index$:Yi,location$:br}):C),...ne("header-title").map(e=>bi(e,{viewport$:Ee,header$:Qe})),...ne("sidebar").map(e=>e.getAttribute("data-md-type")==="navigation"?Qr(zi,()=>tn(e,{viewport$:Ee,header$:Qe,main$:hr})):Qr(vr,()=>tn(e,{viewport$:Ee,header$:Qe,main$:hr}))),...ne("tabs").map(e=>ji(e,{viewport$:Ee,header$:Qe})),...ne("toc").map(e=>Fi(e,{viewport$:Ee,header$:Qe,target$:gt})),...ne("top").map(e=>Ui(e,{viewport$:Ee,header$:Qe,main$:hr,target$:gt})))),Ki=tt.pipe(S(()=>Ds),et(Us),X(1));Ki.subscribe();window.document$=tt;window.location$=br;window.target$=gt;window.keyboard$=rn;window.viewport$=Ee;window.tablet$=vr;window.screen$=zi;window.print$=qi;window.alert$=nn;window.component$=Ki;})(); +//# sourceMappingURL=bundle.9c69f0bc.min.js.map + diff --git a/assets/javascripts/bundle.9c69f0bc.min.js.map b/assets/javascripts/bundle.9c69f0bc.min.js.map new file mode 100644 index 000000000..27a084260 --- /dev/null +++ b/assets/javascripts/bundle.9c69f0bc.min.js.map @@ -0,0 +1,8 @@ +{ + "version": 3, + "sources": ["node_modules/focus-visible/dist/focus-visible.js", "node_modules/url-polyfill/url-polyfill.js", "node_modules/rxjs/node_modules/tslib/tslib.js", "node_modules/clipboard/dist/clipboard.js", "node_modules/escape-html/index.js", "node_modules/array-flat-polyfill/index.mjs", "src/assets/javascripts/bundle.ts", "node_modules/unfetch/polyfill/index.js", "node_modules/rxjs/node_modules/tslib/modules/index.js", "node_modules/rxjs/src/internal/util/isFunction.ts", "node_modules/rxjs/src/internal/util/createErrorClass.ts", "node_modules/rxjs/src/internal/util/UnsubscriptionError.ts", "node_modules/rxjs/src/internal/util/arrRemove.ts", "node_modules/rxjs/src/internal/Subscription.ts", "node_modules/rxjs/src/internal/config.ts", "node_modules/rxjs/src/internal/scheduler/timeoutProvider.ts", "node_modules/rxjs/src/internal/util/reportUnhandledError.ts", "node_modules/rxjs/src/internal/util/noop.ts", "node_modules/rxjs/src/internal/NotificationFactories.ts", "node_modules/rxjs/src/internal/util/errorContext.ts", "node_modules/rxjs/src/internal/Subscriber.ts", "node_modules/rxjs/src/internal/symbol/observable.ts", "node_modules/rxjs/src/internal/util/identity.ts", "node_modules/rxjs/src/internal/util/pipe.ts", "node_modules/rxjs/src/internal/Observable.ts", "node_modules/rxjs/src/internal/util/lift.ts", "node_modules/rxjs/src/internal/operators/OperatorSubscriber.ts", "node_modules/rxjs/src/internal/scheduler/animationFrameProvider.ts", "node_modules/rxjs/src/internal/util/ObjectUnsubscribedError.ts", "node_modules/rxjs/src/internal/Subject.ts", "node_modules/rxjs/src/internal/scheduler/dateTimestampProvider.ts", "node_modules/rxjs/src/internal/ReplaySubject.ts", "node_modules/rxjs/src/internal/scheduler/Action.ts", "node_modules/rxjs/src/internal/scheduler/intervalProvider.ts", "node_modules/rxjs/src/internal/scheduler/AsyncAction.ts", "node_modules/rxjs/src/internal/Scheduler.ts", "node_modules/rxjs/src/internal/scheduler/AsyncScheduler.ts", "node_modules/rxjs/src/internal/scheduler/async.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameAction.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameScheduler.ts", "node_modules/rxjs/src/internal/scheduler/animationFrame.ts", "node_modules/rxjs/src/internal/observable/empty.ts", "node_modules/rxjs/src/internal/util/isScheduler.ts", "node_modules/rxjs/src/internal/util/args.ts", "node_modules/rxjs/src/internal/util/isArrayLike.ts", "node_modules/rxjs/src/internal/util/isPromise.ts", "node_modules/rxjs/src/internal/util/isInteropObservable.ts", "node_modules/rxjs/src/internal/util/isAsyncIterable.ts", "node_modules/rxjs/src/internal/util/throwUnobservableError.ts", "node_modules/rxjs/src/internal/symbol/iterator.ts", "node_modules/rxjs/src/internal/util/isIterable.ts", "node_modules/rxjs/src/internal/util/isReadableStreamLike.ts", "node_modules/rxjs/src/internal/observable/innerFrom.ts", "node_modules/rxjs/src/internal/util/executeSchedule.ts", "node_modules/rxjs/src/internal/operators/observeOn.ts", "node_modules/rxjs/src/internal/operators/subscribeOn.ts", "node_modules/rxjs/src/internal/scheduled/scheduleObservable.ts", "node_modules/rxjs/src/internal/scheduled/schedulePromise.ts", "node_modules/rxjs/src/internal/scheduled/scheduleArray.ts", "node_modules/rxjs/src/internal/scheduled/scheduleIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleAsyncIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleReadableStreamLike.ts", "node_modules/rxjs/src/internal/scheduled/scheduled.ts", "node_modules/rxjs/src/internal/observable/from.ts", "node_modules/rxjs/src/internal/observable/of.ts", "node_modules/rxjs/src/internal/observable/throwError.ts", "node_modules/rxjs/src/internal/util/isDate.ts", "node_modules/rxjs/src/internal/operators/map.ts", "node_modules/rxjs/src/internal/util/mapOneOrManyArgs.ts", "node_modules/rxjs/src/internal/util/argsArgArrayOrObject.ts", "node_modules/rxjs/src/internal/util/createObject.ts", "node_modules/rxjs/src/internal/observable/combineLatest.ts", "node_modules/rxjs/src/internal/operators/mergeInternals.ts", "node_modules/rxjs/src/internal/operators/mergeMap.ts", "node_modules/rxjs/src/internal/operators/mergeAll.ts", "node_modules/rxjs/src/internal/operators/concatAll.ts", "node_modules/rxjs/src/internal/observable/concat.ts", "node_modules/rxjs/src/internal/observable/defer.ts", "node_modules/rxjs/src/internal/observable/fromEvent.ts", "node_modules/rxjs/src/internal/observable/fromEventPattern.ts", "node_modules/rxjs/src/internal/observable/timer.ts", "node_modules/rxjs/src/internal/observable/merge.ts", "node_modules/rxjs/src/internal/observable/never.ts", "node_modules/rxjs/src/internal/util/argsOrArgArray.ts", "node_modules/rxjs/src/internal/operators/filter.ts", "node_modules/rxjs/src/internal/observable/zip.ts", "node_modules/rxjs/src/internal/operators/audit.ts", "node_modules/rxjs/src/internal/operators/auditTime.ts", "node_modules/rxjs/src/internal/operators/bufferCount.ts", "node_modules/rxjs/src/internal/operators/catchError.ts", "node_modules/rxjs/src/internal/operators/scanInternals.ts", "node_modules/rxjs/src/internal/operators/combineLatest.ts", "node_modules/rxjs/src/internal/operators/combineLatestWith.ts", "node_modules/rxjs/src/internal/operators/concatMap.ts", "node_modules/rxjs/src/internal/operators/debounceTime.ts", "node_modules/rxjs/src/internal/operators/defaultIfEmpty.ts", "node_modules/rxjs/src/internal/operators/take.ts", "node_modules/rxjs/src/internal/operators/ignoreElements.ts", "node_modules/rxjs/src/internal/operators/mapTo.ts", "node_modules/rxjs/src/internal/operators/delayWhen.ts", "node_modules/rxjs/src/internal/operators/delay.ts", "node_modules/rxjs/src/internal/operators/distinctUntilChanged.ts", "node_modules/rxjs/src/internal/operators/distinctUntilKeyChanged.ts", "node_modules/rxjs/src/internal/operators/endWith.ts", "node_modules/rxjs/src/internal/operators/finalize.ts", "node_modules/rxjs/src/internal/operators/takeLast.ts", "node_modules/rxjs/src/internal/operators/merge.ts", "node_modules/rxjs/src/internal/operators/mergeWith.ts", "node_modules/rxjs/src/internal/operators/repeat.ts", "node_modules/rxjs/src/internal/operators/sample.ts", "node_modules/rxjs/src/internal/operators/scan.ts", "node_modules/rxjs/src/internal/operators/share.ts", "node_modules/rxjs/src/internal/operators/shareReplay.ts", "node_modules/rxjs/src/internal/operators/skip.ts", "node_modules/rxjs/src/internal/operators/skipUntil.ts", "node_modules/rxjs/src/internal/operators/startWith.ts", "node_modules/rxjs/src/internal/operators/switchMap.ts", "node_modules/rxjs/src/internal/operators/takeUntil.ts", "node_modules/rxjs/src/internal/operators/takeWhile.ts", "node_modules/rxjs/src/internal/operators/tap.ts", "node_modules/rxjs/src/internal/operators/throttle.ts", "node_modules/rxjs/src/internal/operators/throttleTime.ts", "node_modules/rxjs/src/internal/operators/withLatestFrom.ts", "node_modules/rxjs/src/internal/operators/zip.ts", "node_modules/rxjs/src/internal/operators/zipWith.ts", "src/assets/javascripts/browser/document/index.ts", "src/assets/javascripts/browser/element/_/index.ts", "src/assets/javascripts/browser/element/focus/index.ts", "src/assets/javascripts/browser/element/offset/_/index.ts", "src/assets/javascripts/browser/element/offset/content/index.ts", "node_modules/resize-observer-polyfill/dist/ResizeObserver.es.js", "src/assets/javascripts/browser/element/size/_/index.ts", "src/assets/javascripts/browser/element/size/content/index.ts", "src/assets/javascripts/browser/element/visibility/index.ts", "src/assets/javascripts/browser/toggle/index.ts", "src/assets/javascripts/browser/keyboard/index.ts", "src/assets/javascripts/browser/location/_/index.ts", "src/assets/javascripts/utilities/h/index.ts", "src/assets/javascripts/utilities/string/index.ts", "src/assets/javascripts/browser/location/hash/index.ts", "src/assets/javascripts/browser/media/index.ts", "src/assets/javascripts/browser/request/index.ts", "src/assets/javascripts/browser/script/index.ts", "src/assets/javascripts/browser/viewport/offset/index.ts", "src/assets/javascripts/browser/viewport/size/index.ts", "src/assets/javascripts/browser/viewport/_/index.ts", "src/assets/javascripts/browser/viewport/at/index.ts", "src/assets/javascripts/browser/worker/index.ts", "src/assets/javascripts/_/index.ts", "src/assets/javascripts/components/_/index.ts", "src/assets/javascripts/components/announce/index.ts", "src/assets/javascripts/components/consent/index.ts", "src/assets/javascripts/components/content/code/_/index.ts", "src/assets/javascripts/templates/annotation/index.tsx", "src/assets/javascripts/templates/clipboard/index.tsx", "src/assets/javascripts/templates/search/index.tsx", "src/assets/javascripts/templates/source/index.tsx", "src/assets/javascripts/templates/tabbed/index.tsx", "src/assets/javascripts/templates/table/index.tsx", "src/assets/javascripts/templates/version/index.tsx", "src/assets/javascripts/components/content/annotation/_/index.ts", "src/assets/javascripts/components/content/annotation/list/index.ts", "src/assets/javascripts/components/content/code/mermaid/index.ts", "src/assets/javascripts/components/content/details/index.ts", "src/assets/javascripts/components/content/table/index.ts", "src/assets/javascripts/components/content/tabs/index.ts", "src/assets/javascripts/components/content/_/index.ts", "src/assets/javascripts/components/dialog/index.ts", "src/assets/javascripts/components/header/_/index.ts", "src/assets/javascripts/components/header/title/index.ts", "src/assets/javascripts/components/main/index.ts", "src/assets/javascripts/components/palette/index.ts", "src/assets/javascripts/integrations/clipboard/index.ts", "src/assets/javascripts/integrations/sitemap/index.ts", "src/assets/javascripts/integrations/instant/index.ts", "src/assets/javascripts/integrations/search/document/index.ts", "src/assets/javascripts/integrations/search/highlighter/index.ts", "src/assets/javascripts/integrations/search/query/transform/index.ts", "src/assets/javascripts/integrations/search/worker/message/index.ts", "src/assets/javascripts/integrations/search/worker/_/index.ts", "src/assets/javascripts/integrations/version/index.ts", "src/assets/javascripts/components/search/query/index.ts", "src/assets/javascripts/components/search/result/index.ts", "src/assets/javascripts/components/search/share/index.ts", "src/assets/javascripts/components/search/suggest/index.ts", "src/assets/javascripts/components/search/_/index.ts", "src/assets/javascripts/components/search/highlight/index.ts", "src/assets/javascripts/components/sidebar/index.ts", "src/assets/javascripts/components/source/facts/github/index.ts", "src/assets/javascripts/components/source/facts/gitlab/index.ts", "src/assets/javascripts/components/source/facts/_/index.ts", "src/assets/javascripts/components/source/_/index.ts", "src/assets/javascripts/components/tabs/index.ts", "src/assets/javascripts/components/toc/index.ts", "src/assets/javascripts/components/top/index.ts", "src/assets/javascripts/patches/indeterminate/index.ts", "src/assets/javascripts/patches/scrollfix/index.ts", "src/assets/javascripts/patches/scrolllock/index.ts", "src/assets/javascripts/polyfills/index.ts"], + "sourceRoot": "../../../..", + "sourcesContent": ["(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (factory());\n}(this, (function () { 'use strict';\n\n /**\n * Applies the :focus-visible polyfill at the given scope.\n * A scope in this case is either the top-level Document or a Shadow Root.\n *\n * @param {(Document|ShadowRoot)} scope\n * @see https://github.com/WICG/focus-visible\n */\n function applyFocusVisiblePolyfill(scope) {\n var hadKeyboardEvent = true;\n var hadFocusVisibleRecently = false;\n var hadFocusVisibleRecentlyTimeout = null;\n\n var inputTypesAllowlist = {\n text: true,\n search: true,\n url: true,\n tel: true,\n email: true,\n password: true,\n number: true,\n date: true,\n month: true,\n week: true,\n time: true,\n datetime: true,\n 'datetime-local': true\n };\n\n /**\n * Helper function for legacy browsers and iframes which sometimes focus\n * elements like document, body, and non-interactive SVG.\n * @param {Element} el\n */\n function isValidFocusTarget(el) {\n if (\n el &&\n el !== document &&\n el.nodeName !== 'HTML' &&\n el.nodeName !== 'BODY' &&\n 'classList' in el &&\n 'contains' in el.classList\n ) {\n return true;\n }\n return false;\n }\n\n /**\n * Computes whether the given element should automatically trigger the\n * `focus-visible` class being added, i.e. whether it should always match\n * `:focus-visible` when focused.\n * @param {Element} el\n * @return {boolean}\n */\n function focusTriggersKeyboardModality(el) {\n var type = el.type;\n var tagName = el.tagName;\n\n if (tagName === 'INPUT' && inputTypesAllowlist[type] && !el.readOnly) {\n return true;\n }\n\n if (tagName === 'TEXTAREA' && !el.readOnly) {\n return true;\n }\n\n if (el.isContentEditable) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Add the `focus-visible` class to the given element if it was not added by\n * the author.\n * @param {Element} el\n */\n function addFocusVisibleClass(el) {\n if (el.classList.contains('focus-visible')) {\n return;\n }\n el.classList.add('focus-visible');\n el.setAttribute('data-focus-visible-added', '');\n }\n\n /**\n * Remove the `focus-visible` class from the given element if it was not\n * originally added by the author.\n * @param {Element} el\n */\n function removeFocusVisibleClass(el) {\n if (!el.hasAttribute('data-focus-visible-added')) {\n return;\n }\n el.classList.remove('focus-visible');\n el.removeAttribute('data-focus-visible-added');\n }\n\n /**\n * If the most recent user interaction was via the keyboard;\n * and the key press did not include a meta, alt/option, or control key;\n * then the modality is keyboard. Otherwise, the modality is not keyboard.\n * Apply `focus-visible` to any current active element and keep track\n * of our keyboard modality state with `hadKeyboardEvent`.\n * @param {KeyboardEvent} e\n */\n function onKeyDown(e) {\n if (e.metaKey || e.altKey || e.ctrlKey) {\n return;\n }\n\n if (isValidFocusTarget(scope.activeElement)) {\n addFocusVisibleClass(scope.activeElement);\n }\n\n hadKeyboardEvent = true;\n }\n\n /**\n * If at any point a user clicks with a pointing device, ensure that we change\n * the modality away from keyboard.\n * This avoids the situation where a user presses a key on an already focused\n * element, and then clicks on a different element, focusing it with a\n * pointing device, while we still think we're in keyboard modality.\n * @param {Event} e\n */\n function onPointerDown(e) {\n hadKeyboardEvent = false;\n }\n\n /**\n * On `focus`, add the `focus-visible` class to the target if:\n * - the target received focus as a result of keyboard navigation, or\n * - the event target is an element that will likely require interaction\n * via the keyboard (e.g. a text box)\n * @param {Event} e\n */\n function onFocus(e) {\n // Prevent IE from focusing the document or HTML element.\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (hadKeyboardEvent || focusTriggersKeyboardModality(e.target)) {\n addFocusVisibleClass(e.target);\n }\n }\n\n /**\n * On `blur`, remove the `focus-visible` class from the target.\n * @param {Event} e\n */\n function onBlur(e) {\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (\n e.target.classList.contains('focus-visible') ||\n e.target.hasAttribute('data-focus-visible-added')\n ) {\n // To detect a tab/window switch, we look for a blur event followed\n // rapidly by a visibility change.\n // If we don't see a visibility change within 100ms, it's probably a\n // regular focus change.\n hadFocusVisibleRecently = true;\n window.clearTimeout(hadFocusVisibleRecentlyTimeout);\n hadFocusVisibleRecentlyTimeout = window.setTimeout(function() {\n hadFocusVisibleRecently = false;\n }, 100);\n removeFocusVisibleClass(e.target);\n }\n }\n\n /**\n * If the user changes tabs, keep track of whether or not the previously\n * focused element had .focus-visible.\n * @param {Event} e\n */\n function onVisibilityChange(e) {\n if (document.visibilityState === 'hidden') {\n // If the tab becomes active again, the browser will handle calling focus\n // on the element (Safari actually calls it twice).\n // If this tab change caused a blur on an element with focus-visible,\n // re-apply the class when the user switches back to the tab.\n if (hadFocusVisibleRecently) {\n hadKeyboardEvent = true;\n }\n addInitialPointerMoveListeners();\n }\n }\n\n /**\n * Add a group of listeners to detect usage of any pointing devices.\n * These listeners will be added when the polyfill first loads, and anytime\n * the window is blurred, so that they are active when the window regains\n * focus.\n */\n function addInitialPointerMoveListeners() {\n document.addEventListener('mousemove', onInitialPointerMove);\n document.addEventListener('mousedown', onInitialPointerMove);\n document.addEventListener('mouseup', onInitialPointerMove);\n document.addEventListener('pointermove', onInitialPointerMove);\n document.addEventListener('pointerdown', onInitialPointerMove);\n document.addEventListener('pointerup', onInitialPointerMove);\n document.addEventListener('touchmove', onInitialPointerMove);\n document.addEventListener('touchstart', onInitialPointerMove);\n document.addEventListener('touchend', onInitialPointerMove);\n }\n\n function removeInitialPointerMoveListeners() {\n document.removeEventListener('mousemove', onInitialPointerMove);\n document.removeEventListener('mousedown', onInitialPointerMove);\n document.removeEventListener('mouseup', onInitialPointerMove);\n document.removeEventListener('pointermove', onInitialPointerMove);\n document.removeEventListener('pointerdown', onInitialPointerMove);\n document.removeEventListener('pointerup', onInitialPointerMove);\n document.removeEventListener('touchmove', onInitialPointerMove);\n document.removeEventListener('touchstart', onInitialPointerMove);\n document.removeEventListener('touchend', onInitialPointerMove);\n }\n\n /**\n * When the polfyill first loads, assume the user is in keyboard modality.\n * If any event is received from a pointing device (e.g. mouse, pointer,\n * touch), turn off keyboard modality.\n * This accounts for situations where focus enters the page from the URL bar.\n * @param {Event} e\n */\n function onInitialPointerMove(e) {\n // Work around a Safari quirk that fires a mousemove on whenever the\n // window blurs, even if you're tabbing out of the page. \u00AF\\_(\u30C4)_/\u00AF\n if (e.target.nodeName && e.target.nodeName.toLowerCase() === 'html') {\n return;\n }\n\n hadKeyboardEvent = false;\n removeInitialPointerMoveListeners();\n }\n\n // For some kinds of state, we are interested in changes at the global scope\n // only. For example, global pointer input, global key presses and global\n // visibility change should affect the state at every scope:\n document.addEventListener('keydown', onKeyDown, true);\n document.addEventListener('mousedown', onPointerDown, true);\n document.addEventListener('pointerdown', onPointerDown, true);\n document.addEventListener('touchstart', onPointerDown, true);\n document.addEventListener('visibilitychange', onVisibilityChange, true);\n\n addInitialPointerMoveListeners();\n\n // For focus and blur, we specifically care about state changes in the local\n // scope. This is because focus / blur events that originate from within a\n // shadow root are not re-dispatched from the host element if it was already\n // the active element in its own scope:\n scope.addEventListener('focus', onFocus, true);\n scope.addEventListener('blur', onBlur, true);\n\n // We detect that a node is a ShadowRoot by ensuring that it is a\n // DocumentFragment and also has a host property. This check covers native\n // implementation and polyfill implementation transparently. If we only cared\n // about the native implementation, we could just check if the scope was\n // an instance of a ShadowRoot.\n if (scope.nodeType === Node.DOCUMENT_FRAGMENT_NODE && scope.host) {\n // Since a ShadowRoot is a special kind of DocumentFragment, it does not\n // have a root element to add a class to. So, we add this attribute to the\n // host element instead:\n scope.host.setAttribute('data-js-focus-visible', '');\n } else if (scope.nodeType === Node.DOCUMENT_NODE) {\n document.documentElement.classList.add('js-focus-visible');\n document.documentElement.setAttribute('data-js-focus-visible', '');\n }\n }\n\n // It is important to wrap all references to global window and document in\n // these checks to support server-side rendering use cases\n // @see https://github.com/WICG/focus-visible/issues/199\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n // Make the polyfill helper globally available. This can be used as a signal\n // to interested libraries that wish to coordinate with the polyfill for e.g.,\n // applying the polyfill to a shadow root:\n window.applyFocusVisiblePolyfill = applyFocusVisiblePolyfill;\n\n // Notify interested libraries of the polyfill's presence, in case the\n // polyfill was loaded lazily:\n var event;\n\n try {\n event = new CustomEvent('focus-visible-polyfill-ready');\n } catch (error) {\n // IE11 does not support using CustomEvent as a constructor directly:\n event = document.createEvent('CustomEvent');\n event.initCustomEvent('focus-visible-polyfill-ready', false, false, {});\n }\n\n window.dispatchEvent(event);\n }\n\n if (typeof document !== 'undefined') {\n // Apply the polyfill to the global document, so that no JavaScript\n // coordination is required to use the polyfill in the top-level document:\n applyFocusVisiblePolyfill(document);\n }\n\n})));\n", "(function(global) {\r\n /**\r\n * Polyfill URLSearchParams\r\n *\r\n * Inspired from : https://github.com/WebReflection/url-search-params/blob/master/src/url-search-params.js\r\n */\r\n\r\n var checkIfIteratorIsSupported = function() {\r\n try {\r\n return !!Symbol.iterator;\r\n } catch (error) {\r\n return false;\r\n }\r\n };\r\n\r\n\r\n var iteratorSupported = checkIfIteratorIsSupported();\r\n\r\n var createIterator = function(items) {\r\n var iterator = {\r\n next: function() {\r\n var value = items.shift();\r\n return { done: value === void 0, value: value };\r\n }\r\n };\r\n\r\n if (iteratorSupported) {\r\n iterator[Symbol.iterator] = function() {\r\n return iterator;\r\n };\r\n }\r\n\r\n return iterator;\r\n };\r\n\r\n /**\r\n * Search param name and values should be encoded according to https://url.spec.whatwg.org/#urlencoded-serializing\r\n * encodeURIComponent() produces the same result except encoding spaces as `%20` instead of `+`.\r\n */\r\n var serializeParam = function(value) {\r\n return encodeURIComponent(value).replace(/%20/g, '+');\r\n };\r\n\r\n var deserializeParam = function(value) {\r\n return decodeURIComponent(String(value).replace(/\\+/g, ' '));\r\n };\r\n\r\n var polyfillURLSearchParams = function() {\r\n\r\n var URLSearchParams = function(searchString) {\r\n Object.defineProperty(this, '_entries', { writable: true, value: {} });\r\n var typeofSearchString = typeof searchString;\r\n\r\n if (typeofSearchString === 'undefined') {\r\n // do nothing\r\n } else if (typeofSearchString === 'string') {\r\n if (searchString !== '') {\r\n this._fromString(searchString);\r\n }\r\n } else if (searchString instanceof URLSearchParams) {\r\n var _this = this;\r\n searchString.forEach(function(value, name) {\r\n _this.append(name, value);\r\n });\r\n } else if ((searchString !== null) && (typeofSearchString === 'object')) {\r\n if (Object.prototype.toString.call(searchString) === '[object Array]') {\r\n for (var i = 0; i < searchString.length; i++) {\r\n var entry = searchString[i];\r\n if ((Object.prototype.toString.call(entry) === '[object Array]') || (entry.length !== 2)) {\r\n this.append(entry[0], entry[1]);\r\n } else {\r\n throw new TypeError('Expected [string, any] as entry at index ' + i + ' of URLSearchParams\\'s input');\r\n }\r\n }\r\n } else {\r\n for (var key in searchString) {\r\n if (searchString.hasOwnProperty(key)) {\r\n this.append(key, searchString[key]);\r\n }\r\n }\r\n }\r\n } else {\r\n throw new TypeError('Unsupported input\\'s type for URLSearchParams');\r\n }\r\n };\r\n\r\n var proto = URLSearchParams.prototype;\r\n\r\n proto.append = function(name, value) {\r\n if (name in this._entries) {\r\n this._entries[name].push(String(value));\r\n } else {\r\n this._entries[name] = [String(value)];\r\n }\r\n };\r\n\r\n proto.delete = function(name) {\r\n delete this._entries[name];\r\n };\r\n\r\n proto.get = function(name) {\r\n return (name in this._entries) ? this._entries[name][0] : null;\r\n };\r\n\r\n proto.getAll = function(name) {\r\n return (name in this._entries) ? this._entries[name].slice(0) : [];\r\n };\r\n\r\n proto.has = function(name) {\r\n return (name in this._entries);\r\n };\r\n\r\n proto.set = function(name, value) {\r\n this._entries[name] = [String(value)];\r\n };\r\n\r\n proto.forEach = function(callback, thisArg) {\r\n var entries;\r\n for (var name in this._entries) {\r\n if (this._entries.hasOwnProperty(name)) {\r\n entries = this._entries[name];\r\n for (var i = 0; i < entries.length; i++) {\r\n callback.call(thisArg, entries[i], name, this);\r\n }\r\n }\r\n }\r\n };\r\n\r\n proto.keys = function() {\r\n var items = [];\r\n this.forEach(function(value, name) {\r\n items.push(name);\r\n });\r\n return createIterator(items);\r\n };\r\n\r\n proto.values = function() {\r\n var items = [];\r\n this.forEach(function(value) {\r\n items.push(value);\r\n });\r\n return createIterator(items);\r\n };\r\n\r\n proto.entries = function() {\r\n var items = [];\r\n this.forEach(function(value, name) {\r\n items.push([name, value]);\r\n });\r\n return createIterator(items);\r\n };\r\n\r\n if (iteratorSupported) {\r\n proto[Symbol.iterator] = proto.entries;\r\n }\r\n\r\n proto.toString = function() {\r\n var searchArray = [];\r\n this.forEach(function(value, name) {\r\n searchArray.push(serializeParam(name) + '=' + serializeParam(value));\r\n });\r\n return searchArray.join('&');\r\n };\r\n\r\n\r\n global.URLSearchParams = URLSearchParams;\r\n };\r\n\r\n var checkIfURLSearchParamsSupported = function() {\r\n try {\r\n var URLSearchParams = global.URLSearchParams;\r\n\r\n return (\r\n (new URLSearchParams('?a=1').toString() === 'a=1') &&\r\n (typeof URLSearchParams.prototype.set === 'function') &&\r\n (typeof URLSearchParams.prototype.entries === 'function')\r\n );\r\n } catch (e) {\r\n return false;\r\n }\r\n };\r\n\r\n if (!checkIfURLSearchParamsSupported()) {\r\n polyfillURLSearchParams();\r\n }\r\n\r\n var proto = global.URLSearchParams.prototype;\r\n\r\n if (typeof proto.sort !== 'function') {\r\n proto.sort = function() {\r\n var _this = this;\r\n var items = [];\r\n this.forEach(function(value, name) {\r\n items.push([name, value]);\r\n if (!_this._entries) {\r\n _this.delete(name);\r\n }\r\n });\r\n items.sort(function(a, b) {\r\n if (a[0] < b[0]) {\r\n return -1;\r\n } else if (a[0] > b[0]) {\r\n return +1;\r\n } else {\r\n return 0;\r\n }\r\n });\r\n if (_this._entries) { // force reset because IE keeps keys index\r\n _this._entries = {};\r\n }\r\n for (var i = 0; i < items.length; i++) {\r\n this.append(items[i][0], items[i][1]);\r\n }\r\n };\r\n }\r\n\r\n if (typeof proto._fromString !== 'function') {\r\n Object.defineProperty(proto, '_fromString', {\r\n enumerable: false,\r\n configurable: false,\r\n writable: false,\r\n value: function(searchString) {\r\n if (this._entries) {\r\n this._entries = {};\r\n } else {\r\n var keys = [];\r\n this.forEach(function(value, name) {\r\n keys.push(name);\r\n });\r\n for (var i = 0; i < keys.length; i++) {\r\n this.delete(keys[i]);\r\n }\r\n }\r\n\r\n searchString = searchString.replace(/^\\?/, '');\r\n var attributes = searchString.split('&');\r\n var attribute;\r\n for (var i = 0; i < attributes.length; i++) {\r\n attribute = attributes[i].split('=');\r\n this.append(\r\n deserializeParam(attribute[0]),\r\n (attribute.length > 1) ? deserializeParam(attribute[1]) : ''\r\n );\r\n }\r\n }\r\n });\r\n }\r\n\r\n // HTMLAnchorElement\r\n\r\n})(\r\n (typeof global !== 'undefined') ? global\r\n : ((typeof window !== 'undefined') ? window\r\n : ((typeof self !== 'undefined') ? self : this))\r\n);\r\n\r\n(function(global) {\r\n /**\r\n * Polyfill URL\r\n *\r\n * Inspired from : https://github.com/arv/DOM-URL-Polyfill/blob/master/src/url.js\r\n */\r\n\r\n var checkIfURLIsSupported = function() {\r\n try {\r\n var u = new global.URL('b', 'http://a');\r\n u.pathname = 'c d';\r\n return (u.href === 'http://a/c%20d') && u.searchParams;\r\n } catch (e) {\r\n return false;\r\n }\r\n };\r\n\r\n\r\n var polyfillURL = function() {\r\n var _URL = global.URL;\r\n\r\n var URL = function(url, base) {\r\n if (typeof url !== 'string') url = String(url);\r\n if (base && typeof base !== 'string') base = String(base);\r\n\r\n // Only create another document if the base is different from current location.\r\n var doc = document, baseElement;\r\n if (base && (global.location === void 0 || base !== global.location.href)) {\r\n base = base.toLowerCase();\r\n doc = document.implementation.createHTMLDocument('');\r\n baseElement = doc.createElement('base');\r\n baseElement.href = base;\r\n doc.head.appendChild(baseElement);\r\n try {\r\n if (baseElement.href.indexOf(base) !== 0) throw new Error(baseElement.href);\r\n } catch (err) {\r\n throw new Error('URL unable to set base ' + base + ' due to ' + err);\r\n }\r\n }\r\n\r\n var anchorElement = doc.createElement('a');\r\n anchorElement.href = url;\r\n if (baseElement) {\r\n doc.body.appendChild(anchorElement);\r\n anchorElement.href = anchorElement.href; // force href to refresh\r\n }\r\n\r\n var inputElement = doc.createElement('input');\r\n inputElement.type = 'url';\r\n inputElement.value = url;\r\n\r\n if (anchorElement.protocol === ':' || !/:/.test(anchorElement.href) || (!inputElement.checkValidity() && !base)) {\r\n throw new TypeError('Invalid URL');\r\n }\r\n\r\n Object.defineProperty(this, '_anchorElement', {\r\n value: anchorElement\r\n });\r\n\r\n\r\n // create a linked searchParams which reflect its changes on URL\r\n var searchParams = new global.URLSearchParams(this.search);\r\n var enableSearchUpdate = true;\r\n var enableSearchParamsUpdate = true;\r\n var _this = this;\r\n ['append', 'delete', 'set'].forEach(function(methodName) {\r\n var method = searchParams[methodName];\r\n searchParams[methodName] = function() {\r\n method.apply(searchParams, arguments);\r\n if (enableSearchUpdate) {\r\n enableSearchParamsUpdate = false;\r\n _this.search = searchParams.toString();\r\n enableSearchParamsUpdate = true;\r\n }\r\n };\r\n });\r\n\r\n Object.defineProperty(this, 'searchParams', {\r\n value: searchParams,\r\n enumerable: true\r\n });\r\n\r\n var search = void 0;\r\n Object.defineProperty(this, '_updateSearchParams', {\r\n enumerable: false,\r\n configurable: false,\r\n writable: false,\r\n value: function() {\r\n if (this.search !== search) {\r\n search = this.search;\r\n if (enableSearchParamsUpdate) {\r\n enableSearchUpdate = false;\r\n this.searchParams._fromString(this.search);\r\n enableSearchUpdate = true;\r\n }\r\n }\r\n }\r\n });\r\n };\r\n\r\n var proto = URL.prototype;\r\n\r\n var linkURLWithAnchorAttribute = function(attributeName) {\r\n Object.defineProperty(proto, attributeName, {\r\n get: function() {\r\n return this._anchorElement[attributeName];\r\n },\r\n set: function(value) {\r\n this._anchorElement[attributeName] = value;\r\n },\r\n enumerable: true\r\n });\r\n };\r\n\r\n ['hash', 'host', 'hostname', 'port', 'protocol']\r\n .forEach(function(attributeName) {\r\n linkURLWithAnchorAttribute(attributeName);\r\n });\r\n\r\n Object.defineProperty(proto, 'search', {\r\n get: function() {\r\n return this._anchorElement['search'];\r\n },\r\n set: function(value) {\r\n this._anchorElement['search'] = value;\r\n this._updateSearchParams();\r\n },\r\n enumerable: true\r\n });\r\n\r\n Object.defineProperties(proto, {\r\n\r\n 'toString': {\r\n get: function() {\r\n var _this = this;\r\n return function() {\r\n return _this.href;\r\n };\r\n }\r\n },\r\n\r\n 'href': {\r\n get: function() {\r\n return this._anchorElement.href.replace(/\\?$/, '');\r\n },\r\n set: function(value) {\r\n this._anchorElement.href = value;\r\n this._updateSearchParams();\r\n },\r\n enumerable: true\r\n },\r\n\r\n 'pathname': {\r\n get: function() {\r\n return this._anchorElement.pathname.replace(/(^\\/?)/, '/');\r\n },\r\n set: function(value) {\r\n this._anchorElement.pathname = value;\r\n },\r\n enumerable: true\r\n },\r\n\r\n 'origin': {\r\n get: function() {\r\n // get expected port from protocol\r\n var expectedPort = { 'http:': 80, 'https:': 443, 'ftp:': 21 }[this._anchorElement.protocol];\r\n // add port to origin if, expected port is different than actual port\r\n // and it is not empty f.e http://foo:8080\r\n // 8080 != 80 && 8080 != ''\r\n var addPortToOrigin = this._anchorElement.port != expectedPort &&\r\n this._anchorElement.port !== '';\r\n\r\n return this._anchorElement.protocol +\r\n '//' +\r\n this._anchorElement.hostname +\r\n (addPortToOrigin ? (':' + this._anchorElement.port) : '');\r\n },\r\n enumerable: true\r\n },\r\n\r\n 'password': { // TODO\r\n get: function() {\r\n return '';\r\n },\r\n set: function(value) {\r\n },\r\n enumerable: true\r\n },\r\n\r\n 'username': { // TODO\r\n get: function() {\r\n return '';\r\n },\r\n set: function(value) {\r\n },\r\n enumerable: true\r\n },\r\n });\r\n\r\n URL.createObjectURL = function(blob) {\r\n return _URL.createObjectURL.apply(_URL, arguments);\r\n };\r\n\r\n URL.revokeObjectURL = function(url) {\r\n return _URL.revokeObjectURL.apply(_URL, arguments);\r\n };\r\n\r\n global.URL = URL;\r\n\r\n };\r\n\r\n if (!checkIfURLIsSupported()) {\r\n polyfillURL();\r\n }\r\n\r\n if ((global.location !== void 0) && !('origin' in global.location)) {\r\n var getOrigin = function() {\r\n return global.location.protocol + '//' + global.location.hostname + (global.location.port ? (':' + global.location.port) : '');\r\n };\r\n\r\n try {\r\n Object.defineProperty(global.location, 'origin', {\r\n get: getOrigin,\r\n enumerable: true\r\n });\r\n } catch (e) {\r\n setInterval(function() {\r\n global.location.origin = getOrigin();\r\n }, 100);\r\n }\r\n }\r\n\r\n})(\r\n (typeof global !== 'undefined') ? global\r\n : ((typeof window !== 'undefined') ? window\r\n : ((typeof self !== 'undefined') ? self : this))\r\n);\r\n", "/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global global, define, System, Reflect, Promise */\r\nvar __extends;\r\nvar __assign;\r\nvar __rest;\r\nvar __decorate;\r\nvar __param;\r\nvar __metadata;\r\nvar __awaiter;\r\nvar __generator;\r\nvar __exportStar;\r\nvar __values;\r\nvar __read;\r\nvar __spread;\r\nvar __spreadArrays;\r\nvar __spreadArray;\r\nvar __await;\r\nvar __asyncGenerator;\r\nvar __asyncDelegator;\r\nvar __asyncValues;\r\nvar __makeTemplateObject;\r\nvar __importStar;\r\nvar __importDefault;\r\nvar __classPrivateFieldGet;\r\nvar __classPrivateFieldSet;\r\nvar __createBinding;\r\n(function (factory) {\r\n var root = typeof global === \"object\" ? global : typeof self === \"object\" ? self : typeof this === \"object\" ? this : {};\r\n if (typeof define === \"function\" && define.amd) {\r\n define(\"tslib\", [\"exports\"], function (exports) { factory(createExporter(root, createExporter(exports))); });\r\n }\r\n else if (typeof module === \"object\" && typeof module.exports === \"object\") {\r\n factory(createExporter(root, createExporter(module.exports)));\r\n }\r\n else {\r\n factory(createExporter(root));\r\n }\r\n function createExporter(exports, previous) {\r\n if (exports !== root) {\r\n if (typeof Object.create === \"function\") {\r\n Object.defineProperty(exports, \"__esModule\", { value: true });\r\n }\r\n else {\r\n exports.__esModule = true;\r\n }\r\n }\r\n return function (id, v) { return exports[id] = previous ? previous(id, v) : v; };\r\n }\r\n})\r\n(function (exporter) {\r\n var extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n\r\n __extends = function (d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n };\r\n\r\n __assign = Object.assign || function (t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n };\r\n\r\n __rest = function (s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n };\r\n\r\n __decorate = function (decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n };\r\n\r\n __param = function (paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n };\r\n\r\n __metadata = function (metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n };\r\n\r\n __awaiter = function (thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n };\r\n\r\n __generator = function (thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n };\r\n\r\n __exportStar = function(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n };\r\n\r\n __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n }) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n });\r\n\r\n __values = function (o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n };\r\n\r\n __read = function (o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n };\r\n\r\n /** @deprecated */\r\n __spread = function () {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n };\r\n\r\n /** @deprecated */\r\n __spreadArrays = function () {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n };\r\n\r\n __spreadArray = function (to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n };\r\n\r\n __await = function (v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n };\r\n\r\n __asyncGenerator = function (thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n };\r\n\r\n __asyncDelegator = function (o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n };\r\n\r\n __asyncValues = function (o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n };\r\n\r\n __makeTemplateObject = function (cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n };\r\n\r\n var __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n }) : function(o, v) {\r\n o[\"default\"] = v;\r\n };\r\n\r\n __importStar = function (mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n };\r\n\r\n __importDefault = function (mod) {\r\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\r\n };\r\n\r\n __classPrivateFieldGet = function (receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n };\r\n\r\n __classPrivateFieldSet = function (receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n };\r\n\r\n exporter(\"__extends\", __extends);\r\n exporter(\"__assign\", __assign);\r\n exporter(\"__rest\", __rest);\r\n exporter(\"__decorate\", __decorate);\r\n exporter(\"__param\", __param);\r\n exporter(\"__metadata\", __metadata);\r\n exporter(\"__awaiter\", __awaiter);\r\n exporter(\"__generator\", __generator);\r\n exporter(\"__exportStar\", __exportStar);\r\n exporter(\"__createBinding\", __createBinding);\r\n exporter(\"__values\", __values);\r\n exporter(\"__read\", __read);\r\n exporter(\"__spread\", __spread);\r\n exporter(\"__spreadArrays\", __spreadArrays);\r\n exporter(\"__spreadArray\", __spreadArray);\r\n exporter(\"__await\", __await);\r\n exporter(\"__asyncGenerator\", __asyncGenerator);\r\n exporter(\"__asyncDelegator\", __asyncDelegator);\r\n exporter(\"__asyncValues\", __asyncValues);\r\n exporter(\"__makeTemplateObject\", __makeTemplateObject);\r\n exporter(\"__importStar\", __importStar);\r\n exporter(\"__importDefault\", __importDefault);\r\n exporter(\"__classPrivateFieldGet\", __classPrivateFieldGet);\r\n exporter(\"__classPrivateFieldSet\", __classPrivateFieldSet);\r\n});\r\n", "/*!\n * clipboard.js v2.0.11\n * https://clipboardjs.com/\n *\n * Licensed MIT \u00A9 Zeno Rocha\n */\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ClipboardJS\"] = factory();\n\telse\n\t\troot[\"ClipboardJS\"] = factory();\n})(this, function() {\nreturn /******/ (function() { // webpackBootstrap\n/******/ \tvar __webpack_modules__ = ({\n\n/***/ 686:\n/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n \"default\": function() { return /* binding */ clipboard; }\n});\n\n// EXTERNAL MODULE: ./node_modules/tiny-emitter/index.js\nvar tiny_emitter = __webpack_require__(279);\nvar tiny_emitter_default = /*#__PURE__*/__webpack_require__.n(tiny_emitter);\n// EXTERNAL MODULE: ./node_modules/good-listener/src/listen.js\nvar listen = __webpack_require__(370);\nvar listen_default = /*#__PURE__*/__webpack_require__.n(listen);\n// EXTERNAL MODULE: ./node_modules/select/src/select.js\nvar src_select = __webpack_require__(817);\nvar select_default = /*#__PURE__*/__webpack_require__.n(src_select);\n;// CONCATENATED MODULE: ./src/common/command.js\n/**\n * Executes a given operation type.\n * @param {String} type\n * @return {Boolean}\n */\nfunction command(type) {\n try {\n return document.execCommand(type);\n } catch (err) {\n return false;\n }\n}\n;// CONCATENATED MODULE: ./src/actions/cut.js\n\n\n/**\n * Cut action wrapper.\n * @param {String|HTMLElement} target\n * @return {String}\n */\n\nvar ClipboardActionCut = function ClipboardActionCut(target) {\n var selectedText = select_default()(target);\n command('cut');\n return selectedText;\n};\n\n/* harmony default export */ var actions_cut = (ClipboardActionCut);\n;// CONCATENATED MODULE: ./src/common/create-fake-element.js\n/**\n * Creates a fake textarea element with a value.\n * @param {String} value\n * @return {HTMLElement}\n */\nfunction createFakeElement(value) {\n var isRTL = document.documentElement.getAttribute('dir') === 'rtl';\n var fakeElement = document.createElement('textarea'); // Prevent zooming on iOS\n\n fakeElement.style.fontSize = '12pt'; // Reset box model\n\n fakeElement.style.border = '0';\n fakeElement.style.padding = '0';\n fakeElement.style.margin = '0'; // Move element out of screen horizontally\n\n fakeElement.style.position = 'absolute';\n fakeElement.style[isRTL ? 'right' : 'left'] = '-9999px'; // Move element to the same position vertically\n\n var yPosition = window.pageYOffset || document.documentElement.scrollTop;\n fakeElement.style.top = \"\".concat(yPosition, \"px\");\n fakeElement.setAttribute('readonly', '');\n fakeElement.value = value;\n return fakeElement;\n}\n;// CONCATENATED MODULE: ./src/actions/copy.js\n\n\n\n/**\n * Create fake copy action wrapper using a fake element.\n * @param {String} target\n * @param {Object} options\n * @return {String}\n */\n\nvar fakeCopyAction = function fakeCopyAction(value, options) {\n var fakeElement = createFakeElement(value);\n options.container.appendChild(fakeElement);\n var selectedText = select_default()(fakeElement);\n command('copy');\n fakeElement.remove();\n return selectedText;\n};\n/**\n * Copy action wrapper.\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @return {String}\n */\n\n\nvar ClipboardActionCopy = function ClipboardActionCopy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n var selectedText = '';\n\n if (typeof target === 'string') {\n selectedText = fakeCopyAction(target, options);\n } else if (target instanceof HTMLInputElement && !['text', 'search', 'url', 'tel', 'password'].includes(target === null || target === void 0 ? void 0 : target.type)) {\n // If input type doesn't support `setSelectionRange`. Simulate it. https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange\n selectedText = fakeCopyAction(target.value, options);\n } else {\n selectedText = select_default()(target);\n command('copy');\n }\n\n return selectedText;\n};\n\n/* harmony default export */ var actions_copy = (ClipboardActionCopy);\n;// CONCATENATED MODULE: ./src/actions/default.js\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n\n\n/**\n * Inner function which performs selection from either `text` or `target`\n * properties and then executes copy or cut operations.\n * @param {Object} options\n */\n\nvar ClipboardActionDefault = function ClipboardActionDefault() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n // Defines base properties passed from constructor.\n var _options$action = options.action,\n action = _options$action === void 0 ? 'copy' : _options$action,\n container = options.container,\n target = options.target,\n text = options.text; // Sets the `action` to be performed which can be either 'copy' or 'cut'.\n\n if (action !== 'copy' && action !== 'cut') {\n throw new Error('Invalid \"action\" value, use either \"copy\" or \"cut\"');\n } // Sets the `target` property using an element that will be have its content copied.\n\n\n if (target !== undefined) {\n if (target && _typeof(target) === 'object' && target.nodeType === 1) {\n if (action === 'copy' && target.hasAttribute('disabled')) {\n throw new Error('Invalid \"target\" attribute. Please use \"readonly\" instead of \"disabled\" attribute');\n }\n\n if (action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {\n throw new Error('Invalid \"target\" attribute. You can\\'t cut text from elements with \"readonly\" or \"disabled\" attributes');\n }\n } else {\n throw new Error('Invalid \"target\" value, use a valid Element');\n }\n } // Define selection strategy based on `text` property.\n\n\n if (text) {\n return actions_copy(text, {\n container: container\n });\n } // Defines which selection strategy based on `target` property.\n\n\n if (target) {\n return action === 'cut' ? actions_cut(target) : actions_copy(target, {\n container: container\n });\n }\n};\n\n/* harmony default export */ var actions_default = (ClipboardActionDefault);\n;// CONCATENATED MODULE: ./src/clipboard.js\nfunction clipboard_typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { clipboard_typeof = function _typeof(obj) { return typeof obj; }; } else { clipboard_typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return clipboard_typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (clipboard_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n\n\n\n\n\n/**\n * Helper function to retrieve attribute value.\n * @param {String} suffix\n * @param {Element} element\n */\n\nfunction getAttributeValue(suffix, element) {\n var attribute = \"data-clipboard-\".concat(suffix);\n\n if (!element.hasAttribute(attribute)) {\n return;\n }\n\n return element.getAttribute(attribute);\n}\n/**\n * Base class which takes one or more elements, adds event listeners to them,\n * and instantiates a new `ClipboardAction` on each click.\n */\n\n\nvar Clipboard = /*#__PURE__*/function (_Emitter) {\n _inherits(Clipboard, _Emitter);\n\n var _super = _createSuper(Clipboard);\n\n /**\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n * @param {Object} options\n */\n function Clipboard(trigger, options) {\n var _this;\n\n _classCallCheck(this, Clipboard);\n\n _this = _super.call(this);\n\n _this.resolveOptions(options);\n\n _this.listenClick(trigger);\n\n return _this;\n }\n /**\n * Defines if attributes would be resolved using internal setter functions\n * or custom functions that were passed in the constructor.\n * @param {Object} options\n */\n\n\n _createClass(Clipboard, [{\n key: \"resolveOptions\",\n value: function resolveOptions() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n this.action = typeof options.action === 'function' ? options.action : this.defaultAction;\n this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;\n this.text = typeof options.text === 'function' ? options.text : this.defaultText;\n this.container = clipboard_typeof(options.container) === 'object' ? options.container : document.body;\n }\n /**\n * Adds a click event listener to the passed trigger.\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n */\n\n }, {\n key: \"listenClick\",\n value: function listenClick(trigger) {\n var _this2 = this;\n\n this.listener = listen_default()(trigger, 'click', function (e) {\n return _this2.onClick(e);\n });\n }\n /**\n * Defines a new `ClipboardAction` on each click event.\n * @param {Event} e\n */\n\n }, {\n key: \"onClick\",\n value: function onClick(e) {\n var trigger = e.delegateTarget || e.currentTarget;\n var action = this.action(trigger) || 'copy';\n var text = actions_default({\n action: action,\n container: this.container,\n target: this.target(trigger),\n text: this.text(trigger)\n }); // Fires an event based on the copy operation result.\n\n this.emit(text ? 'success' : 'error', {\n action: action,\n text: text,\n trigger: trigger,\n clearSelection: function clearSelection() {\n if (trigger) {\n trigger.focus();\n }\n\n window.getSelection().removeAllRanges();\n }\n });\n }\n /**\n * Default `action` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultAction\",\n value: function defaultAction(trigger) {\n return getAttributeValue('action', trigger);\n }\n /**\n * Default `target` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultTarget\",\n value: function defaultTarget(trigger) {\n var selector = getAttributeValue('target', trigger);\n\n if (selector) {\n return document.querySelector(selector);\n }\n }\n /**\n * Allow fire programmatically a copy action\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @returns Text copied.\n */\n\n }, {\n key: \"defaultText\",\n\n /**\n * Default `text` lookup function.\n * @param {Element} trigger\n */\n value: function defaultText(trigger) {\n return getAttributeValue('text', trigger);\n }\n /**\n * Destroy lifecycle.\n */\n\n }, {\n key: \"destroy\",\n value: function destroy() {\n this.listener.destroy();\n }\n }], [{\n key: \"copy\",\n value: function copy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n return actions_copy(target, options);\n }\n /**\n * Allow fire programmatically a cut action\n * @param {String|HTMLElement} target\n * @returns Text cutted.\n */\n\n }, {\n key: \"cut\",\n value: function cut(target) {\n return actions_cut(target);\n }\n /**\n * Returns the support of the given action, or all actions if no action is\n * given.\n * @param {String} [action]\n */\n\n }, {\n key: \"isSupported\",\n value: function isSupported() {\n var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut'];\n var actions = typeof action === 'string' ? [action] : action;\n var support = !!document.queryCommandSupported;\n actions.forEach(function (action) {\n support = support && !!document.queryCommandSupported(action);\n });\n return support;\n }\n }]);\n\n return Clipboard;\n}((tiny_emitter_default()));\n\n/* harmony default export */ var clipboard = (Clipboard);\n\n/***/ }),\n\n/***/ 828:\n/***/ (function(module) {\n\nvar DOCUMENT_NODE_TYPE = 9;\n\n/**\n * A polyfill for Element.matches()\n */\nif (typeof Element !== 'undefined' && !Element.prototype.matches) {\n var proto = Element.prototype;\n\n proto.matches = proto.matchesSelector ||\n proto.mozMatchesSelector ||\n proto.msMatchesSelector ||\n proto.oMatchesSelector ||\n proto.webkitMatchesSelector;\n}\n\n/**\n * Finds the closest parent that matches a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @return {Function}\n */\nfunction closest (element, selector) {\n while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {\n if (typeof element.matches === 'function' &&\n element.matches(selector)) {\n return element;\n }\n element = element.parentNode;\n }\n}\n\nmodule.exports = closest;\n\n\n/***/ }),\n\n/***/ 438:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar closest = __webpack_require__(828);\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction _delegate(element, selector, type, callback, useCapture) {\n var listenerFn = listener.apply(this, arguments);\n\n element.addEventListener(type, listenerFn, useCapture);\n\n return {\n destroy: function() {\n element.removeEventListener(type, listenerFn, useCapture);\n }\n }\n}\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element|String|Array} [elements]\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction delegate(elements, selector, type, callback, useCapture) {\n // Handle the regular Element usage\n if (typeof elements.addEventListener === 'function') {\n return _delegate.apply(null, arguments);\n }\n\n // Handle Element-less usage, it defaults to global delegation\n if (typeof type === 'function') {\n // Use `document` as the first parameter, then apply arguments\n // This is a short way to .unshift `arguments` without running into deoptimizations\n return _delegate.bind(null, document).apply(null, arguments);\n }\n\n // Handle Selector-based usage\n if (typeof elements === 'string') {\n elements = document.querySelectorAll(elements);\n }\n\n // Handle Array-like based usage\n return Array.prototype.map.call(elements, function (element) {\n return _delegate(element, selector, type, callback, useCapture);\n });\n}\n\n/**\n * Finds closest match and invokes callback.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Function}\n */\nfunction listener(element, selector, type, callback) {\n return function(e) {\n e.delegateTarget = closest(e.target, selector);\n\n if (e.delegateTarget) {\n callback.call(element, e);\n }\n }\n}\n\nmodule.exports = delegate;\n\n\n/***/ }),\n\n/***/ 879:\n/***/ (function(__unused_webpack_module, exports) {\n\n/**\n * Check if argument is a HTML element.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.node = function(value) {\n return value !== undefined\n && value instanceof HTMLElement\n && value.nodeType === 1;\n};\n\n/**\n * Check if argument is a list of HTML elements.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.nodeList = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return value !== undefined\n && (type === '[object NodeList]' || type === '[object HTMLCollection]')\n && ('length' in value)\n && (value.length === 0 || exports.node(value[0]));\n};\n\n/**\n * Check if argument is a string.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.string = function(value) {\n return typeof value === 'string'\n || value instanceof String;\n};\n\n/**\n * Check if argument is a function.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.fn = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return type === '[object Function]';\n};\n\n\n/***/ }),\n\n/***/ 370:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar is = __webpack_require__(879);\nvar delegate = __webpack_require__(438);\n\n/**\n * Validates all params and calls the right\n * listener function based on its target type.\n *\n * @param {String|HTMLElement|HTMLCollection|NodeList} target\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listen(target, type, callback) {\n if (!target && !type && !callback) {\n throw new Error('Missing required arguments');\n }\n\n if (!is.string(type)) {\n throw new TypeError('Second argument must be a String');\n }\n\n if (!is.fn(callback)) {\n throw new TypeError('Third argument must be a Function');\n }\n\n if (is.node(target)) {\n return listenNode(target, type, callback);\n }\n else if (is.nodeList(target)) {\n return listenNodeList(target, type, callback);\n }\n else if (is.string(target)) {\n return listenSelector(target, type, callback);\n }\n else {\n throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');\n }\n}\n\n/**\n * Adds an event listener to a HTML element\n * and returns a remove listener function.\n *\n * @param {HTMLElement} node\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNode(node, type, callback) {\n node.addEventListener(type, callback);\n\n return {\n destroy: function() {\n node.removeEventListener(type, callback);\n }\n }\n}\n\n/**\n * Add an event listener to a list of HTML elements\n * and returns a remove listener function.\n *\n * @param {NodeList|HTMLCollection} nodeList\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNodeList(nodeList, type, callback) {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.addEventListener(type, callback);\n });\n\n return {\n destroy: function() {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.removeEventListener(type, callback);\n });\n }\n }\n}\n\n/**\n * Add an event listener to a selector\n * and returns a remove listener function.\n *\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenSelector(selector, type, callback) {\n return delegate(document.body, selector, type, callback);\n}\n\nmodule.exports = listen;\n\n\n/***/ }),\n\n/***/ 817:\n/***/ (function(module) {\n\nfunction select(element) {\n var selectedText;\n\n if (element.nodeName === 'SELECT') {\n element.focus();\n\n selectedText = element.value;\n }\n else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {\n var isReadOnly = element.hasAttribute('readonly');\n\n if (!isReadOnly) {\n element.setAttribute('readonly', '');\n }\n\n element.select();\n element.setSelectionRange(0, element.value.length);\n\n if (!isReadOnly) {\n element.removeAttribute('readonly');\n }\n\n selectedText = element.value;\n }\n else {\n if (element.hasAttribute('contenteditable')) {\n element.focus();\n }\n\n var selection = window.getSelection();\n var range = document.createRange();\n\n range.selectNodeContents(element);\n selection.removeAllRanges();\n selection.addRange(range);\n\n selectedText = selection.toString();\n }\n\n return selectedText;\n}\n\nmodule.exports = select;\n\n\n/***/ }),\n\n/***/ 279:\n/***/ (function(module) {\n\nfunction E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\nmodule.exports.TinyEmitter = E;\n\n\n/***/ })\n\n/******/ \t});\n/************************************************************************/\n/******/ \t// The module cache\n/******/ \tvar __webpack_module_cache__ = {};\n/******/ \t\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(__webpack_module_cache__[moduleId]) {\n/******/ \t\t\treturn __webpack_module_cache__[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t\t// no module.id needed\n/******/ \t\t\t// no module.loaded needed\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/ \t\n/******/ \t\t// Execute the module function\n/******/ \t\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n/******/ \t\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/ \t\n/************************************************************************/\n/******/ \t/* webpack/runtime/compat get default export */\n/******/ \t!function() {\n/******/ \t\t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t\t__webpack_require__.n = function(module) {\n/******/ \t\t\tvar getter = module && module.__esModule ?\n/******/ \t\t\t\tfunction() { return module['default']; } :\n/******/ \t\t\t\tfunction() { return module; };\n/******/ \t\t\t__webpack_require__.d(getter, { a: getter });\n/******/ \t\t\treturn getter;\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/define property getters */\n/******/ \t!function() {\n/******/ \t\t// define getter functions for harmony exports\n/******/ \t\t__webpack_require__.d = function(exports, definition) {\n/******/ \t\t\tfor(var key in definition) {\n/******/ \t\t\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n/******/ \t\t\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n/******/ \t\t\t\t}\n/******/ \t\t\t}\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/hasOwnProperty shorthand */\n/******/ \t!function() {\n/******/ \t\t__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }\n/******/ \t}();\n/******/ \t\n/************************************************************************/\n/******/ \t// module exports must be returned from runtime so entry inlining is disabled\n/******/ \t// startup\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(686);\n/******/ })()\n.default;\n});", "/*!\n * escape-html\n * Copyright(c) 2012-2013 TJ Holowaychuk\n * Copyright(c) 2015 Andreas Lubbe\n * Copyright(c) 2015 Tiancheng \"Timothy\" Gu\n * MIT Licensed\n */\n\n'use strict';\n\n/**\n * Module variables.\n * @private\n */\n\nvar matchHtmlRegExp = /[\"'&<>]/;\n\n/**\n * Module exports.\n * @public\n */\n\nmodule.exports = escapeHtml;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @param {string} string The string to escape for inserting into HTML\n * @return {string}\n * @public\n */\n\nfunction escapeHtml(string) {\n var str = '' + string;\n var match = matchHtmlRegExp.exec(str);\n\n if (!match) {\n return str;\n }\n\n var escape;\n var html = '';\n var index = 0;\n var lastIndex = 0;\n\n for (index = match.index; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34: // \"\n escape = '"';\n break;\n case 38: // &\n escape = '&';\n break;\n case 39: // '\n escape = ''';\n break;\n case 60: // <\n escape = '<';\n break;\n case 62: // >\n escape = '>';\n break;\n default:\n continue;\n }\n\n if (lastIndex !== index) {\n html += str.substring(lastIndex, index);\n }\n\n lastIndex = index + 1;\n html += escape;\n }\n\n return lastIndex !== index\n ? html + str.substring(lastIndex, index)\n : html;\n}\n", "Array.prototype.flat||Object.defineProperty(Array.prototype,\"flat\",{configurable:!0,value:function r(){var t=isNaN(arguments[0])?1:Number(arguments[0]);return t?Array.prototype.reduce.call(this,function(a,e){return Array.isArray(e)?a.push.apply(a,r.call(e,t-1)):a.push(e),a},[]):Array.prototype.slice.call(this)},writable:!0}),Array.prototype.flatMap||Object.defineProperty(Array.prototype,\"flatMap\",{configurable:!0,value:function(r){return Array.prototype.map.apply(this,arguments).flat()},writable:!0})\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport \"array-flat-polyfill\"\nimport \"focus-visible\"\nimport \"unfetch/polyfill\"\nimport \"url-polyfill\"\n\nimport {\n EMPTY,\n NEVER,\n Subject,\n defer,\n delay,\n filter,\n map,\n merge,\n mergeWith,\n shareReplay,\n switchMap\n} from \"rxjs\"\n\nimport { configuration, feature } from \"./_\"\nimport {\n at,\n getOptionalElement,\n requestJSON,\n setToggle,\n watchDocument,\n watchKeyboard,\n watchLocation,\n watchLocationTarget,\n watchMedia,\n watchPrint,\n watchViewport\n} from \"./browser\"\nimport {\n getComponentElement,\n getComponentElements,\n mountAnnounce,\n mountBackToTop,\n mountConsent,\n mountContent,\n mountDialog,\n mountHeader,\n mountHeaderTitle,\n mountPalette,\n mountSearch,\n mountSearchHiglight,\n mountSidebar,\n mountSource,\n mountTableOfContents,\n mountTabs,\n watchHeader,\n watchMain\n} from \"./components\"\nimport {\n SearchIndex,\n setupClipboardJS,\n setupInstantLoading,\n setupVersionSelector\n} from \"./integrations\"\nimport {\n patchIndeterminate,\n patchScrollfix,\n patchScrolllock\n} from \"./patches\"\nimport \"./polyfills\"\n\n/* ----------------------------------------------------------------------------\n * Application\n * ------------------------------------------------------------------------- */\n\n/* Yay, JavaScript is available */\ndocument.documentElement.classList.remove(\"no-js\")\ndocument.documentElement.classList.add(\"js\")\n\n/* Set up navigation observables and subjects */\nconst document$ = watchDocument()\nconst location$ = watchLocation()\nconst target$ = watchLocationTarget()\nconst keyboard$ = watchKeyboard()\n\n/* Set up media observables */\nconst viewport$ = watchViewport()\nconst tablet$ = watchMedia(\"(min-width: 960px)\")\nconst screen$ = watchMedia(\"(min-width: 1220px)\")\nconst print$ = watchPrint()\n\n/* Retrieve search index, if search is enabled */\nconst config = configuration()\nconst index$ = document.forms.namedItem(\"search\")\n ? __search?.index || requestJSON(\n new URL(\"search/search_index.json\", config.base)\n )\n : NEVER\n\n/* Set up Clipboard.js integration */\nconst alert$ = new Subject()\nsetupClipboardJS({ alert$ })\n\n/* Set up instant loading, if enabled */\nif (feature(\"navigation.instant\"))\n setupInstantLoading({ document$, location$, viewport$ })\n\n/* Set up version selector */\nif (config.version?.provider === \"mike\")\n setupVersionSelector({ document$ })\n\n/* Always close drawer and search on navigation */\nmerge(location$, target$)\n .pipe(\n delay(125)\n )\n .subscribe(() => {\n setToggle(\"drawer\", false)\n setToggle(\"search\", false)\n })\n\n/* Set up global keyboard handlers */\nkeyboard$\n .pipe(\n filter(({ mode }) => mode === \"global\")\n )\n .subscribe(key => {\n switch (key.type) {\n\n /* Go to previous page */\n case \"p\":\n case \",\":\n const prev = getOptionalElement(\"[href][rel=prev]\")\n if (typeof prev !== \"undefined\")\n prev.click()\n break\n\n /* Go to next page */\n case \"n\":\n case \".\":\n const next = getOptionalElement(\"[href][rel=next]\")\n if (typeof next !== \"undefined\")\n next.click()\n break\n }\n })\n\n/* Set up patches */\npatchIndeterminate({ document$, tablet$ })\npatchScrollfix({ document$ })\npatchScrolllock({ viewport$, tablet$ })\n\n/* Set up header and main area observable */\nconst header$ = watchHeader(getComponentElement(\"header\"), { viewport$ })\nconst main$ = document$\n .pipe(\n map(() => getComponentElement(\"main\")),\n switchMap(el => watchMain(el, { viewport$, header$ })),\n shareReplay(1)\n )\n\n/* Set up control component observables */\nconst control$ = merge(\n\n /* Consent */\n ...getComponentElements(\"consent\")\n .map(el => mountConsent(el, { target$ })),\n\n /* Dialog */\n ...getComponentElements(\"dialog\")\n .map(el => mountDialog(el, { alert$ })),\n\n /* Header */\n ...getComponentElements(\"header\")\n .map(el => mountHeader(el, { viewport$, header$, main$ })),\n\n /* Color palette */\n ...getComponentElements(\"palette\")\n .map(el => mountPalette(el)),\n\n /* Search */\n ...getComponentElements(\"search\")\n .map(el => mountSearch(el, { index$, keyboard$ })),\n\n /* Repository information */\n ...getComponentElements(\"source\")\n .map(el => mountSource(el))\n)\n\n/* Set up content component observables */\nconst content$ = defer(() => merge(\n\n /* Announcement bar */\n ...getComponentElements(\"announce\")\n .map(el => mountAnnounce(el)),\n\n /* Content */\n ...getComponentElements(\"content\")\n .map(el => mountContent(el, { target$, print$ })),\n\n /* Search highlighting */\n ...getComponentElements(\"content\")\n .map(el => feature(\"search.highlight\")\n ? mountSearchHiglight(el, { index$, location$ })\n : EMPTY\n ),\n\n /* Header title */\n ...getComponentElements(\"header-title\")\n .map(el => mountHeaderTitle(el, { viewport$, header$ })),\n\n /* Sidebar */\n ...getComponentElements(\"sidebar\")\n .map(el => el.getAttribute(\"data-md-type\") === \"navigation\"\n ? at(screen$, () => mountSidebar(el, { viewport$, header$, main$ }))\n : at(tablet$, () => mountSidebar(el, { viewport$, header$, main$ }))\n ),\n\n /* Navigation tabs */\n ...getComponentElements(\"tabs\")\n .map(el => mountTabs(el, { viewport$, header$ })),\n\n /* Table of contents */\n ...getComponentElements(\"toc\")\n .map(el => mountTableOfContents(el, { viewport$, header$, target$ })),\n\n /* Back-to-top button */\n ...getComponentElements(\"top\")\n .map(el => mountBackToTop(el, { viewport$, header$, main$, target$ }))\n))\n\n/* Set up component observables */\nconst component$ = document$\n .pipe(\n switchMap(() => content$),\n mergeWith(control$),\n shareReplay(1)\n )\n\n/* Subscribe to all components */\ncomponent$.subscribe()\n\n/* ----------------------------------------------------------------------------\n * Exports\n * ------------------------------------------------------------------------- */\n\nwindow.document$ = document$ /* Document observable */\nwindow.location$ = location$ /* Location subject */\nwindow.target$ = target$ /* Location target observable */\nwindow.keyboard$ = keyboard$ /* Keyboard observable */\nwindow.viewport$ = viewport$ /* Viewport observable */\nwindow.tablet$ = tablet$ /* Media tablet observable */\nwindow.screen$ = screen$ /* Media screen observable */\nwindow.print$ = print$ /* Media print observable */\nwindow.alert$ = alert$ /* Alert subject */\nwindow.component$ = component$ /* Component observable */\n", "self.fetch||(self.fetch=function(e,n){return n=n||{},new Promise(function(t,s){var r=new XMLHttpRequest,o=[],u=[],i={},a=function(){return{ok:2==(r.status/100|0),statusText:r.statusText,status:r.status,url:r.responseURL,text:function(){return Promise.resolve(r.responseText)},json:function(){return Promise.resolve(r.responseText).then(JSON.parse)},blob:function(){return Promise.resolve(new Blob([r.response]))},clone:a,headers:{keys:function(){return o},entries:function(){return u},get:function(e){return i[e.toLowerCase()]},has:function(e){return e.toLowerCase()in i}}}};for(var c in r.open(n.method||\"get\",e,!0),r.onload=function(){r.getAllResponseHeaders().replace(/^(.*?):[^\\S\\n]*([\\s\\S]*?)$/gm,function(e,n,t){o.push(n=n.toLowerCase()),u.push([n,t]),i[n]=i[n]?i[n]+\",\"+t:t}),t(a())},r.onerror=s,r.withCredentials=\"include\"==n.credentials,n.headers)r.setRequestHeader(c,n.headers[c]);r.send(n.body||null)})});\n", "import tslib from '../tslib.js';\r\nconst {\r\n __extends,\r\n __assign,\r\n __rest,\r\n __decorate,\r\n __param,\r\n __metadata,\r\n __awaiter,\r\n __generator,\r\n __exportStar,\r\n __createBinding,\r\n __values,\r\n __read,\r\n __spread,\r\n __spreadArrays,\r\n __spreadArray,\r\n __await,\r\n __asyncGenerator,\r\n __asyncDelegator,\r\n __asyncValues,\r\n __makeTemplateObject,\r\n __importStar,\r\n __importDefault,\r\n __classPrivateFieldGet,\r\n __classPrivateFieldSet,\r\n} = tslib;\r\nexport {\r\n __extends,\r\n __assign,\r\n __rest,\r\n __decorate,\r\n __param,\r\n __metadata,\r\n __awaiter,\r\n __generator,\r\n __exportStar,\r\n __createBinding,\r\n __values,\r\n __read,\r\n __spread,\r\n __spreadArrays,\r\n __spreadArray,\r\n __await,\r\n __asyncGenerator,\r\n __asyncDelegator,\r\n __asyncValues,\r\n __makeTemplateObject,\r\n __importStar,\r\n __importDefault,\r\n __classPrivateFieldGet,\r\n __classPrivateFieldSet,\r\n};\r\n", null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n ReplaySubject,\n Subject,\n fromEvent\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch document\n *\n * Documents are implemented as subjects, so all downstream observables are\n * automatically updated when a new document is emitted.\n *\n * @returns Document subject\n */\nexport function watchDocument(): Subject {\n const document$ = new ReplaySubject(1)\n fromEvent(document, \"DOMContentLoaded\", { once: true })\n .subscribe(() => document$.next(document))\n\n /* Return document */\n return document$\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve all elements matching the query selector\n *\n * @template T - Element type\n *\n * @param selector - Query selector\n * @param node - Node of reference\n *\n * @returns Elements\n */\nexport function getElements(\n selector: T, node?: ParentNode\n): HTMLElementTagNameMap[T][]\n\nexport function getElements(\n selector: string, node?: ParentNode\n): T[]\n\nexport function getElements(\n selector: string, node: ParentNode = document\n): T[] {\n return Array.from(node.querySelectorAll(selector))\n}\n\n/**\n * Retrieve an element matching a query selector or throw a reference error\n *\n * Note that this function assumes that the element is present. If unsure if an\n * element is existent, use the `getOptionalElement` function instead.\n *\n * @template T - Element type\n *\n * @param selector - Query selector\n * @param node - Node of reference\n *\n * @returns Element\n */\nexport function getElement(\n selector: T, node?: ParentNode\n): HTMLElementTagNameMap[T]\n\nexport function getElement(\n selector: string, node?: ParentNode\n): T\n\nexport function getElement(\n selector: string, node: ParentNode = document\n): T {\n const el = getOptionalElement(selector, node)\n if (typeof el === \"undefined\")\n throw new ReferenceError(\n `Missing element: expected \"${selector}\" to be present`\n )\n\n /* Return element */\n return el\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Retrieve an optional element matching the query selector\n *\n * @template T - Element type\n *\n * @param selector - Query selector\n * @param node - Node of reference\n *\n * @returns Element or nothing\n */\nexport function getOptionalElement(\n selector: T, node?: ParentNode\n): HTMLElementTagNameMap[T] | undefined\n\nexport function getOptionalElement(\n selector: string, node?: ParentNode\n): T | undefined\n\nexport function getOptionalElement(\n selector: string, node: ParentNode = document\n): T | undefined {\n return node.querySelector(selector) || undefined\n}\n\n/**\n * Retrieve the currently active element\n *\n * @returns Element or nothing\n */\nexport function getActiveElement(): HTMLElement | undefined {\n return document.activeElement instanceof HTMLElement\n ? document.activeElement || undefined\n : undefined\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n debounceTime,\n distinctUntilChanged,\n fromEvent,\n map,\n merge,\n startWith\n} from \"rxjs\"\n\nimport { getActiveElement } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch element focus\n *\n * Previously, this function used `focus` and `blur` events to determine whether\n * an element is focused, but this doesn't work if there are focusable elements\n * within the elements itself. A better solutions are `focusin` and `focusout`\n * events, which bubble up the tree and allow for more fine-grained control.\n *\n * `debounceTime` is necessary, because when a focus change happens inside an\n * element, the observable would first emit `false` and then `true` again.\n *\n * @param el - Element\n *\n * @returns Element focus observable\n */\nexport function watchElementFocus(\n el: HTMLElement\n): Observable {\n return merge(\n fromEvent(document.body, \"focusin\"),\n fromEvent(document.body, \"focusout\")\n )\n .pipe(\n debounceTime(1),\n map(() => {\n const active = getActiveElement()\n return typeof active !== \"undefined\"\n ? el.contains(active)\n : false\n }),\n startWith(el === getActiveElement()),\n distinctUntilChanged()\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n animationFrameScheduler,\n auditTime,\n fromEvent,\n map,\n merge,\n startWith\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Element offset\n */\nexport interface ElementOffset {\n x: number /* Horizontal offset */\n y: number /* Vertical offset */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve element offset\n *\n * @param el - Element\n *\n * @returns Element offset\n */\nexport function getElementOffset(\n el: HTMLElement\n): ElementOffset {\n return {\n x: el.offsetLeft,\n y: el.offsetTop\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch element offset\n *\n * @param el - Element\n *\n * @returns Element offset observable\n */\nexport function watchElementOffset(\n el: HTMLElement\n): Observable {\n return merge(\n fromEvent(window, \"load\"),\n fromEvent(window, \"resize\")\n )\n .pipe(\n auditTime(0, animationFrameScheduler),\n map(() => getElementOffset(el)),\n startWith(getElementOffset(el))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n animationFrameScheduler,\n auditTime,\n fromEvent,\n map,\n merge,\n startWith\n} from \"rxjs\"\n\nimport { ElementOffset } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve element content offset (= scroll offset)\n *\n * @param el - Element\n *\n * @returns Element content offset\n */\nexport function getElementContentOffset(\n el: HTMLElement\n): ElementOffset {\n return {\n x: el.scrollLeft,\n y: el.scrollTop\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch element content offset\n *\n * @param el - Element\n *\n * @returns Element content offset observable\n */\nexport function watchElementContentOffset(\n el: HTMLElement\n): Observable {\n return merge(\n fromEvent(el, \"scroll\"),\n fromEvent(window, \"resize\")\n )\n .pipe(\n auditTime(0, animationFrameScheduler),\n map(() => getElementContentOffset(el)),\n startWith(getElementContentOffset(el))\n )\n}\n", "/**\r\n * A collection of shims that provide minimal functionality of the ES6 collections.\r\n *\r\n * These implementations are not meant to be used outside of the ResizeObserver\r\n * modules as they cover only a limited range of use cases.\r\n */\r\n/* eslint-disable require-jsdoc, valid-jsdoc */\r\nvar MapShim = (function () {\r\n if (typeof Map !== 'undefined') {\r\n return Map;\r\n }\r\n /**\r\n * Returns index in provided array that matches the specified key.\r\n *\r\n * @param {Array} arr\r\n * @param {*} key\r\n * @returns {number}\r\n */\r\n function getIndex(arr, key) {\r\n var result = -1;\r\n arr.some(function (entry, index) {\r\n if (entry[0] === key) {\r\n result = index;\r\n return true;\r\n }\r\n return false;\r\n });\r\n return result;\r\n }\r\n return /** @class */ (function () {\r\n function class_1() {\r\n this.__entries__ = [];\r\n }\r\n Object.defineProperty(class_1.prototype, \"size\", {\r\n /**\r\n * @returns {boolean}\r\n */\r\n get: function () {\r\n return this.__entries__.length;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n /**\r\n * @param {*} key\r\n * @returns {*}\r\n */\r\n class_1.prototype.get = function (key) {\r\n var index = getIndex(this.__entries__, key);\r\n var entry = this.__entries__[index];\r\n return entry && entry[1];\r\n };\r\n /**\r\n * @param {*} key\r\n * @param {*} value\r\n * @returns {void}\r\n */\r\n class_1.prototype.set = function (key, value) {\r\n var index = getIndex(this.__entries__, key);\r\n if (~index) {\r\n this.__entries__[index][1] = value;\r\n }\r\n else {\r\n this.__entries__.push([key, value]);\r\n }\r\n };\r\n /**\r\n * @param {*} key\r\n * @returns {void}\r\n */\r\n class_1.prototype.delete = function (key) {\r\n var entries = this.__entries__;\r\n var index = getIndex(entries, key);\r\n if (~index) {\r\n entries.splice(index, 1);\r\n }\r\n };\r\n /**\r\n * @param {*} key\r\n * @returns {void}\r\n */\r\n class_1.prototype.has = function (key) {\r\n return !!~getIndex(this.__entries__, key);\r\n };\r\n /**\r\n * @returns {void}\r\n */\r\n class_1.prototype.clear = function () {\r\n this.__entries__.splice(0);\r\n };\r\n /**\r\n * @param {Function} callback\r\n * @param {*} [ctx=null]\r\n * @returns {void}\r\n */\r\n class_1.prototype.forEach = function (callback, ctx) {\r\n if (ctx === void 0) { ctx = null; }\r\n for (var _i = 0, _a = this.__entries__; _i < _a.length; _i++) {\r\n var entry = _a[_i];\r\n callback.call(ctx, entry[1], entry[0]);\r\n }\r\n };\r\n return class_1;\r\n }());\r\n})();\n\n/**\r\n * Detects whether window and document objects are available in current environment.\r\n */\r\nvar isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && window.document === document;\n\n// Returns global object of a current environment.\r\nvar global$1 = (function () {\r\n if (typeof global !== 'undefined' && global.Math === Math) {\r\n return global;\r\n }\r\n if (typeof self !== 'undefined' && self.Math === Math) {\r\n return self;\r\n }\r\n if (typeof window !== 'undefined' && window.Math === Math) {\r\n return window;\r\n }\r\n // eslint-disable-next-line no-new-func\r\n return Function('return this')();\r\n})();\n\n/**\r\n * A shim for the requestAnimationFrame which falls back to the setTimeout if\r\n * first one is not supported.\r\n *\r\n * @returns {number} Requests' identifier.\r\n */\r\nvar requestAnimationFrame$1 = (function () {\r\n if (typeof requestAnimationFrame === 'function') {\r\n // It's required to use a bounded function because IE sometimes throws\r\n // an \"Invalid calling object\" error if rAF is invoked without the global\r\n // object on the left hand side.\r\n return requestAnimationFrame.bind(global$1);\r\n }\r\n return function (callback) { return setTimeout(function () { return callback(Date.now()); }, 1000 / 60); };\r\n})();\n\n// Defines minimum timeout before adding a trailing call.\r\nvar trailingTimeout = 2;\r\n/**\r\n * Creates a wrapper function which ensures that provided callback will be\r\n * invoked only once during the specified delay period.\r\n *\r\n * @param {Function} callback - Function to be invoked after the delay period.\r\n * @param {number} delay - Delay after which to invoke callback.\r\n * @returns {Function}\r\n */\r\nfunction throttle (callback, delay) {\r\n var leadingCall = false, trailingCall = false, lastCallTime = 0;\r\n /**\r\n * Invokes the original callback function and schedules new invocation if\r\n * the \"proxy\" was called during current request.\r\n *\r\n * @returns {void}\r\n */\r\n function resolvePending() {\r\n if (leadingCall) {\r\n leadingCall = false;\r\n callback();\r\n }\r\n if (trailingCall) {\r\n proxy();\r\n }\r\n }\r\n /**\r\n * Callback invoked after the specified delay. It will further postpone\r\n * invocation of the original function delegating it to the\r\n * requestAnimationFrame.\r\n *\r\n * @returns {void}\r\n */\r\n function timeoutCallback() {\r\n requestAnimationFrame$1(resolvePending);\r\n }\r\n /**\r\n * Schedules invocation of the original function.\r\n *\r\n * @returns {void}\r\n */\r\n function proxy() {\r\n var timeStamp = Date.now();\r\n if (leadingCall) {\r\n // Reject immediately following calls.\r\n if (timeStamp - lastCallTime < trailingTimeout) {\r\n return;\r\n }\r\n // Schedule new call to be in invoked when the pending one is resolved.\r\n // This is important for \"transitions\" which never actually start\r\n // immediately so there is a chance that we might miss one if change\r\n // happens amids the pending invocation.\r\n trailingCall = true;\r\n }\r\n else {\r\n leadingCall = true;\r\n trailingCall = false;\r\n setTimeout(timeoutCallback, delay);\r\n }\r\n lastCallTime = timeStamp;\r\n }\r\n return proxy;\r\n}\n\n// Minimum delay before invoking the update of observers.\r\nvar REFRESH_DELAY = 20;\r\n// A list of substrings of CSS properties used to find transition events that\r\n// might affect dimensions of observed elements.\r\nvar transitionKeys = ['top', 'right', 'bottom', 'left', 'width', 'height', 'size', 'weight'];\r\n// Check if MutationObserver is available.\r\nvar mutationObserverSupported = typeof MutationObserver !== 'undefined';\r\n/**\r\n * Singleton controller class which handles updates of ResizeObserver instances.\r\n */\r\nvar ResizeObserverController = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserverController.\r\n *\r\n * @private\r\n */\r\n function ResizeObserverController() {\r\n /**\r\n * Indicates whether DOM listeners have been added.\r\n *\r\n * @private {boolean}\r\n */\r\n this.connected_ = false;\r\n /**\r\n * Tells that controller has subscribed for Mutation Events.\r\n *\r\n * @private {boolean}\r\n */\r\n this.mutationEventsAdded_ = false;\r\n /**\r\n * Keeps reference to the instance of MutationObserver.\r\n *\r\n * @private {MutationObserver}\r\n */\r\n this.mutationsObserver_ = null;\r\n /**\r\n * A list of connected observers.\r\n *\r\n * @private {Array}\r\n */\r\n this.observers_ = [];\r\n this.onTransitionEnd_ = this.onTransitionEnd_.bind(this);\r\n this.refresh = throttle(this.refresh.bind(this), REFRESH_DELAY);\r\n }\r\n /**\r\n * Adds observer to observers list.\r\n *\r\n * @param {ResizeObserverSPI} observer - Observer to be added.\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.addObserver = function (observer) {\r\n if (!~this.observers_.indexOf(observer)) {\r\n this.observers_.push(observer);\r\n }\r\n // Add listeners if they haven't been added yet.\r\n if (!this.connected_) {\r\n this.connect_();\r\n }\r\n };\r\n /**\r\n * Removes observer from observers list.\r\n *\r\n * @param {ResizeObserverSPI} observer - Observer to be removed.\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.removeObserver = function (observer) {\r\n var observers = this.observers_;\r\n var index = observers.indexOf(observer);\r\n // Remove observer if it's present in registry.\r\n if (~index) {\r\n observers.splice(index, 1);\r\n }\r\n // Remove listeners if controller has no connected observers.\r\n if (!observers.length && this.connected_) {\r\n this.disconnect_();\r\n }\r\n };\r\n /**\r\n * Invokes the update of observers. It will continue running updates insofar\r\n * it detects changes.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.refresh = function () {\r\n var changesDetected = this.updateObservers_();\r\n // Continue running updates if changes have been detected as there might\r\n // be future ones caused by CSS transitions.\r\n if (changesDetected) {\r\n this.refresh();\r\n }\r\n };\r\n /**\r\n * Updates every observer from observers list and notifies them of queued\r\n * entries.\r\n *\r\n * @private\r\n * @returns {boolean} Returns \"true\" if any observer has detected changes in\r\n * dimensions of it's elements.\r\n */\r\n ResizeObserverController.prototype.updateObservers_ = function () {\r\n // Collect observers that have active observations.\r\n var activeObservers = this.observers_.filter(function (observer) {\r\n return observer.gatherActive(), observer.hasActive();\r\n });\r\n // Deliver notifications in a separate cycle in order to avoid any\r\n // collisions between observers, e.g. when multiple instances of\r\n // ResizeObserver are tracking the same element and the callback of one\r\n // of them changes content dimensions of the observed target. Sometimes\r\n // this may result in notifications being blocked for the rest of observers.\r\n activeObservers.forEach(function (observer) { return observer.broadcastActive(); });\r\n return activeObservers.length > 0;\r\n };\r\n /**\r\n * Initializes DOM listeners.\r\n *\r\n * @private\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.connect_ = function () {\r\n // Do nothing if running in a non-browser environment or if listeners\r\n // have been already added.\r\n if (!isBrowser || this.connected_) {\r\n return;\r\n }\r\n // Subscription to the \"Transitionend\" event is used as a workaround for\r\n // delayed transitions. This way it's possible to capture at least the\r\n // final state of an element.\r\n document.addEventListener('transitionend', this.onTransitionEnd_);\r\n window.addEventListener('resize', this.refresh);\r\n if (mutationObserverSupported) {\r\n this.mutationsObserver_ = new MutationObserver(this.refresh);\r\n this.mutationsObserver_.observe(document, {\r\n attributes: true,\r\n childList: true,\r\n characterData: true,\r\n subtree: true\r\n });\r\n }\r\n else {\r\n document.addEventListener('DOMSubtreeModified', this.refresh);\r\n this.mutationEventsAdded_ = true;\r\n }\r\n this.connected_ = true;\r\n };\r\n /**\r\n * Removes DOM listeners.\r\n *\r\n * @private\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.disconnect_ = function () {\r\n // Do nothing if running in a non-browser environment or if listeners\r\n // have been already removed.\r\n if (!isBrowser || !this.connected_) {\r\n return;\r\n }\r\n document.removeEventListener('transitionend', this.onTransitionEnd_);\r\n window.removeEventListener('resize', this.refresh);\r\n if (this.mutationsObserver_) {\r\n this.mutationsObserver_.disconnect();\r\n }\r\n if (this.mutationEventsAdded_) {\r\n document.removeEventListener('DOMSubtreeModified', this.refresh);\r\n }\r\n this.mutationsObserver_ = null;\r\n this.mutationEventsAdded_ = false;\r\n this.connected_ = false;\r\n };\r\n /**\r\n * \"Transitionend\" event handler.\r\n *\r\n * @private\r\n * @param {TransitionEvent} event\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.onTransitionEnd_ = function (_a) {\r\n var _b = _a.propertyName, propertyName = _b === void 0 ? '' : _b;\r\n // Detect whether transition may affect dimensions of an element.\r\n var isReflowProperty = transitionKeys.some(function (key) {\r\n return !!~propertyName.indexOf(key);\r\n });\r\n if (isReflowProperty) {\r\n this.refresh();\r\n }\r\n };\r\n /**\r\n * Returns instance of the ResizeObserverController.\r\n *\r\n * @returns {ResizeObserverController}\r\n */\r\n ResizeObserverController.getInstance = function () {\r\n if (!this.instance_) {\r\n this.instance_ = new ResizeObserverController();\r\n }\r\n return this.instance_;\r\n };\r\n /**\r\n * Holds reference to the controller's instance.\r\n *\r\n * @private {ResizeObserverController}\r\n */\r\n ResizeObserverController.instance_ = null;\r\n return ResizeObserverController;\r\n}());\n\n/**\r\n * Defines non-writable/enumerable properties of the provided target object.\r\n *\r\n * @param {Object} target - Object for which to define properties.\r\n * @param {Object} props - Properties to be defined.\r\n * @returns {Object} Target object.\r\n */\r\nvar defineConfigurable = (function (target, props) {\r\n for (var _i = 0, _a = Object.keys(props); _i < _a.length; _i++) {\r\n var key = _a[_i];\r\n Object.defineProperty(target, key, {\r\n value: props[key],\r\n enumerable: false,\r\n writable: false,\r\n configurable: true\r\n });\r\n }\r\n return target;\r\n});\n\n/**\r\n * Returns the global object associated with provided element.\r\n *\r\n * @param {Object} target\r\n * @returns {Object}\r\n */\r\nvar getWindowOf = (function (target) {\r\n // Assume that the element is an instance of Node, which means that it\r\n // has the \"ownerDocument\" property from which we can retrieve a\r\n // corresponding global object.\r\n var ownerGlobal = target && target.ownerDocument && target.ownerDocument.defaultView;\r\n // Return the local global object if it's not possible extract one from\r\n // provided element.\r\n return ownerGlobal || global$1;\r\n});\n\n// Placeholder of an empty content rectangle.\r\nvar emptyRect = createRectInit(0, 0, 0, 0);\r\n/**\r\n * Converts provided string to a number.\r\n *\r\n * @param {number|string} value\r\n * @returns {number}\r\n */\r\nfunction toFloat(value) {\r\n return parseFloat(value) || 0;\r\n}\r\n/**\r\n * Extracts borders size from provided styles.\r\n *\r\n * @param {CSSStyleDeclaration} styles\r\n * @param {...string} positions - Borders positions (top, right, ...)\r\n * @returns {number}\r\n */\r\nfunction getBordersSize(styles) {\r\n var positions = [];\r\n for (var _i = 1; _i < arguments.length; _i++) {\r\n positions[_i - 1] = arguments[_i];\r\n }\r\n return positions.reduce(function (size, position) {\r\n var value = styles['border-' + position + '-width'];\r\n return size + toFloat(value);\r\n }, 0);\r\n}\r\n/**\r\n * Extracts paddings sizes from provided styles.\r\n *\r\n * @param {CSSStyleDeclaration} styles\r\n * @returns {Object} Paddings box.\r\n */\r\nfunction getPaddings(styles) {\r\n var positions = ['top', 'right', 'bottom', 'left'];\r\n var paddings = {};\r\n for (var _i = 0, positions_1 = positions; _i < positions_1.length; _i++) {\r\n var position = positions_1[_i];\r\n var value = styles['padding-' + position];\r\n paddings[position] = toFloat(value);\r\n }\r\n return paddings;\r\n}\r\n/**\r\n * Calculates content rectangle of provided SVG element.\r\n *\r\n * @param {SVGGraphicsElement} target - Element content rectangle of which needs\r\n * to be calculated.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getSVGContentRect(target) {\r\n var bbox = target.getBBox();\r\n return createRectInit(0, 0, bbox.width, bbox.height);\r\n}\r\n/**\r\n * Calculates content rectangle of provided HTMLElement.\r\n *\r\n * @param {HTMLElement} target - Element for which to calculate the content rectangle.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getHTMLElementContentRect(target) {\r\n // Client width & height properties can't be\r\n // used exclusively as they provide rounded values.\r\n var clientWidth = target.clientWidth, clientHeight = target.clientHeight;\r\n // By this condition we can catch all non-replaced inline, hidden and\r\n // detached elements. Though elements with width & height properties less\r\n // than 0.5 will be discarded as well.\r\n //\r\n // Without it we would need to implement separate methods for each of\r\n // those cases and it's not possible to perform a precise and performance\r\n // effective test for hidden elements. E.g. even jQuery's ':visible' filter\r\n // gives wrong results for elements with width & height less than 0.5.\r\n if (!clientWidth && !clientHeight) {\r\n return emptyRect;\r\n }\r\n var styles = getWindowOf(target).getComputedStyle(target);\r\n var paddings = getPaddings(styles);\r\n var horizPad = paddings.left + paddings.right;\r\n var vertPad = paddings.top + paddings.bottom;\r\n // Computed styles of width & height are being used because they are the\r\n // only dimensions available to JS that contain non-rounded values. It could\r\n // be possible to utilize the getBoundingClientRect if only it's data wasn't\r\n // affected by CSS transformations let alone paddings, borders and scroll bars.\r\n var width = toFloat(styles.width), height = toFloat(styles.height);\r\n // Width & height include paddings and borders when the 'border-box' box\r\n // model is applied (except for IE).\r\n if (styles.boxSizing === 'border-box') {\r\n // Following conditions are required to handle Internet Explorer which\r\n // doesn't include paddings and borders to computed CSS dimensions.\r\n //\r\n // We can say that if CSS dimensions + paddings are equal to the \"client\"\r\n // properties then it's either IE, and thus we don't need to subtract\r\n // anything, or an element merely doesn't have paddings/borders styles.\r\n if (Math.round(width + horizPad) !== clientWidth) {\r\n width -= getBordersSize(styles, 'left', 'right') + horizPad;\r\n }\r\n if (Math.round(height + vertPad) !== clientHeight) {\r\n height -= getBordersSize(styles, 'top', 'bottom') + vertPad;\r\n }\r\n }\r\n // Following steps can't be applied to the document's root element as its\r\n // client[Width/Height] properties represent viewport area of the window.\r\n // Besides, it's as well not necessary as the itself neither has\r\n // rendered scroll bars nor it can be clipped.\r\n if (!isDocumentElement(target)) {\r\n // In some browsers (only in Firefox, actually) CSS width & height\r\n // include scroll bars size which can be removed at this step as scroll\r\n // bars are the only difference between rounded dimensions + paddings\r\n // and \"client\" properties, though that is not always true in Chrome.\r\n var vertScrollbar = Math.round(width + horizPad) - clientWidth;\r\n var horizScrollbar = Math.round(height + vertPad) - clientHeight;\r\n // Chrome has a rather weird rounding of \"client\" properties.\r\n // E.g. for an element with content width of 314.2px it sometimes gives\r\n // the client width of 315px and for the width of 314.7px it may give\r\n // 314px. And it doesn't happen all the time. So just ignore this delta\r\n // as a non-relevant.\r\n if (Math.abs(vertScrollbar) !== 1) {\r\n width -= vertScrollbar;\r\n }\r\n if (Math.abs(horizScrollbar) !== 1) {\r\n height -= horizScrollbar;\r\n }\r\n }\r\n return createRectInit(paddings.left, paddings.top, width, height);\r\n}\r\n/**\r\n * Checks whether provided element is an instance of the SVGGraphicsElement.\r\n *\r\n * @param {Element} target - Element to be checked.\r\n * @returns {boolean}\r\n */\r\nvar isSVGGraphicsElement = (function () {\r\n // Some browsers, namely IE and Edge, don't have the SVGGraphicsElement\r\n // interface.\r\n if (typeof SVGGraphicsElement !== 'undefined') {\r\n return function (target) { return target instanceof getWindowOf(target).SVGGraphicsElement; };\r\n }\r\n // If it's so, then check that element is at least an instance of the\r\n // SVGElement and that it has the \"getBBox\" method.\r\n // eslint-disable-next-line no-extra-parens\r\n return function (target) { return (target instanceof getWindowOf(target).SVGElement &&\r\n typeof target.getBBox === 'function'); };\r\n})();\r\n/**\r\n * Checks whether provided element is a document element ().\r\n *\r\n * @param {Element} target - Element to be checked.\r\n * @returns {boolean}\r\n */\r\nfunction isDocumentElement(target) {\r\n return target === getWindowOf(target).document.documentElement;\r\n}\r\n/**\r\n * Calculates an appropriate content rectangle for provided html or svg element.\r\n *\r\n * @param {Element} target - Element content rectangle of which needs to be calculated.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getContentRect(target) {\r\n if (!isBrowser) {\r\n return emptyRect;\r\n }\r\n if (isSVGGraphicsElement(target)) {\r\n return getSVGContentRect(target);\r\n }\r\n return getHTMLElementContentRect(target);\r\n}\r\n/**\r\n * Creates rectangle with an interface of the DOMRectReadOnly.\r\n * Spec: https://drafts.fxtf.org/geometry/#domrectreadonly\r\n *\r\n * @param {DOMRectInit} rectInit - Object with rectangle's x/y coordinates and dimensions.\r\n * @returns {DOMRectReadOnly}\r\n */\r\nfunction createReadOnlyRect(_a) {\r\n var x = _a.x, y = _a.y, width = _a.width, height = _a.height;\r\n // If DOMRectReadOnly is available use it as a prototype for the rectangle.\r\n var Constr = typeof DOMRectReadOnly !== 'undefined' ? DOMRectReadOnly : Object;\r\n var rect = Object.create(Constr.prototype);\r\n // Rectangle's properties are not writable and non-enumerable.\r\n defineConfigurable(rect, {\r\n x: x, y: y, width: width, height: height,\r\n top: y,\r\n right: x + width,\r\n bottom: height + y,\r\n left: x\r\n });\r\n return rect;\r\n}\r\n/**\r\n * Creates DOMRectInit object based on the provided dimensions and the x/y coordinates.\r\n * Spec: https://drafts.fxtf.org/geometry/#dictdef-domrectinit\r\n *\r\n * @param {number} x - X coordinate.\r\n * @param {number} y - Y coordinate.\r\n * @param {number} width - Rectangle's width.\r\n * @param {number} height - Rectangle's height.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction createRectInit(x, y, width, height) {\r\n return { x: x, y: y, width: width, height: height };\r\n}\n\n/**\r\n * Class that is responsible for computations of the content rectangle of\r\n * provided DOM element and for keeping track of it's changes.\r\n */\r\nvar ResizeObservation = /** @class */ (function () {\r\n /**\r\n * Creates an instance of ResizeObservation.\r\n *\r\n * @param {Element} target - Element to be observed.\r\n */\r\n function ResizeObservation(target) {\r\n /**\r\n * Broadcasted width of content rectangle.\r\n *\r\n * @type {number}\r\n */\r\n this.broadcastWidth = 0;\r\n /**\r\n * Broadcasted height of content rectangle.\r\n *\r\n * @type {number}\r\n */\r\n this.broadcastHeight = 0;\r\n /**\r\n * Reference to the last observed content rectangle.\r\n *\r\n * @private {DOMRectInit}\r\n */\r\n this.contentRect_ = createRectInit(0, 0, 0, 0);\r\n this.target = target;\r\n }\r\n /**\r\n * Updates content rectangle and tells whether it's width or height properties\r\n * have changed since the last broadcast.\r\n *\r\n * @returns {boolean}\r\n */\r\n ResizeObservation.prototype.isActive = function () {\r\n var rect = getContentRect(this.target);\r\n this.contentRect_ = rect;\r\n return (rect.width !== this.broadcastWidth ||\r\n rect.height !== this.broadcastHeight);\r\n };\r\n /**\r\n * Updates 'broadcastWidth' and 'broadcastHeight' properties with a data\r\n * from the corresponding properties of the last observed content rectangle.\r\n *\r\n * @returns {DOMRectInit} Last observed content rectangle.\r\n */\r\n ResizeObservation.prototype.broadcastRect = function () {\r\n var rect = this.contentRect_;\r\n this.broadcastWidth = rect.width;\r\n this.broadcastHeight = rect.height;\r\n return rect;\r\n };\r\n return ResizeObservation;\r\n}());\n\nvar ResizeObserverEntry = /** @class */ (function () {\r\n /**\r\n * Creates an instance of ResizeObserverEntry.\r\n *\r\n * @param {Element} target - Element that is being observed.\r\n * @param {DOMRectInit} rectInit - Data of the element's content rectangle.\r\n */\r\n function ResizeObserverEntry(target, rectInit) {\r\n var contentRect = createReadOnlyRect(rectInit);\r\n // According to the specification following properties are not writable\r\n // and are also not enumerable in the native implementation.\r\n //\r\n // Property accessors are not being used as they'd require to define a\r\n // private WeakMap storage which may cause memory leaks in browsers that\r\n // don't support this type of collections.\r\n defineConfigurable(this, { target: target, contentRect: contentRect });\r\n }\r\n return ResizeObserverEntry;\r\n}());\n\nvar ResizeObserverSPI = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserver.\r\n *\r\n * @param {ResizeObserverCallback} callback - Callback function that is invoked\r\n * when one of the observed elements changes it's content dimensions.\r\n * @param {ResizeObserverController} controller - Controller instance which\r\n * is responsible for the updates of observer.\r\n * @param {ResizeObserver} callbackCtx - Reference to the public\r\n * ResizeObserver instance which will be passed to callback function.\r\n */\r\n function ResizeObserverSPI(callback, controller, callbackCtx) {\r\n /**\r\n * Collection of resize observations that have detected changes in dimensions\r\n * of elements.\r\n *\r\n * @private {Array}\r\n */\r\n this.activeObservations_ = [];\r\n /**\r\n * Registry of the ResizeObservation instances.\r\n *\r\n * @private {Map}\r\n */\r\n this.observations_ = new MapShim();\r\n if (typeof callback !== 'function') {\r\n throw new TypeError('The callback provided as parameter 1 is not a function.');\r\n }\r\n this.callback_ = callback;\r\n this.controller_ = controller;\r\n this.callbackCtx_ = callbackCtx;\r\n }\r\n /**\r\n * Starts observing provided element.\r\n *\r\n * @param {Element} target - Element to be observed.\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.observe = function (target) {\r\n if (!arguments.length) {\r\n throw new TypeError('1 argument required, but only 0 present.');\r\n }\r\n // Do nothing if current environment doesn't have the Element interface.\r\n if (typeof Element === 'undefined' || !(Element instanceof Object)) {\r\n return;\r\n }\r\n if (!(target instanceof getWindowOf(target).Element)) {\r\n throw new TypeError('parameter 1 is not of type \"Element\".');\r\n }\r\n var observations = this.observations_;\r\n // Do nothing if element is already being observed.\r\n if (observations.has(target)) {\r\n return;\r\n }\r\n observations.set(target, new ResizeObservation(target));\r\n this.controller_.addObserver(this);\r\n // Force the update of observations.\r\n this.controller_.refresh();\r\n };\r\n /**\r\n * Stops observing provided element.\r\n *\r\n * @param {Element} target - Element to stop observing.\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.unobserve = function (target) {\r\n if (!arguments.length) {\r\n throw new TypeError('1 argument required, but only 0 present.');\r\n }\r\n // Do nothing if current environment doesn't have the Element interface.\r\n if (typeof Element === 'undefined' || !(Element instanceof Object)) {\r\n return;\r\n }\r\n if (!(target instanceof getWindowOf(target).Element)) {\r\n throw new TypeError('parameter 1 is not of type \"Element\".');\r\n }\r\n var observations = this.observations_;\r\n // Do nothing if element is not being observed.\r\n if (!observations.has(target)) {\r\n return;\r\n }\r\n observations.delete(target);\r\n if (!observations.size) {\r\n this.controller_.removeObserver(this);\r\n }\r\n };\r\n /**\r\n * Stops observing all elements.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.disconnect = function () {\r\n this.clearActive();\r\n this.observations_.clear();\r\n this.controller_.removeObserver(this);\r\n };\r\n /**\r\n * Collects observation instances the associated element of which has changed\r\n * it's content rectangle.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.gatherActive = function () {\r\n var _this = this;\r\n this.clearActive();\r\n this.observations_.forEach(function (observation) {\r\n if (observation.isActive()) {\r\n _this.activeObservations_.push(observation);\r\n }\r\n });\r\n };\r\n /**\r\n * Invokes initial callback function with a list of ResizeObserverEntry\r\n * instances collected from active resize observations.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.broadcastActive = function () {\r\n // Do nothing if observer doesn't have active observations.\r\n if (!this.hasActive()) {\r\n return;\r\n }\r\n var ctx = this.callbackCtx_;\r\n // Create ResizeObserverEntry instance for every active observation.\r\n var entries = this.activeObservations_.map(function (observation) {\r\n return new ResizeObserverEntry(observation.target, observation.broadcastRect());\r\n });\r\n this.callback_.call(ctx, entries, ctx);\r\n this.clearActive();\r\n };\r\n /**\r\n * Clears the collection of active observations.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.clearActive = function () {\r\n this.activeObservations_.splice(0);\r\n };\r\n /**\r\n * Tells whether observer has active observations.\r\n *\r\n * @returns {boolean}\r\n */\r\n ResizeObserverSPI.prototype.hasActive = function () {\r\n return this.activeObservations_.length > 0;\r\n };\r\n return ResizeObserverSPI;\r\n}());\n\n// Registry of internal observers. If WeakMap is not available use current shim\r\n// for the Map collection as it has all required methods and because WeakMap\r\n// can't be fully polyfilled anyway.\r\nvar observers = typeof WeakMap !== 'undefined' ? new WeakMap() : new MapShim();\r\n/**\r\n * ResizeObserver API. Encapsulates the ResizeObserver SPI implementation\r\n * exposing only those methods and properties that are defined in the spec.\r\n */\r\nvar ResizeObserver = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserver.\r\n *\r\n * @param {ResizeObserverCallback} callback - Callback that is invoked when\r\n * dimensions of the observed elements change.\r\n */\r\n function ResizeObserver(callback) {\r\n if (!(this instanceof ResizeObserver)) {\r\n throw new TypeError('Cannot call a class as a function.');\r\n }\r\n if (!arguments.length) {\r\n throw new TypeError('1 argument required, but only 0 present.');\r\n }\r\n var controller = ResizeObserverController.getInstance();\r\n var observer = new ResizeObserverSPI(callback, controller, this);\r\n observers.set(this, observer);\r\n }\r\n return ResizeObserver;\r\n}());\r\n// Expose public methods of ResizeObserver.\r\n[\r\n 'observe',\r\n 'unobserve',\r\n 'disconnect'\r\n].forEach(function (method) {\r\n ResizeObserver.prototype[method] = function () {\r\n var _a;\r\n return (_a = observers.get(this))[method].apply(_a, arguments);\r\n };\r\n});\n\nvar index = (function () {\r\n // Export existing implementation if available.\r\n if (typeof global$1.ResizeObserver !== 'undefined') {\r\n return global$1.ResizeObserver;\r\n }\r\n return ResizeObserver;\r\n})();\n\nexport default index;\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport ResizeObserver from \"resize-observer-polyfill\"\nimport {\n NEVER,\n Observable,\n Subject,\n defer,\n filter,\n finalize,\n map,\n merge,\n of,\n shareReplay,\n startWith,\n switchMap,\n tap\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Element offset\n */\nexport interface ElementSize {\n width: number /* Element width */\n height: number /* Element height */\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Resize observer entry subject\n */\nconst entry$ = new Subject()\n\n/**\n * Resize observer observable\n *\n * This observable will create a `ResizeObserver` on the first subscription\n * and will automatically terminate it when there are no more subscribers.\n * It's quite important to centralize observation in a single `ResizeObserver`,\n * as the performance difference can be quite dramatic, as the link shows.\n *\n * @see https://bit.ly/3iIYfEm - Google Groups on performance\n */\nconst observer$ = defer(() => of(\n new ResizeObserver(entries => {\n for (const entry of entries)\n entry$.next(entry)\n })\n))\n .pipe(\n switchMap(observer => merge(NEVER, of(observer))\n .pipe(\n finalize(() => observer.disconnect())\n )\n ),\n shareReplay(1)\n )\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve element size\n *\n * @param el - Element\n *\n * @returns Element size\n */\nexport function getElementSize(\n el: HTMLElement\n): ElementSize {\n return {\n width: el.offsetWidth,\n height: el.offsetHeight\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch element size\n *\n * This function returns an observable that subscribes to a single internal\n * instance of `ResizeObserver` upon subscription, and emit resize events until\n * termination. Note that this function should not be called with the same\n * element twice, as the first unsubscription will terminate observation.\n *\n * Sadly, we can't use the `DOMRect` objects returned by the observer, because\n * we need the emitted values to be consistent with `getElementSize`, which will\n * return the used values (rounded) and not actual values (unrounded). Thus, we\n * use the `offset*` properties. See the linked GitHub issue.\n *\n * @see https://bit.ly/3m0k3he - GitHub issue\n *\n * @param el - Element\n *\n * @returns Element size observable\n */\nexport function watchElementSize(\n el: HTMLElement\n): Observable {\n return observer$\n .pipe(\n tap(observer => observer.observe(el)),\n switchMap(observer => entry$\n .pipe(\n filter(({ target }) => target === el),\n finalize(() => observer.unobserve(el)),\n map(() => getElementSize(el))\n )\n ),\n startWith(getElementSize(el))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { ElementSize } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve element content size (= scroll width and height)\n *\n * @param el - Element\n *\n * @returns Element content size\n */\nexport function getElementContentSize(\n el: HTMLElement\n): ElementSize {\n return {\n width: el.scrollWidth,\n height: el.scrollHeight\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n NEVER,\n Observable,\n Subject,\n defer,\n distinctUntilChanged,\n filter,\n finalize,\n map,\n merge,\n of,\n shareReplay,\n switchMap,\n tap\n} from \"rxjs\"\n\nimport {\n getElementContentSize,\n getElementSize,\n watchElementContentOffset\n} from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Intersection observer entry subject\n */\nconst entry$ = new Subject()\n\n/**\n * Intersection observer observable\n *\n * This observable will create an `IntersectionObserver` on first subscription\n * and will automatically terminate it when there are no more subscribers.\n *\n * @see https://bit.ly/3iIYfEm - Google Groups on performance\n */\nconst observer$ = defer(() => of(\n new IntersectionObserver(entries => {\n for (const entry of entries)\n entry$.next(entry)\n }, {\n threshold: 0\n })\n))\n .pipe(\n switchMap(observer => merge(NEVER, of(observer))\n .pipe(\n finalize(() => observer.disconnect())\n )\n ),\n shareReplay(1)\n )\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch element visibility\n *\n * @param el - Element\n *\n * @returns Element visibility observable\n */\nexport function watchElementVisibility(\n el: HTMLElement\n): Observable {\n return observer$\n .pipe(\n tap(observer => observer.observe(el)),\n switchMap(observer => entry$\n .pipe(\n filter(({ target }) => target === el),\n finalize(() => observer.unobserve(el)),\n map(({ isIntersecting }) => isIntersecting)\n )\n )\n )\n}\n\n/**\n * Watch element boundary\n *\n * This function returns an observable which emits whether the bottom content\n * boundary (= scroll offset) of an element is within a certain threshold.\n *\n * @param el - Element\n * @param threshold - Threshold\n *\n * @returns Element boundary observable\n */\nexport function watchElementBoundary(\n el: HTMLElement, threshold = 16\n): Observable {\n return watchElementContentOffset(el)\n .pipe(\n map(({ y }) => {\n const visible = getElementSize(el)\n const content = getElementContentSize(el)\n return y >= (\n content.height - visible.height - threshold\n )\n }),\n distinctUntilChanged()\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n fromEvent,\n map,\n startWith\n} from \"rxjs\"\n\nimport { getElement } from \"../element\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Toggle\n */\nexport type Toggle =\n | \"drawer\" /* Toggle for drawer */\n | \"search\" /* Toggle for search */\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Toggle map\n */\nconst toggles: Record = {\n drawer: getElement(\"[data-md-toggle=drawer]\"),\n search: getElement(\"[data-md-toggle=search]\")\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve the value of a toggle\n *\n * @param name - Toggle\n *\n * @returns Toggle value\n */\nexport function getToggle(name: Toggle): boolean {\n return toggles[name].checked\n}\n\n/**\n * Set toggle\n *\n * Simulating a click event seems to be the most cross-browser compatible way\n * of changing the value while also emitting a `change` event. Before, Material\n * used `CustomEvent` to programmatically change the value of a toggle, but this\n * is a much simpler and cleaner solution which doesn't require a polyfill.\n *\n * @param name - Toggle\n * @param value - Toggle value\n */\nexport function setToggle(name: Toggle, value: boolean): void {\n if (toggles[name].checked !== value)\n toggles[name].click()\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch toggle\n *\n * @param name - Toggle\n *\n * @returns Toggle value observable\n */\nexport function watchToggle(name: Toggle): Observable {\n const el = toggles[name]\n return fromEvent(el, \"change\")\n .pipe(\n map(() => el.checked),\n startWith(el.checked)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n filter,\n fromEvent,\n map,\n share\n} from \"rxjs\"\n\nimport { getActiveElement } from \"../element\"\nimport { getToggle } from \"../toggle\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Keyboard mode\n */\nexport type KeyboardMode =\n | \"global\" /* Global */\n | \"search\" /* Search is open */\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Keyboard\n */\nexport interface Keyboard {\n mode: KeyboardMode /* Keyboard mode */\n type: string /* Key type */\n claim(): void /* Key claim */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Check whether an element may receive keyboard input\n *\n * @param el - Element\n * @param type - Key type\n *\n * @returns Test result\n */\nfunction isSusceptibleToKeyboard(\n el: HTMLElement, type: string\n): boolean {\n switch (el.constructor) {\n\n /* Input elements */\n case HTMLInputElement:\n /* @ts-expect-error - omit unnecessary type cast */\n if (el.type === \"radio\")\n return /^Arrow/.test(type)\n else\n return true\n\n /* Select element and textarea */\n case HTMLSelectElement:\n case HTMLTextAreaElement:\n return true\n\n /* Everything else */\n default:\n return el.isContentEditable\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch keyboard\n *\n * @returns Keyboard observable\n */\nexport function watchKeyboard(): Observable {\n return fromEvent(window, \"keydown\")\n .pipe(\n filter(ev => !(ev.metaKey || ev.ctrlKey)),\n map(ev => ({\n mode: getToggle(\"search\") ? \"search\" : \"global\",\n type: ev.key,\n claim() {\n ev.preventDefault()\n ev.stopPropagation()\n }\n } as Keyboard)),\n filter(({ mode, type }) => {\n if (mode === \"global\") {\n const active = getActiveElement()\n if (typeof active !== \"undefined\")\n return !isSusceptibleToKeyboard(active, type)\n }\n return true\n }),\n share()\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Subject } from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve location\n *\n * This function returns a `URL` object (and not `Location`) to normalize the\n * typings across the application. Furthermore, locations need to be tracked\n * without setting them and `Location` is a singleton which represents the\n * current location.\n *\n * @returns URL\n */\nexport function getLocation(): URL {\n return new URL(location.href)\n}\n\n/**\n * Set location\n *\n * @param url - URL to change to\n */\nexport function setLocation(url: URL): void {\n location.href = url.href\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch location\n *\n * @returns Location subject\n */\nexport function watchLocation(): Subject {\n return new Subject()\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { JSX as JSXInternal } from \"preact\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * HTML attributes\n */\ntype Attributes =\n & JSXInternal.HTMLAttributes\n & JSXInternal.SVGAttributes\n & Record\n\n/**\n * Child element\n */\ntype Child =\n | HTMLElement\n | Text\n | string\n | number\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Append a child node to an element\n *\n * @param el - Element\n * @param child - Child node(s)\n */\nfunction appendChild(el: HTMLElement, child: Child | Child[]): void {\n\n /* Handle primitive types (including raw HTML) */\n if (typeof child === \"string\" || typeof child === \"number\") {\n el.innerHTML += child.toString()\n\n /* Handle nodes */\n } else if (child instanceof Node) {\n el.appendChild(child)\n\n /* Handle nested children */\n } else if (Array.isArray(child)) {\n for (const node of child)\n appendChild(el, node)\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * JSX factory\n *\n * @template T - Element type\n *\n * @param tag - HTML tag\n * @param attributes - HTML attributes\n * @param children - Child elements\n *\n * @returns Element\n */\nexport function h(\n tag: T, attributes?: Attributes | null, ...children: Child[]\n): HTMLElementTagNameMap[T]\n\nexport function h(\n tag: string, attributes?: Attributes | null, ...children: Child[]\n): T\n\nexport function h(\n tag: string, attributes?: Attributes | null, ...children: Child[]\n): T {\n const el = document.createElement(tag)\n\n /* Set attributes, if any */\n if (attributes)\n for (const attr of Object.keys(attributes)) {\n if (typeof attributes[attr] === \"undefined\")\n continue\n\n /* Set default attribute or boolean */\n if (typeof attributes[attr] !== \"boolean\")\n el.setAttribute(attr, attributes[attr])\n else\n el.setAttribute(attr, \"\")\n }\n\n /* Append child nodes */\n for (const child of children)\n appendChild(el, child)\n\n /* Return element */\n return el as T\n}\n\n/* ----------------------------------------------------------------------------\n * Namespace\n * ------------------------------------------------------------------------- */\n\nexport declare namespace h {\n namespace JSX {\n type Element = HTMLElement\n type IntrinsicElements = JSXInternal.IntrinsicElements\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Truncate a string after the given number of characters\n *\n * This is not a very reasonable approach, since the summaries kind of suck.\n * It would be better to create something more intelligent, highlighting the\n * search occurrences and making a better summary out of it, but this note was\n * written three years ago, so who knows if we'll ever fix it.\n *\n * @param value - Value to be truncated\n * @param n - Number of characters\n *\n * @returns Truncated value\n */\nexport function truncate(value: string, n: number): string {\n let i = n\n if (value.length > i) {\n while (value[i] !== \" \" && --i > 0) { /* keep eating */ }\n return `${value.substring(0, i)}...`\n }\n return value\n}\n\n/**\n * Round a number for display with repository facts\n *\n * This is a reverse-engineered version of GitHub's weird rounding algorithm\n * for stars, forks and all other numbers. While all numbers below `1,000` are\n * returned as-is, bigger numbers are converted to fixed numbers:\n *\n * - `1,049` => `1k`\n * - `1,050` => `1.1k`\n * - `1,949` => `1.9k`\n * - `1,950` => `2k`\n *\n * @param value - Original value\n *\n * @returns Rounded value\n */\nexport function round(value: number): string {\n if (value > 999) {\n const digits = +((value - 950) % 1000 > 99)\n return `${((value + 0.000001) / 1000).toFixed(digits)}k`\n } else {\n return value.toString()\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n filter,\n fromEvent,\n map,\n shareReplay,\n startWith\n} from \"rxjs\"\n\nimport { getOptionalElement } from \"~/browser\"\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve location hash\n *\n * @returns Location hash\n */\nexport function getLocationHash(): string {\n return location.hash.substring(1)\n}\n\n/**\n * Set location hash\n *\n * Setting a new fragment identifier via `location.hash` will have no effect\n * if the value doesn't change. When a new fragment identifier is set, we want\n * the browser to target the respective element at all times, which is why we\n * use this dirty little trick.\n *\n * @param hash - Location hash\n */\nexport function setLocationHash(hash: string): void {\n const el = h(\"a\", { href: hash })\n el.addEventListener(\"click\", ev => ev.stopPropagation())\n el.click()\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch location hash\n *\n * @returns Location hash observable\n */\nexport function watchLocationHash(): Observable {\n return fromEvent(window, \"hashchange\")\n .pipe(\n map(getLocationHash),\n startWith(getLocationHash()),\n filter(hash => hash.length > 0),\n shareReplay(1)\n )\n}\n\n/**\n * Watch location target\n *\n * @returns Location target observable\n */\nexport function watchLocationTarget(): Observable {\n return watchLocationHash()\n .pipe(\n map(id => getOptionalElement(`[id=\"${id}\"]`)!),\n filter(el => typeof el !== \"undefined\")\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n fromEvent,\n fromEventPattern,\n map,\n merge,\n startWith,\n switchMap\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch media query\n *\n * Note that although `MediaQueryList.addListener` is deprecated we have to\n * use it, because it's the only way to ensure proper downward compatibility.\n *\n * @see https://bit.ly/3dUBH2m - GitHub issue\n *\n * @param query - Media query\n *\n * @returns Media observable\n */\nexport function watchMedia(query: string): Observable {\n const media = matchMedia(query)\n return fromEventPattern(next => (\n media.addListener(() => next(media.matches))\n ))\n .pipe(\n startWith(media.matches)\n )\n}\n\n/**\n * Watch print mode\n *\n * @returns Print observable\n */\nexport function watchPrint(): Observable {\n const media = matchMedia(\"print\")\n return merge(\n fromEvent(window, \"beforeprint\").pipe(map(() => true)),\n fromEvent(window, \"afterprint\").pipe(map(() => false))\n )\n .pipe(\n startWith(media.matches)\n )\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Toggle an observable with a media observable\n *\n * @template T - Data type\n *\n * @param query$ - Media observable\n * @param factory - Observable factory\n *\n * @returns Toggled observable\n */\nexport function at(\n query$: Observable, factory: () => Observable\n): Observable {\n return query$\n .pipe(\n switchMap(active => active ? factory() : EMPTY)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n catchError,\n from,\n map,\n of,\n shareReplay,\n switchMap,\n throwError\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch the given URL\n *\n * If the request fails (e.g. when dispatched from `file://` locations), the\n * observable will complete without emitting a value.\n *\n * @param url - Request URL\n * @param options - Options\n *\n * @returns Response observable\n */\nexport function request(\n url: URL | string, options: RequestInit = { credentials: \"same-origin\" }\n): Observable {\n return from(fetch(`${url}`, options))\n .pipe(\n catchError(() => EMPTY),\n switchMap(res => res.status !== 200\n ? throwError(() => new Error(res.statusText))\n : of(res)\n )\n )\n}\n\n/**\n * Fetch JSON from the given URL\n *\n * @template T - Data type\n *\n * @param url - Request URL\n * @param options - Options\n *\n * @returns Data observable\n */\nexport function requestJSON(\n url: URL | string, options?: RequestInit\n): Observable {\n return request(url, options)\n .pipe(\n switchMap(res => res.json()),\n shareReplay(1)\n )\n}\n\n/**\n * Fetch XML from the given URL\n *\n * @param url - Request URL\n * @param options - Options\n *\n * @returns Data observable\n */\nexport function requestXML(\n url: URL | string, options?: RequestInit\n): Observable {\n const dom = new DOMParser()\n return request(url, options)\n .pipe(\n switchMap(res => res.text()),\n map(res => dom.parseFromString(res, \"text/xml\")),\n shareReplay(1)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n defer,\n finalize,\n fromEvent,\n map,\n merge,\n switchMap,\n take,\n throwError\n} from \"rxjs\"\n\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Create and load a `script` element\n *\n * This function returns an observable that will emit when the script was\n * successfully loaded, or throw an error if it didn't.\n *\n * @param src - Script URL\n *\n * @returns Script observable\n */\nexport function watchScript(src: string): Observable {\n const script = h(\"script\", { src })\n return defer(() => {\n document.head.appendChild(script)\n return merge(\n fromEvent(script, \"load\"),\n fromEvent(script, \"error\")\n .pipe(\n switchMap(() => (\n throwError(() => new ReferenceError(`Invalid script: ${src}`))\n ))\n )\n )\n .pipe(\n map(() => undefined),\n finalize(() => document.head.removeChild(script)),\n take(1)\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n fromEvent,\n map,\n merge,\n startWith\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Viewport offset\n */\nexport interface ViewportOffset {\n x: number /* Horizontal offset */\n y: number /* Vertical offset */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve viewport offset\n *\n * On iOS Safari, viewport offset can be negative due to overflow scrolling.\n * As this may induce strange behaviors downstream, we'll just limit it to 0.\n *\n * @returns Viewport offset\n */\nexport function getViewportOffset(): ViewportOffset {\n return {\n x: Math.max(0, scrollX),\n y: Math.max(0, scrollY)\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch viewport offset\n *\n * @returns Viewport offset observable\n */\nexport function watchViewportOffset(): Observable {\n return merge(\n fromEvent(window, \"scroll\", { passive: true }),\n fromEvent(window, \"resize\", { passive: true })\n )\n .pipe(\n map(getViewportOffset),\n startWith(getViewportOffset())\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n fromEvent,\n map,\n startWith\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Viewport size\n */\nexport interface ViewportSize {\n width: number /* Viewport width */\n height: number /* Viewport height */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve viewport size\n *\n * @returns Viewport size\n */\nexport function getViewportSize(): ViewportSize {\n return {\n width: innerWidth,\n height: innerHeight\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch viewport size\n *\n * @returns Viewport size observable\n */\nexport function watchViewportSize(): Observable {\n return fromEvent(window, \"resize\", { passive: true })\n .pipe(\n map(getViewportSize),\n startWith(getViewportSize())\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n combineLatest,\n map,\n shareReplay\n} from \"rxjs\"\n\nimport {\n ViewportOffset,\n watchViewportOffset\n} from \"../offset\"\nimport {\n ViewportSize,\n watchViewportSize\n} from \"../size\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Viewport\n */\nexport interface Viewport {\n offset: ViewportOffset /* Viewport offset */\n size: ViewportSize /* Viewport size */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch viewport\n *\n * @returns Viewport observable\n */\nexport function watchViewport(): Observable {\n return combineLatest([\n watchViewportOffset(),\n watchViewportSize()\n ])\n .pipe(\n map(([offset, size]) => ({ offset, size })),\n shareReplay(1)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n combineLatest,\n distinctUntilKeyChanged,\n map\n} from \"rxjs\"\n\nimport { Header } from \"~/components\"\n\nimport { getElementOffset } from \"../../element\"\nimport { Viewport } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
/* Header observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch viewport relative to element\n *\n * @param el - Element\n * @param options - Options\n *\n * @returns Viewport observable\n */\nexport function watchViewportAt(\n el: HTMLElement, { viewport$, header$ }: WatchOptions\n): Observable {\n const size$ = viewport$\n .pipe(\n distinctUntilKeyChanged(\"size\")\n )\n\n /* Compute element offset */\n const offset$ = combineLatest([size$, header$])\n .pipe(\n map(() => getElementOffset(el))\n )\n\n /* Compute relative viewport, return hot observable */\n return combineLatest([header$, viewport$, offset$])\n .pipe(\n map(([{ height }, { offset, size }, { x, y }]) => ({\n offset: {\n x: offset.x - x,\n y: offset.y - y + height\n },\n size\n }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n fromEvent,\n map,\n share,\n switchMap,\n tap,\n throttle\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Worker message\n */\nexport interface WorkerMessage {\n type: unknown /* Message type */\n data?: unknown /* Message data */\n}\n\n/**\n * Worker handler\n *\n * @template T - Message type\n */\nexport interface WorkerHandler<\n T extends WorkerMessage\n> {\n tx$: Subject /* Message transmission subject */\n rx$: Observable /* Message receive observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n *\n * @template T - Worker message type\n */\ninterface WatchOptions {\n tx$: Observable /* Message transmission observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch a web worker\n *\n * This function returns an observable that sends all values emitted by the\n * message observable to the web worker. Web worker communication is expected\n * to be bidirectional (request-response) and synchronous. Messages that are\n * emitted during a pending request are throttled, the last one is emitted.\n *\n * @param worker - Web worker\n * @param options - Options\n *\n * @returns Worker message observable\n */\nexport function watchWorker(\n worker: Worker, { tx$ }: WatchOptions\n): Observable {\n\n /* Intercept messages from worker-like objects */\n const rx$ = fromEvent(worker, \"message\")\n .pipe(\n map(({ data }) => data as T)\n )\n\n /* Send and receive messages, return hot observable */\n return tx$\n .pipe(\n throttle(() => rx$, { leading: true, trailing: true }),\n tap(message => worker.postMessage(message)),\n switchMap(() => rx$),\n share()\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { getElement, getLocation } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Feature flag\n */\nexport type Flag =\n | \"announce.dismiss\" /* Dismissable announcement bar */\n | \"content.code.annotate\" /* Code annotations */\n | \"content.tabs.link\" /* Link content tabs */\n | \"header.autohide\" /* Hide header */\n | \"navigation.expand\" /* Automatic expansion */\n | \"navigation.indexes\" /* Section pages */\n | \"navigation.instant\" /* Instant loading */\n | \"navigation.sections\" /* Section navigation */\n | \"navigation.tabs\" /* Tabs navigation */\n | \"navigation.tabs.sticky\" /* Tabs navigation (sticky) */\n | \"navigation.top\" /* Back-to-top button */\n | \"navigation.tracking\" /* Anchor tracking */\n | \"search.highlight\" /* Search highlighting */\n | \"search.share\" /* Search sharing */\n | \"search.suggest\" /* Search suggestions */\n | \"toc.integrate\" /* Integrated table of contents */\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Translation\n */\nexport type Translation =\n | \"clipboard.copy\" /* Copy to clipboard */\n | \"clipboard.copied\" /* Copied to clipboard */\n | \"search.config.lang\" /* Search language */\n | \"search.config.pipeline\" /* Search pipeline */\n | \"search.config.separator\" /* Search separator */\n | \"search.placeholder\" /* Search */\n | \"search.result.placeholder\" /* Type to start searching */\n | \"search.result.none\" /* No matching documents */\n | \"search.result.one\" /* 1 matching document */\n | \"search.result.other\" /* # matching documents */\n | \"search.result.more.one\" /* 1 more on this page */\n | \"search.result.more.other\" /* # more on this page */\n | \"search.result.term.missing\" /* Missing */\n | \"select.version.title\" /* Version selector */\n\n/**\n * Translations\n */\nexport type Translations = Record\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Versioning\n */\nexport interface Versioning {\n provider: \"mike\" /* Version provider */\n default?: string /* Default version */\n}\n\n/**\n * Configuration\n */\nexport interface Config {\n base: string /* Base URL */\n features: Flag[] /* Feature flags */\n translations: Translations /* Translations */\n search: string /* Search worker URL */\n version?: Versioning /* Versioning */\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve global configuration and make base URL absolute\n */\nconst script = getElement(\"#__config\")\nconst config: Config = JSON.parse(script.textContent!)\nconfig.base = `${new URL(config.base, getLocation())}`\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve global configuration\n *\n * @returns Global configuration\n */\nexport function configuration(): Config {\n return config\n}\n\n/**\n * Check whether a feature flag is enabled\n *\n * @param flag - Feature flag\n *\n * @returns Test result\n */\nexport function feature(flag: Flag): boolean {\n return config.features.includes(flag)\n}\n\n/**\n * Retrieve the translation for the given key\n *\n * @param key - Key to be translated\n * @param value - Positional value, if any\n *\n * @returns Translation\n */\nexport function translation(\n key: Translation, value?: string | number\n): string {\n return typeof value !== \"undefined\"\n ? config.translations[key].replace(\"#\", value.toString())\n : config.translations[key]\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { getElement, getElements } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Component type\n */\nexport type ComponentType =\n | \"announce\" /* Announcement bar */\n | \"container\" /* Container */\n | \"consent\" /* Consent */\n | \"content\" /* Content */\n | \"dialog\" /* Dialog */\n | \"header\" /* Header */\n | \"header-title\" /* Header title */\n | \"header-topic\" /* Header topic */\n | \"main\" /* Main area */\n | \"outdated\" /* Version warning */\n | \"palette\" /* Color palette */\n | \"search\" /* Search */\n | \"search-query\" /* Search input */\n | \"search-result\" /* Search results */\n | \"search-share\" /* Search sharing */\n | \"search-suggest\" /* Search suggestions */\n | \"sidebar\" /* Sidebar */\n | \"skip\" /* Skip link */\n | \"source\" /* Repository information */\n | \"tabs\" /* Navigation tabs */\n | \"toc\" /* Table of contents */\n | \"top\" /* Back-to-top button */\n\n/**\n * Component\n *\n * @template T - Component type\n * @template U - Reference type\n */\nexport type Component<\n T extends {} = {},\n U extends HTMLElement = HTMLElement\n> =\n T & {\n ref: U /* Component reference */\n }\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Component type map\n */\ninterface ComponentTypeMap {\n \"announce\": HTMLElement /* Announcement bar */\n \"container\": HTMLElement /* Container */\n \"consent\": HTMLElement /* Consent */\n \"content\": HTMLElement /* Content */\n \"dialog\": HTMLElement /* Dialog */\n \"header\": HTMLElement /* Header */\n \"header-title\": HTMLElement /* Header title */\n \"header-topic\": HTMLElement /* Header topic */\n \"main\": HTMLElement /* Main area */\n \"outdated\": HTMLElement /* Version warning */\n \"palette\": HTMLElement /* Color palette */\n \"search\": HTMLElement /* Search */\n \"search-query\": HTMLInputElement /* Search input */\n \"search-result\": HTMLElement /* Search results */\n \"search-share\": HTMLAnchorElement /* Search sharing */\n \"search-suggest\": HTMLElement /* Search suggestions */\n \"sidebar\": HTMLElement /* Sidebar */\n \"skip\": HTMLAnchorElement /* Skip link */\n \"source\": HTMLAnchorElement /* Repository information */\n \"tabs\": HTMLElement /* Navigation tabs */\n \"toc\": HTMLElement /* Table of contents */\n \"top\": HTMLAnchorElement /* Back-to-top button */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve the element for a given component or throw a reference error\n *\n * @template T - Component type\n *\n * @param type - Component type\n * @param node - Node of reference\n *\n * @returns Element\n */\nexport function getComponentElement(\n type: T, node: ParentNode = document\n): ComponentTypeMap[T] {\n return getElement(`[data-md-component=${type}]`, node)\n}\n\n/**\n * Retrieve all elements for a given component\n *\n * @template T - Component type\n *\n * @param type - Component type\n * @param node - Node of reference\n *\n * @returns Elements\n */\nexport function getComponentElements(\n type: T, node: ParentNode = document\n): ComponentTypeMap[T][] {\n return getElements(`[data-md-component=${type}]`, node)\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n Subject,\n defer,\n finalize,\n fromEvent,\n map,\n startWith,\n tap\n} from \"rxjs\"\n\nimport { feature } from \"~/_\"\nimport { getElement } from \"~/browser\"\n\nimport { Component } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Announcement bar\n */\nexport interface Announce {\n hash: number /* Content hash */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch announcement bar\n *\n * @param el - Announcement bar element\n *\n * @returns Announcement bar observable\n */\nexport function watchAnnounce(\n el: HTMLElement\n): Observable {\n const button = getElement(\".md-typeset > :first-child\", el)\n return fromEvent(button, \"click\", { once: true })\n .pipe(\n map(() => getElement(\".md-typeset\", el)),\n map(content => ({ hash: __md_hash(content.innerHTML) }))\n )\n}\n\n/**\n * Mount announcement bar\n *\n * @param el - Announcement bar element\n *\n * @returns Announcement bar component observable\n */\nexport function mountAnnounce(\n el: HTMLElement\n): Observable> {\n if (!feature(\"announce.dismiss\") || !el.childElementCount)\n return EMPTY\n\n /* Mount component on subscription */\n return defer(() => {\n const push$ = new Subject()\n push$\n .pipe(\n startWith({ hash: __md_get(\"__announce\") })\n )\n .subscribe(({ hash }) => {\n if (hash && hash === (__md_get(\"__announce\") ?? hash)) {\n el.hidden = true\n\n /* Persist preference in local storage */\n __md_set(\"__announce\", hash)\n }\n })\n\n /* Create and return component */\n return watchAnnounce(el)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n finalize,\n map,\n tap\n} from \"rxjs\"\n\nimport { Component } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Consent\n */\nexport interface Consent {\n hidden: boolean /* Consent is hidden */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n target$: Observable /* Target observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n target$: Observable /* Target observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch consent\n *\n * @param el - Consent element\n * @param options - Options\n *\n * @returns Consent observable\n */\nexport function watchConsent(\n el: HTMLElement, { target$ }: WatchOptions\n): Observable {\n return target$\n .pipe(\n map(target => ({ hidden: target !== el }))\n )\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Mount consent\n *\n * @param el - Consent element\n * @param options - Options\n *\n * @returns Consent component observable\n */\nexport function mountConsent(\n el: HTMLElement, options: MountOptions\n): Observable> {\n const internal$ = new Subject()\n internal$.subscribe(({ hidden }) => {\n el.hidden = hidden\n })\n\n /* Create and return component */\n return watchConsent(el, options)\n .pipe(\n tap(state => internal$.next(state)),\n finalize(() => internal$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport ClipboardJS from \"clipboard\"\nimport {\n EMPTY,\n Observable,\n Subject,\n defer,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n filter,\n finalize,\n map,\n mergeWith,\n switchMap,\n take,\n takeLast,\n takeUntil,\n tap\n} from \"rxjs\"\n\nimport { feature } from \"~/_\"\nimport {\n getElementContentSize,\n watchElementSize,\n watchElementVisibility\n} from \"~/browser\"\nimport { renderClipboardButton } from \"~/templates\"\n\nimport { Component } from \"../../../_\"\nimport {\n Annotation,\n mountAnnotationList\n} from \"../../annotation\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Code block\n */\nexport interface CodeBlock {\n scrollable: boolean /* Code block overflows */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n print$: Observable /* Media print observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Global sequence number for Clipboard.js integration\n */\nlet sequence = 0\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Find candidate list element directly following a code block\n *\n * @param el - Code block element\n *\n * @returns List element or nothing\n */\nfunction findCandidateList(el: HTMLElement): HTMLElement | undefined {\n if (el.nextElementSibling) {\n const sibling = el.nextElementSibling as HTMLElement\n if (sibling.tagName === \"OL\")\n return sibling\n\n /* Skip empty paragraphs - see https://bit.ly/3r4ZJ2O */\n else if (sibling.tagName === \"P\" && !sibling.children.length)\n return findCandidateList(sibling)\n }\n\n /* Everything else */\n return undefined\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch code block\n *\n * This function monitors size changes of the viewport, as well as switches of\n * content tabs with embedded code blocks, as both may trigger overflow.\n *\n * @param el - Code block element\n *\n * @returns Code block observable\n */\nexport function watchCodeBlock(\n el: HTMLElement\n): Observable {\n return watchElementSize(el)\n .pipe(\n map(({ width }) => {\n const content = getElementContentSize(el)\n return {\n scrollable: content.width > width\n }\n }),\n distinctUntilKeyChanged(\"scrollable\")\n )\n}\n\n/**\n * Mount code block\n *\n * This function ensures that an overflowing code block is focusable through\n * keyboard, so it can be scrolled without a mouse to improve on accessibility.\n * Furthermore, if code annotations are enabled, they are mounted if and only\n * if the code block is currently visible, e.g., not in a hidden content tab.\n *\n * @param el - Code block element\n * @param options - Options\n *\n * @returns Code block and annotation component observable\n */\nexport function mountCodeBlock(\n el: HTMLElement, options: MountOptions\n): Observable> {\n const { matches: hover } = matchMedia(\"(hover)\")\n\n /* Defer mounting of code block - see https://bit.ly/3vHVoVD */\n const factory$ = defer(() => {\n const push$ = new Subject()\n push$.subscribe(({ scrollable }) => {\n if (scrollable && hover)\n el.setAttribute(\"tabindex\", \"0\")\n else\n el.removeAttribute(\"tabindex\")\n })\n\n /* Render button for Clipboard.js integration */\n if (ClipboardJS.isSupported()) {\n const parent = el.closest(\"pre\")!\n parent.id = `__code_${++sequence}`\n parent.insertBefore(\n renderClipboardButton(parent.id),\n el\n )\n }\n\n /* Handle code annotations */\n const container = el.closest(\".highlight\")\n if (container instanceof HTMLElement) {\n const list = findCandidateList(container)\n\n /* Mount code annotations, if enabled */\n if (typeof list !== \"undefined\" && (\n container.classList.contains(\"annotate\") ||\n feature(\"content.code.annotate\")\n )) {\n const annotations$ = mountAnnotationList(list, el, options)\n\n /* Create and return component */\n return watchCodeBlock(el)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state })),\n mergeWith(\n watchElementSize(container)\n .pipe(\n takeUntil(push$.pipe(takeLast(1))),\n map(({ width, height }) => width && height),\n distinctUntilChanged(),\n switchMap(active => active ? annotations$ : EMPTY)\n )\n )\n )\n }\n }\n\n /* Create and return component */\n return watchCodeBlock(el)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n\n /* Mount code block on first sight */\n return watchElementVisibility(el)\n .pipe(\n filter(visible => visible),\n take(1),\n switchMap(() => factory$)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render an empty annotation\n *\n * @param id - Annotation identifier\n *\n * @returns Element\n */\nexport function renderAnnotation(id: number): HTMLElement {\n return (\n \n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { translation } from \"~/_\"\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a 'copy-to-clipboard' button\n *\n * @param id - Unique identifier\n *\n * @returns Element\n */\nexport function renderClipboardButton(id: string): HTMLElement {\n return (\n code`}\n >\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { ComponentChild } from \"preact\"\n\nimport { feature, translation } from \"~/_\"\nimport {\n SearchDocument,\n SearchMetadata,\n SearchResultItem\n} from \"~/integrations/search\"\nimport { h, truncate } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Render flag\n */\nconst enum Flag {\n TEASER = 1, /* Render teaser */\n PARENT = 2 /* Render as parent */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper function\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a search document\n *\n * @param document - Search document\n * @param flag - Render flags\n *\n * @returns Element\n */\nfunction renderSearchDocument(\n document: SearchDocument & SearchMetadata, flag: Flag\n): HTMLElement {\n const parent = flag & Flag.PARENT\n const teaser = flag & Flag.TEASER\n\n /* Render missing query terms */\n const missing = Object.keys(document.terms)\n .filter(key => !document.terms[key])\n .reduce((list, key) => [\n ...list, {key}, \" \"\n ], [])\n .slice(0, -1)\n\n /* Assemble query string for highlighting */\n const url = new URL(document.location)\n if (feature(\"search.highlight\"))\n url.searchParams.set(\"h\", Object.entries(document.terms)\n .filter(([, match]) => match)\n .reduce((highlight, [value]) => `${highlight} ${value}`.trim(), \"\")\n )\n\n /* Render article or section, depending on flags */\n return (\n \n \n {parent > 0 &&
}\n

{document.title}

\n {teaser > 0 && document.text.length > 0 &&\n

\n {truncate(document.text, 320)}\n

\n }\n {document.tags && document.tags.map(tag => (\n {tag}\n ))}\n {teaser > 0 && missing.length > 0 &&\n

\n {translation(\"search.result.term.missing\")}: {...missing}\n

\n }\n \n
\n )\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a search result\n *\n * @param result - Search result\n *\n * @returns Element\n */\nexport function renderSearchResultItem(\n result: SearchResultItem\n): HTMLElement {\n const threshold = result[0].score\n const docs = [...result]\n\n /* Find and extract parent article */\n const parent = docs.findIndex(doc => !doc.location.includes(\"#\"))\n const [article] = docs.splice(parent, 1)\n\n /* Determine last index above threshold */\n let index = docs.findIndex(doc => doc.score < threshold)\n if (index === -1)\n index = docs.length\n\n /* Partition sections */\n const best = docs.slice(0, index)\n const more = docs.slice(index)\n\n /* Render children */\n const children = [\n renderSearchDocument(article, Flag.PARENT | +(!parent && index === 0)),\n ...best.map(section => renderSearchDocument(section, Flag.TEASER)),\n ...more.length ? [\n
\n \n {more.length > 0 && more.length === 1\n ? translation(\"search.result.more.one\")\n : translation(\"search.result.more.other\", more.length)\n }\n \n {...more.map(section => renderSearchDocument(section, Flag.TEASER))}\n
\n ] : []\n ]\n\n /* Render search result */\n return (\n
  • \n {children}\n
  • \n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { SourceFacts } from \"~/components\"\nimport { h, round } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render repository facts\n *\n * @param facts - Repository facts\n *\n * @returns Element\n */\nexport function renderSourceFacts(facts: SourceFacts): HTMLElement {\n return (\n
      \n {Object.entries(facts).map(([key, value]) => (\n
    • \n {typeof value === \"number\" ? round(value) : value}\n
    • \n ))}\n
    \n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Tabbed control type\n */\ntype TabbedControlType =\n | \"prev\"\n | \"next\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render control for content tabs\n *\n * @param type - Control type\n *\n * @returns Element\n */\nexport function renderTabbedControl(\n type: TabbedControlType\n): HTMLElement {\n const classes = `tabbed-control tabbed-control--${type}`\n return (\n \n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a table inside a wrapper to improve scrolling on mobile\n *\n * @param table - Table element\n *\n * @returns Element\n */\nexport function renderTable(table: HTMLElement): HTMLElement {\n return (\n
    \n
    \n {table}\n
    \n
    \n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { configuration, translation } from \"~/_\"\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Version\n */\nexport interface Version {\n version: string /* Version identifier */\n title: string /* Version title */\n aliases: string[] /* Version aliases */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a version\n *\n * @param version - Version\n *\n * @returns Element\n */\nfunction renderVersion(version: Version): HTMLElement {\n const config = configuration()\n\n /* Ensure trailing slash, see https://bit.ly/3rL5u3f */\n const url = new URL(`../${version.version}/`, config.base)\n return (\n
  • \n \n {version.title}\n \n
  • \n )\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a version selector\n *\n * @param versions - Versions\n * @param active - Active version\n *\n * @returns Element\n */\nexport function renderVersionSelector(\n versions: Version[], active: Version\n): HTMLElement {\n return (\n
    \n \n {active.title}\n \n
      \n {versions.map(renderVersion)}\n
    \n
    \n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n Subject,\n animationFrameScheduler,\n combineLatest,\n defer,\n finalize,\n fromEvent,\n map,\n switchMap,\n take,\n takeLast,\n takeUntil,\n tap,\n throttleTime\n} from \"rxjs\"\n\nimport {\n ElementOffset,\n getElement,\n getElementSize,\n watchElementContentOffset,\n watchElementFocus,\n watchElementOffset,\n watchElementVisibility\n} from \"~/browser\"\n\nimport { Component } from \"../../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Annotation\n */\nexport interface Annotation {\n active: boolean /* Annotation is active */\n offset: ElementOffset /* Annotation offset */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch annotation\n *\n * @param el - Annotation element\n * @param container - Containing element\n *\n * @returns Annotation observable\n */\nexport function watchAnnotation(\n el: HTMLElement, container: HTMLElement\n): Observable {\n const offset$ = defer(() => combineLatest([\n watchElementOffset(el),\n watchElementContentOffset(container)\n ]))\n .pipe(\n map(([{ x, y }, scroll]) => {\n const { width } = getElementSize(el)\n return ({\n x: x - scroll.x + width / 2,\n y: y - scroll.y\n })\n })\n )\n\n /* Actively watch annotation on focus */\n return watchElementFocus(el)\n .pipe(\n switchMap(active => offset$\n .pipe(\n map(offset => ({ active, offset })),\n take(+!active || Infinity)\n )\n )\n )\n}\n\n/**\n * Mount annotation\n *\n * @param el - Annotation element\n * @param container - Containing element\n *\n * @returns Annotation component observable\n */\nexport function mountAnnotation(\n el: HTMLElement, container: HTMLElement\n): Observable> {\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe({\n\n /* Handle emission */\n next({ offset }) {\n el.style.setProperty(\"--md-tooltip-x\", `${offset.x}px`)\n el.style.setProperty(\"--md-tooltip-y\", `${offset.y}px`)\n },\n\n /* Handle complete */\n complete() {\n el.style.removeProperty(\"--md-tooltip-x\")\n el.style.removeProperty(\"--md-tooltip-y\")\n }\n })\n\n /* Start animation only when annotation is visible */\n const done$ = push$.pipe(takeLast(1))\n watchElementVisibility(el)\n .pipe(\n takeUntil(done$)\n )\n .subscribe(visible => {\n el.toggleAttribute(\"data-md-visible\", visible)\n })\n\n /* Track relative origin of tooltip */\n push$\n .pipe(\n throttleTime(500, animationFrameScheduler),\n map(() => container.getBoundingClientRect()),\n map(({ x }) => x)\n )\n .subscribe({\n\n /* Handle emission */\n next(origin) {\n if (origin)\n el.style.setProperty(\"--md-tooltip-0\", `${-origin}px`)\n else\n el.style.removeProperty(\"--md-tooltip-0\")\n },\n\n /* Handle complete */\n complete() {\n el.style.removeProperty(\"--md-tooltip-0\")\n }\n })\n\n /* Close open annotation on click */\n const index = getElement(\":scope > :last-child\", el)\n const blur$ = fromEvent(index, \"mousedown\", { once: true })\n push$\n .pipe(\n switchMap(({ active }) => active ? blur$ : EMPTY),\n tap(ev => ev.preventDefault())\n )\n .subscribe(() => el.blur())\n\n /* Create and return component */\n return watchAnnotation(el, container)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n Subject,\n defer,\n finalize,\n merge,\n share,\n takeLast,\n takeUntil\n} from \"rxjs\"\n\nimport {\n getElement,\n getElements,\n getOptionalElement\n} from \"~/browser\"\nimport { renderAnnotation } from \"~/templates\"\n\nimport { Component } from \"../../../_\"\nimport {\n Annotation,\n mountAnnotation\n} from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n print$: Observable /* Media print observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Find all annotation markers in the given code block\n *\n * @param container - Containing element\n *\n * @returns Annotation markers\n */\nfunction findAnnotationMarkers(container: HTMLElement): Text[] {\n const markers: Text[] = []\n for (const comment of getElements(\".c, .c1, .cm\", container)) {\n let match: RegExpExecArray | null\n\n /* Split text at marker and add to list */\n let text = comment.firstChild as Text\n if (text instanceof Text)\n while ((match = /\\((\\d+)\\)/.exec(text.textContent!))) {\n const marker = text.splitText(match.index)\n text = marker.splitText(match[0].length)\n markers.push(marker)\n }\n }\n return markers\n}\n\n/**\n * Swap the child nodes of two elements\n *\n * @param source - Source element\n * @param target - Target element\n */\nfunction swap(source: HTMLElement, target: HTMLElement): void {\n target.append(...Array.from(source.childNodes))\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount annotation list\n *\n * This function analyzes the containing code block and checks for markers\n * referring to elements in the given annotation list. If no markers are found,\n * the list is left untouched. Otherwise, list elements are rendered as\n * annotations inside the code block.\n *\n * @param el - Annotation list element\n * @param container - Containing element\n * @param options - Options\n *\n * @returns Annotation component observable\n */\nexport function mountAnnotationList(\n el: HTMLElement, container: HTMLElement, { print$ }: MountOptions\n): Observable> {\n\n /* Find and replace all markers with empty annotations */\n const annotations = new Map()\n for (const marker of findAnnotationMarkers(container)) {\n const [, id] = marker.textContent!.match(/\\((\\d+)\\)/)!\n if (getOptionalElement(`li:nth-child(${id})`, el)) {\n annotations.set(+id, renderAnnotation(+id))\n marker.replaceWith(annotations.get(+id)!)\n }\n }\n\n /* Keep list if there are no annotations to render */\n if (annotations.size === 0)\n return EMPTY\n\n /* Create and return component */\n return defer(() => {\n const done$ = new Subject()\n\n /* Handle print mode - see https://bit.ly/3rgPdpt */\n print$\n .pipe(\n takeUntil(done$.pipe(takeLast(1)))\n )\n .subscribe(active => {\n el.hidden = !active\n\n /* Show annotations in code block or list (print) */\n for (const [id, annotation] of annotations) {\n const inner = getElement(\".md-typeset\", annotation)\n const child = getElement(`li:nth-child(${id})`, el)\n if (!active)\n swap(child, inner)\n else\n swap(inner, child)\n }\n })\n\n /* Create and return component */\n return merge(...[...annotations]\n .map(([, annotation]) => (\n mountAnnotation(annotation, container)\n ))\n )\n .pipe(\n finalize(() => done$.complete()),\n share()\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n map,\n of,\n shareReplay,\n tap\n} from \"rxjs\"\n\nimport { watchScript } from \"~/browser\"\nimport { h } from \"~/utilities\"\n\nimport { Component } from \"../../../_\"\n\nimport themeCSS from \"./index.css\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mermaid diagram\n */\nexport interface Mermaid {}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Mermaid instance observable\n */\nlet mermaid$: Observable\n\n/**\n * Global sequence number for diagrams\n */\nlet sequence = 0\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch Mermaid script\n *\n * @returns Mermaid scripts observable\n */\nfunction fetchScripts(): Observable {\n return typeof mermaid === \"undefined\" || mermaid instanceof Element\n ? watchScript(\"https://unpkg.com/mermaid@9.0.1/dist/mermaid.min.js\")\n : of(undefined)\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount Mermaid diagram\n *\n * @param el - Code block element\n *\n * @returns Mermaid diagram component observable\n */\nexport function mountMermaid(\n el: HTMLElement\n): Observable> {\n el.classList.remove(\"mermaid\") // Hack: mitigate https://bit.ly/3CiN6Du\n mermaid$ ||= fetchScripts()\n .pipe(\n tap(() => mermaid.initialize({\n startOnLoad: false,\n themeCSS\n })),\n map(() => undefined),\n shareReplay(1)\n )\n\n /* Render diagram */\n mermaid$.subscribe(() => {\n el.classList.add(\"mermaid\") // Hack: mitigate https://bit.ly/3CiN6Du\n const id = `__mermaid_${sequence++}`\n const host = h(\"div\", { class: \"mermaid\" })\n mermaid.mermaidAPI.render(id, el.textContent, (svg: string) => {\n\n /* Create a shadow root and inject diagram */\n const shadow = host.attachShadow({ mode: \"closed\" })\n shadow.innerHTML = svg\n\n /* Replace code block with diagram */\n el.replaceWith(host)\n })\n })\n\n /* Create and return component */\n return mermaid$\n .pipe(\n map(() => ({ ref: el }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n defer,\n filter,\n finalize,\n map,\n merge,\n tap\n} from \"rxjs\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Details\n */\nexport interface Details {\n action: \"open\" | \"close\" /* Details state */\n reveal?: boolean /* Details is revealed */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n target$: Observable /* Location target observable */\n print$: Observable /* Media print observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n target$: Observable /* Location target observable */\n print$: Observable /* Media print observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch details\n *\n * @param el - Details element\n * @param options - Options\n *\n * @returns Details observable\n */\nexport function watchDetails(\n el: HTMLDetailsElement, { target$, print$ }: WatchOptions\n): Observable
    {\n let open = true\n return merge(\n\n /* Open and focus details on location target */\n target$\n .pipe(\n map(target => target.closest(\"details:not([open])\")!),\n filter(details => el === details),\n map(() => ({\n action: \"open\", reveal: true\n }) as Details)\n ),\n\n /* Open details on print and close afterwards */\n print$\n .pipe(\n filter(active => active || !open),\n tap(() => open = el.open),\n map(active => ({\n action: active ? \"open\" : \"close\"\n }) as Details)\n )\n )\n}\n\n/**\n * Mount details\n *\n * This function ensures that `details` tags are opened on anchor jumps and\n * prior to printing, so the whole content of the page is visible.\n *\n * @param el - Details element\n * @param options - Options\n *\n * @returns Details component observable\n */\nexport function mountDetails(\n el: HTMLDetailsElement, options: MountOptions\n): Observable> {\n return defer(() => {\n const push$ = new Subject
    ()\n push$.subscribe(({ action, reveal }) => {\n if (action === \"open\")\n el.setAttribute(\"open\", \"\")\n else\n el.removeAttribute(\"open\")\n if (reveal)\n el.scrollIntoView()\n })\n\n /* Create and return component */\n return watchDetails(el, options)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, of } from \"rxjs\"\n\nimport { renderTable } from \"~/templates\"\nimport { h } from \"~/utilities\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Data table\n */\nexport interface DataTable {}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Sentinel for replacement\n */\nconst sentinel = h(\"table\")\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount data table\n *\n * This function wraps a data table in another scrollable container, so it can\n * be smoothly scrolled on smaller screen sizes and won't break the layout.\n *\n * @param el - Data table element\n *\n * @returns Data table component observable\n */\nexport function mountDataTable(\n el: HTMLElement\n): Observable> {\n el.replaceWith(sentinel)\n sentinel.replaceWith(renderTable(el))\n\n /* Create and return component */\n return of({ ref: el })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n animationFrameScheduler,\n asyncScheduler,\n auditTime,\n combineLatest,\n defer,\n finalize,\n fromEvent,\n map,\n merge,\n skip,\n startWith,\n subscribeOn,\n takeLast,\n takeUntil,\n tap\n} from \"rxjs\"\n\nimport { feature } from \"~/_\"\nimport {\n getElement,\n getElementContentOffset,\n getElementContentSize,\n getElementOffset,\n getElementSize,\n getElements,\n watchElementContentOffset,\n watchElementSize\n} from \"~/browser\"\nimport { renderTabbedControl } from \"~/templates\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Content tabs\n */\nexport interface ContentTabs {\n active: HTMLLabelElement /* Active tab label */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch content tabs\n *\n * @param el - Content tabs element\n *\n * @returns Content tabs observable\n */\nexport function watchContentTabs(\n el: HTMLElement\n): Observable {\n const inputs = getElements(\":scope > input\", el)\n const initial = inputs.find(input => input.checked) || inputs[0]\n return merge(...inputs.map(input => fromEvent(input, \"change\")\n .pipe(\n map(() => getElement(`label[for=\"${input.id}\"]`))\n )\n ))\n .pipe(\n startWith(getElement(`label[for=\"${initial.id}\"]`)),\n map(active => ({ active }))\n )\n}\n\n/**\n * Mount content tabs\n *\n * This function scrolls the active tab into view. While this functionality is\n * provided by browsers as part of `scrollInfoView`, browsers will always also\n * scroll the vertical axis, which we do not want. Thus, we decided to provide\n * this functionality ourselves.\n *\n * @param el - Content tabs element\n *\n * @returns Content tabs component observable\n */\nexport function mountContentTabs(\n el: HTMLElement\n): Observable> {\n\n /* Render content tab previous button for pagination */\n const prev = renderTabbedControl(\"prev\")\n el.append(prev)\n\n /* Render content tab next button for pagination */\n const next = renderTabbedControl(\"next\")\n el.append(next)\n\n /* Mount component on subscription */\n const container = getElement(\".tabbed-labels\", el)\n return defer(() => {\n const push$ = new Subject()\n const done$ = push$.pipe(takeLast(1))\n combineLatest([push$, watchElementSize(el)])\n .pipe(\n auditTime(1, animationFrameScheduler),\n takeUntil(done$)\n )\n .subscribe({\n\n /* Handle emission */\n next([{ active }, size]) {\n const offset = getElementOffset(active)\n const { width } = getElementSize(active)\n\n /* Set tab indicator offset and width */\n el.style.setProperty(\"--md-indicator-x\", `${offset.x}px`)\n el.style.setProperty(\"--md-indicator-width\", `${width}px`)\n\n /* Scroll container to active content tab */\n const content = getElementContentOffset(container)\n if (\n offset.x < content.x ||\n offset.x + width > content.x + size.width\n )\n container.scrollTo({\n left: Math.max(0, offset.x - 16),\n behavior: \"smooth\"\n })\n },\n\n /* Handle complete */\n complete() {\n el.style.removeProperty(\"--md-indicator-x\")\n el.style.removeProperty(\"--md-indicator-width\")\n }\n })\n\n /* Hide content tab buttons on borders */\n combineLatest([\n watchElementContentOffset(container),\n watchElementSize(container)\n ])\n .pipe(\n takeUntil(done$)\n )\n .subscribe(([offset, size]) => {\n const content = getElementContentSize(container)\n prev.hidden = offset.x < 16\n next.hidden = offset.x > content.width - size.width - 16\n })\n\n /* Paginate content tab container on click */\n merge(\n fromEvent(prev, \"click\").pipe(map(() => -1)),\n fromEvent(next, \"click\").pipe(map(() => +1))\n )\n .pipe(\n takeUntil(done$)\n )\n .subscribe(direction => {\n const { width } = getElementSize(container)\n container.scrollBy({\n left: width * direction,\n behavior: \"smooth\"\n })\n })\n\n /* Set up linking of content tabs, if enabled */\n if (feature(\"content.tabs.link\"))\n push$.pipe(skip(1))\n .subscribe(({ active }) => {\n const tab = active.innerText.trim()\n for (const set of getElements(\"[data-tabs]\"))\n for (const input of getElements(\n \":scope > input\", set\n )) {\n const label = getElement(`label[for=\"${input.id}\"]`)\n if (label.innerText.trim() === tab) {\n input.click()\n break\n }\n }\n\n /* Persist active tabs in local storage */\n const tabs = __md_get(\"__tabs\") || []\n __md_set(\"__tabs\", [...new Set([tab, ...tabs])])\n })\n\n /* Create and return component */\n return watchContentTabs(el)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n .pipe(\n subscribeOn(asyncScheduler)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, merge } from \"rxjs\"\n\nimport { getElements } from \"~/browser\"\n\nimport { Component } from \"../../_\"\nimport { Annotation } from \"../annotation\"\nimport {\n CodeBlock,\n Mermaid,\n mountCodeBlock,\n mountMermaid\n} from \"../code\"\nimport {\n Details,\n mountDetails\n} from \"../details\"\nimport {\n DataTable,\n mountDataTable\n} from \"../table\"\nimport {\n ContentTabs,\n mountContentTabs\n} from \"../tabs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Content\n */\nexport type Content =\n | Annotation\n | ContentTabs\n | CodeBlock\n | Mermaid\n | DataTable\n | Details\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n target$: Observable /* Location target observable */\n print$: Observable /* Media print observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount content\n *\n * This function mounts all components that are found in the content of the\n * actual article, including code blocks, data tables and details.\n *\n * @param el - Content element\n * @param options - Options\n *\n * @returns Content component observable\n */\nexport function mountContent(\n el: HTMLElement, { target$, print$ }: MountOptions\n): Observable> {\n return merge(\n\n /* Code blocks */\n ...getElements(\"pre:not(.mermaid) > code\", el)\n .map(child => mountCodeBlock(child, { print$ })),\n\n /* Mermaid diagrams */\n ...getElements(\"pre.mermaid\", el)\n .map(child => mountMermaid(child)),\n\n /* Data tables */\n ...getElements(\"table:not([class])\", el)\n .map(child => mountDataTable(child)),\n\n /* Details */\n ...getElements(\"details\", el)\n .map(child => mountDetails(child, { target$, print$ })),\n\n /* Content tabs */\n ...getElements(\"[data-tabs]\", el)\n .map(child => mountContentTabs(child))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n defer,\n delay,\n finalize,\n map,\n merge,\n of,\n switchMap,\n tap\n} from \"rxjs\"\n\nimport { getElement } from \"~/browser\"\n\nimport { Component } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Dialog\n */\nexport interface Dialog {\n message: string /* Dialog message */\n active: boolean /* Dialog is active */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n alert$: Subject /* Alert subject */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n alert$: Subject /* Alert subject */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch dialog\n *\n * @param _el - Dialog element\n * @param options - Options\n *\n * @returns Dialog observable\n */\nexport function watchDialog(\n _el: HTMLElement, { alert$ }: WatchOptions\n): Observable {\n return alert$\n .pipe(\n switchMap(message => merge(\n of(true),\n of(false).pipe(delay(2000))\n )\n .pipe(\n map(active => ({ message, active }))\n )\n )\n )\n}\n\n/**\n * Mount dialog\n *\n * This function reveals the dialog in the right corner when a new alert is\n * emitted through the subject that is passed as part of the options.\n *\n * @param el - Dialog element\n * @param options - Options\n *\n * @returns Dialog component observable\n */\nexport function mountDialog(\n el: HTMLElement, options: MountOptions\n): Observable> {\n const inner = getElement(\".md-typeset\", el)\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe(({ message, active }) => {\n el.classList.toggle(\"md-dialog--active\", active)\n inner.textContent = message\n })\n\n /* Create and return component */\n return watchDialog(el, options)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n bufferCount,\n combineLatest,\n combineLatestWith,\n defer,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n filter,\n map,\n of,\n shareReplay,\n startWith,\n switchMap,\n takeLast,\n takeUntil\n} from \"rxjs\"\n\nimport { feature } from \"~/_\"\nimport {\n Viewport,\n watchElementSize,\n watchToggle\n} from \"~/browser\"\n\nimport { Component } from \"../../_\"\nimport { Main } from \"../../main\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Header\n */\nexport interface Header {\n height: number /* Header visible height */\n hidden: boolean /* Header is hidden */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n main$: Observable
    /* Main area observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Compute whether the header is hidden\n *\n * If the user scrolls past a certain threshold, the header can be hidden when\n * scrolling down, and shown when scrolling up.\n *\n * @param options - Options\n *\n * @returns Toggle observable\n */\nfunction isHidden({ viewport$ }: WatchOptions): Observable {\n if (!feature(\"header.autohide\"))\n return of(false)\n\n /* Compute direction and turning point */\n const direction$ = viewport$\n .pipe(\n map(({ offset: { y } }) => y),\n bufferCount(2, 1),\n map(([a, b]) => [a < b, b] as const),\n distinctUntilKeyChanged(0)\n )\n\n /* Compute whether header should be hidden */\n const hidden$ = combineLatest([viewport$, direction$])\n .pipe(\n filter(([{ offset }, [, y]]) => Math.abs(y - offset.y) > 100),\n map(([, [direction]]) => direction),\n distinctUntilChanged()\n )\n\n /* Compute threshold for hiding */\n const search$ = watchToggle(\"search\")\n return combineLatest([viewport$, search$])\n .pipe(\n map(([{ offset }, search]) => offset.y > 400 && !search),\n distinctUntilChanged(),\n switchMap(active => active ? hidden$ : of(false)),\n startWith(false)\n )\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch header\n *\n * @param el - Header element\n * @param options - Options\n *\n * @returns Header observable\n */\nexport function watchHeader(\n el: HTMLElement, options: WatchOptions\n): Observable
    {\n return defer(() => combineLatest([\n watchElementSize(el),\n isHidden(options)\n ]))\n .pipe(\n map(([{ height }, hidden]) => ({\n height,\n hidden\n })),\n distinctUntilChanged((a, b) => (\n a.height === b.height &&\n a.hidden === b.hidden\n )),\n shareReplay(1)\n )\n}\n\n/**\n * Mount header\n *\n * This function manages the different states of the header, i.e. whether it's\n * hidden or rendered with a shadow. This depends heavily on the main area.\n *\n * @param el - Header element\n * @param options - Options\n *\n * @returns Header component observable\n */\nexport function mountHeader(\n el: HTMLElement, { header$, main$ }: MountOptions\n): Observable> {\n return defer(() => {\n const push$ = new Subject
    ()\n const done$ = push$.pipe(takeLast(1))\n push$\n .pipe(\n distinctUntilKeyChanged(\"active\"),\n combineLatestWith(header$)\n )\n .subscribe(([{ active }, { hidden }]) => {\n el.classList.toggle(\"md-header--shadow\", active && !hidden)\n el.hidden = hidden\n })\n\n /* Link to main area */\n main$.subscribe(push$)\n\n /* Create and return component */\n return header$\n .pipe(\n takeUntil(done$),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n Subject,\n defer,\n distinctUntilKeyChanged,\n finalize,\n map,\n tap\n} from \"rxjs\"\n\nimport {\n Viewport,\n getElementSize,\n getOptionalElement,\n watchViewportAt\n} from \"~/browser\"\n\nimport { Component } from \"../../_\"\nimport { Header } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Header\n */\nexport interface HeaderTitle {\n active: boolean /* Header title is active */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch header title\n *\n * @param el - Heading element\n * @param options - Options\n *\n * @returns Header title observable\n */\nexport function watchHeaderTitle(\n el: HTMLElement, { viewport$, header$ }: WatchOptions\n): Observable {\n return watchViewportAt(el, { viewport$, header$ })\n .pipe(\n map(({ offset: { y } }) => {\n const { height } = getElementSize(el)\n return {\n active: y >= height\n }\n }),\n distinctUntilKeyChanged(\"active\")\n )\n}\n\n/**\n * Mount header title\n *\n * This function swaps the header title from the site title to the title of the\n * current page when the user scrolls past the first headline.\n *\n * @param el - Header title element\n * @param options - Options\n *\n * @returns Header title component observable\n */\nexport function mountHeaderTitle(\n el: HTMLElement, options: MountOptions\n): Observable> {\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe(({ active }) => {\n el.classList.toggle(\"md-header__title--active\", active)\n })\n\n /* Obtain headline, if any */\n const heading = getOptionalElement(\"article h1\")\n if (typeof heading === \"undefined\")\n return EMPTY\n\n /* Create and return component */\n return watchHeaderTitle(heading, options)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n combineLatest,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n map,\n switchMap\n} from \"rxjs\"\n\nimport {\n Viewport,\n watchElementSize\n} from \"~/browser\"\n\nimport { Header } from \"../header\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Main area\n */\nexport interface Main {\n offset: number /* Main area top offset */\n height: number /* Main area visible height */\n active: boolean /* Main area is active */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch main area\n *\n * This function returns an observable that computes the visual parameters of\n * the main area which depends on the viewport vertical offset and height, as\n * well as the height of the header element, if the header is fixed.\n *\n * @param el - Main area element\n * @param options - Options\n *\n * @returns Main area observable\n */\nexport function watchMain(\n el: HTMLElement, { viewport$, header$ }: WatchOptions\n): Observable
    {\n\n /* Compute necessary adjustment for header */\n const adjust$ = header$\n .pipe(\n map(({ height }) => height),\n distinctUntilChanged()\n )\n\n /* Compute the main area's top and bottom borders */\n const border$ = adjust$\n .pipe(\n switchMap(() => watchElementSize(el)\n .pipe(\n map(({ height }) => ({\n top: el.offsetTop,\n bottom: el.offsetTop + height\n })),\n distinctUntilKeyChanged(\"bottom\")\n )\n )\n )\n\n /* Compute the main area's offset, visible height and if we scrolled past */\n return combineLatest([adjust$, border$, viewport$])\n .pipe(\n map(([header, { top, bottom }, { offset: { y }, size: { height } }]) => {\n height = Math.max(0, height\n - Math.max(0, top - y, header)\n - Math.max(0, height + y - bottom)\n )\n return {\n offset: top - header,\n height,\n active: top - header <= y\n }\n }),\n distinctUntilChanged((a, b) => (\n a.offset === b.offset &&\n a.height === b.height &&\n a.active === b.active\n ))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n asyncScheduler,\n defer,\n finalize,\n fromEvent,\n map,\n mergeMap,\n observeOn,\n of,\n shareReplay,\n startWith,\n tap\n} from \"rxjs\"\n\nimport { getElements } from \"~/browser\"\n\nimport { Component } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Palette colors\n */\nexport interface PaletteColor {\n scheme?: string /* Color scheme */\n primary?: string /* Primary color */\n accent?: string /* Accent color */\n}\n\n/**\n * Palette\n */\nexport interface Palette {\n index: number /* Palette index */\n color: PaletteColor /* Palette colors */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch color palette\n *\n * @param inputs - Color palette element\n *\n * @returns Color palette observable\n */\nexport function watchPalette(\n inputs: HTMLInputElement[]\n): Observable {\n const current = __md_get(\"__palette\") || {\n index: inputs.findIndex(input => matchMedia(\n input.getAttribute(\"data-md-color-media\")!\n ).matches)\n }\n\n /* Emit changes in color palette */\n return of(...inputs)\n .pipe(\n mergeMap(input => fromEvent(input, \"change\")\n .pipe(\n map(() => input)\n )\n ),\n startWith(inputs[Math.max(0, current.index)]),\n map(input => ({\n index: inputs.indexOf(input),\n color: {\n scheme: input.getAttribute(\"data-md-color-scheme\"),\n primary: input.getAttribute(\"data-md-color-primary\"),\n accent: input.getAttribute(\"data-md-color-accent\")\n }\n } as Palette)),\n shareReplay(1)\n )\n}\n\n/**\n * Mount color palette\n *\n * @param el - Color palette element\n *\n * @returns Color palette component observable\n */\nexport function mountPalette(\n el: HTMLElement\n): Observable> {\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe(palette => {\n document.body.setAttribute(\"data-md-color-switching\", \"\")\n\n /* Set color palette */\n for (const [key, value] of Object.entries(palette.color))\n document.body.setAttribute(`data-md-color-${key}`, value)\n\n /* Toggle visibility */\n for (let index = 0; index < inputs.length; index++) {\n const label = inputs[index].nextElementSibling\n if (label instanceof HTMLElement)\n label.hidden = palette.index !== index\n }\n\n /* Persist preference in local storage */\n __md_set(\"__palette\", palette)\n })\n\n /* Revert transition durations after color switch */\n push$.pipe(observeOn(asyncScheduler))\n .subscribe(() => {\n document.body.removeAttribute(\"data-md-color-switching\")\n })\n\n /* Create and return component */\n const inputs = getElements(\"input\", el)\n return watchPalette(inputs)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport ClipboardJS from \"clipboard\"\nimport {\n Observable,\n Subject,\n map,\n tap\n} from \"rxjs\"\n\nimport { translation } from \"~/_\"\nimport { getElement } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Setup options\n */\ninterface SetupOptions {\n alert$: Subject /* Alert subject */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Extract text to copy\n *\n * @param el - HTML element\n *\n * @returns Extracted text\n */\nfunction extract(el: HTMLElement): string {\n el.setAttribute(\"data-md-copying\", \"\")\n const text = el.innerText\n el.removeAttribute(\"data-md-copying\")\n return text\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up Clipboard.js integration\n *\n * @param options - Options\n */\nexport function setupClipboardJS(\n { alert$ }: SetupOptions\n): void {\n if (ClipboardJS.isSupported()) {\n new Observable(subscriber => {\n new ClipboardJS(\"[data-clipboard-target], [data-clipboard-text]\", {\n text: el => (\n el.getAttribute(\"data-clipboard-text\")! ||\n extract(getElement(\n el.getAttribute(\"data-clipboard-target\")!\n ))\n )\n })\n .on(\"success\", ev => subscriber.next(ev))\n })\n .pipe(\n tap(ev => {\n const trigger = ev.trigger as HTMLElement\n trigger.focus()\n }),\n map(() => translation(\"clipboard.copied\"))\n )\n .subscribe(alert$)\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n catchError,\n defaultIfEmpty,\n map,\n of,\n tap\n} from \"rxjs\"\n\nimport { configuration } from \"~/_\"\nimport { getElements, requestXML } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Sitemap, i.e. a list of URLs\n */\nexport type Sitemap = string[]\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Preprocess a list of URLs\n *\n * This function replaces the `site_url` in the sitemap with the actual base\n * URL, to allow instant loading to work in occasions like Netlify previews.\n *\n * @param urls - URLs\n *\n * @returns URL path parts\n */\nfunction preprocess(urls: Sitemap): Sitemap {\n if (urls.length < 2)\n return [\"\"]\n\n /* Take the first two URLs and remove everything after the last slash */\n const [root, next] = [...urls]\n .sort((a, b) => a.length - b.length)\n .map(url => url.replace(/[^/]+$/, \"\"))\n\n /* Compute common prefix */\n let index = 0\n if (root === next)\n index = root.length\n else\n while (root.charCodeAt(index) === next.charCodeAt(index))\n index++\n\n /* Remove common prefix and return in original order */\n return urls.map(url => url.replace(root.slice(0, index), \"\"))\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch the sitemap for the given base URL\n *\n * @param base - Base URL\n *\n * @returns Sitemap observable\n */\nexport function fetchSitemap(base?: URL): Observable {\n const cached = __md_get(\"__sitemap\", sessionStorage, base)\n if (cached) {\n return of(cached)\n } else {\n const config = configuration()\n return requestXML(new URL(\"sitemap.xml\", base || config.base))\n .pipe(\n map(sitemap => preprocess(getElements(\"loc\", sitemap)\n .map(node => node.textContent!)\n )),\n catchError(() => EMPTY), // @todo refactor instant loading\n defaultIfEmpty([]),\n tap(sitemap => __md_set(\"__sitemap\", sitemap, sessionStorage, base))\n )\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n NEVER,\n Observable,\n Subject,\n bufferCount,\n catchError,\n concatMap,\n debounceTime,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n filter,\n fromEvent,\n map,\n merge,\n of,\n sample,\n share,\n skip,\n skipUntil,\n switchMap\n} from \"rxjs\"\n\nimport { configuration, feature } from \"~/_\"\nimport {\n Viewport,\n ViewportOffset,\n getElements,\n getOptionalElement,\n request,\n setLocation,\n setLocationHash\n} from \"~/browser\"\nimport { getComponentElement } from \"~/components\"\nimport { h } from \"~/utilities\"\n\nimport { fetchSitemap } from \"../sitemap\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * History state\n */\nexport interface HistoryState {\n url: URL /* State URL */\n offset?: ViewportOffset /* State viewport offset */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Setup options\n */\ninterface SetupOptions {\n document$: Subject /* Document subject */\n location$: Subject /* Location subject */\n viewport$: Observable /* Viewport observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up instant loading\n *\n * When fetching, theoretically, we could use `responseType: \"document\"`, but\n * since all MkDocs links are relative, we need to make sure that the current\n * location matches the document we just loaded. Otherwise any relative links\n * in the document could use the old location.\n *\n * This is the reason why we need to synchronize history events and the process\n * of fetching the document for navigation changes (except `popstate` events):\n *\n * 1. Fetch document via `XMLHTTPRequest`\n * 2. Set new location via `history.pushState`\n * 3. Parse and emit fetched document\n *\n * For `popstate` events, we must not use `history.pushState`, or the forward\n * history will be irreversibly overwritten. In case the request fails, the\n * location change is dispatched regularly.\n *\n * @param options - Options\n */\nexport function setupInstantLoading(\n { document$, location$, viewport$ }: SetupOptions\n): void {\n const config = configuration()\n if (location.protocol === \"file:\")\n return\n\n /* Disable automatic scroll restoration */\n if (\"scrollRestoration\" in history) {\n history.scrollRestoration = \"manual\"\n\n /* Hack: ensure that reloads restore viewport offset */\n fromEvent(window, \"beforeunload\")\n .subscribe(() => {\n history.scrollRestoration = \"auto\"\n })\n }\n\n /* Hack: ensure absolute favicon link to omit 404s when switching */\n const favicon = getOptionalElement(\"link[rel=icon]\")\n if (typeof favicon !== \"undefined\")\n favicon.href = favicon.href\n\n /* Intercept internal navigation */\n const push$ = fetchSitemap()\n .pipe(\n map(paths => paths.map(path => `${new URL(path, config.base)}`)),\n switchMap(urls => fromEvent(document.body, \"click\")\n .pipe(\n filter(ev => !ev.metaKey && !ev.ctrlKey),\n switchMap(ev => {\n if (ev.target instanceof Element) {\n const el = ev.target.closest(\"a\")\n if (el && !el.target) {\n const url = new URL(el.href)\n\n /* Canonicalize URL */\n url.search = \"\"\n url.hash = \"\"\n\n /* Check if URL should be intercepted */\n if (\n url.pathname !== location.pathname &&\n urls.includes(url.toString())\n ) {\n ev.preventDefault()\n return of({\n url: new URL(el.href)\n })\n }\n }\n }\n return NEVER\n })\n )\n ),\n share()\n )\n\n /* Intercept history back and forward */\n const pop$ = fromEvent(window, \"popstate\")\n .pipe(\n filter(ev => ev.state !== null),\n map(ev => ({\n url: new URL(location.href),\n offset: ev.state\n })),\n share()\n )\n\n /* Emit location change */\n merge(push$, pop$)\n .pipe(\n distinctUntilChanged((a, b) => a.url.href === b.url.href),\n map(({ url }) => url)\n )\n .subscribe(location$)\n\n /* Fetch document via `XMLHTTPRequest` */\n const response$ = location$\n .pipe(\n distinctUntilKeyChanged(\"pathname\"),\n switchMap(url => request(url.href)\n .pipe(\n catchError(() => {\n setLocation(url)\n return NEVER\n })\n )\n ),\n share()\n )\n\n /* Set new location via `history.pushState` */\n push$\n .pipe(\n sample(response$)\n )\n .subscribe(({ url }) => {\n history.pushState({}, \"\", `${url}`)\n })\n\n /* Parse and emit fetched document */\n const dom = new DOMParser()\n response$\n .pipe(\n switchMap(res => res.text()),\n map(res => dom.parseFromString(res, \"text/html\"))\n )\n .subscribe(document$)\n\n /* Replace meta tags and components */\n document$\n .pipe(\n skip(1)\n )\n .subscribe(replacement => {\n for (const selector of [\n\n /* Meta tags */\n \"title\",\n \"link[rel=canonical]\",\n \"meta[name=author]\",\n \"meta[name=description]\",\n\n /* Components */\n \"[data-md-component=announce]\",\n \"[data-md-component=container]\",\n \"[data-md-component=header-topic]\",\n \"[data-md-component=outdated]\",\n \"[data-md-component=logo]\",\n \"[data-md-component=skip]\",\n ...feature(\"navigation.tabs.sticky\")\n ? [\"[data-md-component=tabs]\"]\n : []\n ]) {\n const source = getOptionalElement(selector)\n const target = getOptionalElement(selector, replacement)\n if (\n typeof source !== \"undefined\" &&\n typeof target !== \"undefined\"\n ) {\n source.replaceWith(target)\n }\n }\n })\n\n /* Re-evaluate scripts */\n document$\n .pipe(\n skip(1),\n map(() => getComponentElement(\"container\")),\n switchMap(el => getElements(\"script\", el)),\n concatMap(el => {\n const script = h(\"script\")\n if (el.src) {\n for (const name of el.getAttributeNames())\n script.setAttribute(name, el.getAttribute(name)!)\n el.replaceWith(script)\n\n /* Complete when script is loaded */\n return new Observable(observer => {\n script.onload = () => observer.complete()\n })\n\n /* Complete immediately */\n } else {\n script.textContent = el.textContent\n el.replaceWith(script)\n return EMPTY\n }\n })\n )\n .subscribe()\n\n /* Emit history state change */\n merge(push$, pop$)\n .pipe(\n sample(document$)\n )\n .subscribe(({ url, offset }) => {\n if (url.hash && !offset) {\n setLocationHash(url.hash)\n } else {\n window.scrollTo(0, offset?.y || 0)\n }\n })\n\n /* Debounce update of viewport offset */\n viewport$\n .pipe(\n skipUntil(push$),\n debounceTime(250),\n distinctUntilKeyChanged(\"offset\")\n )\n .subscribe(({ offset }) => {\n history.replaceState(offset, \"\")\n })\n\n /* Set viewport offset from history */\n merge(push$, pop$)\n .pipe(\n bufferCount(2, 1),\n filter(([a, b]) => a.url.pathname === b.url.pathname),\n map(([, state]) => state)\n )\n .subscribe(({ offset }) => {\n window.scrollTo(0, offset?.y || 0)\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport escapeHTML from \"escape-html\"\n\nimport { SearchIndexDocument } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search document\n */\nexport interface SearchDocument extends SearchIndexDocument {\n parent?: SearchIndexDocument /* Parent article */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search document mapping\n */\nexport type SearchDocumentMap = Map\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Create a search document mapping\n *\n * @param docs - Search index documents\n *\n * @returns Search document map\n */\nexport function setupSearchDocumentMap(\n docs: SearchIndexDocument[]\n): SearchDocumentMap {\n const documents = new Map()\n const parents = new Set()\n for (const doc of docs) {\n const [path, hash] = doc.location.split(\"#\")\n\n /* Extract location, title and tags */\n const location = doc.location\n const title = doc.title\n const tags = doc.tags\n\n /* Escape and cleanup text */\n const text = escapeHTML(doc.text)\n .replace(/\\s+(?=[,.:;!?])/g, \"\")\n .replace(/\\s+/g, \" \")\n\n /* Handle section */\n if (hash) {\n const parent = documents.get(path)!\n\n /* Ignore first section, override article */\n if (!parents.has(parent)) {\n parent.title = doc.title\n parent.text = text\n\n /* Remember that we processed the article */\n parents.add(parent)\n\n /* Add subsequent section */\n } else {\n documents.set(location, {\n location,\n title,\n text,\n parent\n })\n }\n\n /* Add article */\n } else {\n documents.set(location, {\n location,\n title,\n text,\n ...tags && { tags }\n })\n }\n }\n return documents\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport escapeHTML from \"escape-html\"\n\nimport { SearchIndexConfig } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search highlight function\n *\n * @param value - Value\n *\n * @returns Highlighted value\n */\nexport type SearchHighlightFn = (value: string) => string\n\n/**\n * Search highlight factory function\n *\n * @param query - Query value\n *\n * @returns Search highlight function\n */\nexport type SearchHighlightFactoryFn = (query: string) => SearchHighlightFn\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Create a search highlighter\n *\n * @param config - Search index configuration\n * @param escape - Whether to escape HTML\n *\n * @returns Search highlight factory function\n */\nexport function setupSearchHighlighter(\n config: SearchIndexConfig, escape: boolean\n): SearchHighlightFactoryFn {\n const separator = new RegExp(config.separator, \"img\")\n const highlight = (_: unknown, data: string, term: string) => {\n return `${data}${term}`\n }\n\n /* Return factory function */\n return (query: string) => {\n query = query\n .replace(/[\\s*+\\-:~^]+/g, \" \")\n .trim()\n\n /* Create search term match expression */\n const match = new RegExp(`(^|${config.separator})(${\n query\n .replace(/[|\\\\{}()[\\]^$+*?.-]/g, \"\\\\$&\")\n .replace(separator, \"|\")\n })`, \"img\")\n\n /* Highlight string value */\n return value => (\n escape\n ? escapeHTML(value)\n : value\n )\n .replace(match, highlight)\n .replace(/<\\/mark>(\\s+)]*>/img, \"$1\")\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search transformation function\n *\n * @param value - Query value\n *\n * @returns Transformed query value\n */\nexport type SearchTransformFn = (value: string) => string\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Default transformation function\n *\n * 1. Search for terms in quotation marks and prepend a `+` modifier to denote\n * that the resulting document must contain all terms, converting the query\n * to an `AND` query (as opposed to the default `OR` behavior). While users\n * may expect terms enclosed in quotation marks to map to span queries, i.e.\n * for which order is important, Lunr.js doesn't support them, so the best\n * we can do is to convert the terms to an `AND` query.\n *\n * 2. Replace control characters which are not located at the beginning of the\n * query or preceded by white space, or are not followed by a non-whitespace\n * character or are at the end of the query string. Furthermore, filter\n * unmatched quotation marks.\n *\n * 3. Trim excess whitespace from left and right.\n *\n * @param query - Query value\n *\n * @returns Transformed query value\n */\nexport function defaultTransform(query: string): string {\n return query\n .split(/\"([^\"]+)\"/g) /* => 1 */\n .map((terms, index) => index & 1\n ? terms.replace(/^\\b|^(?![^\\x00-\\x7F]|$)|\\s+/g, \" +\")\n : terms\n )\n .join(\"\")\n .replace(/\"|(?:^|\\s+)[*+\\-:^~]+(?=\\s+|$)/g, \"\") /* => 2 */\n .trim() /* => 3 */\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A RTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { SearchIndex, SearchResult } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search message type\n */\nexport const enum SearchMessageType {\n SETUP, /* Search index setup */\n READY, /* Search index ready */\n QUERY, /* Search query */\n RESULT /* Search results */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Message containing the data necessary to setup the search index\n */\nexport interface SearchSetupMessage {\n type: SearchMessageType.SETUP /* Message type */\n data: SearchIndex /* Message data */\n}\n\n/**\n * Message indicating the search index is ready\n */\nexport interface SearchReadyMessage {\n type: SearchMessageType.READY /* Message type */\n}\n\n/**\n * Message containing a search query\n */\nexport interface SearchQueryMessage {\n type: SearchMessageType.QUERY /* Message type */\n data: string /* Message data */\n}\n\n/**\n * Message containing results for a search query\n */\nexport interface SearchResultMessage {\n type: SearchMessageType.RESULT /* Message type */\n data: SearchResult /* Message data */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Message exchanged with the search worker\n */\nexport type SearchMessage =\n | SearchSetupMessage\n | SearchReadyMessage\n | SearchQueryMessage\n | SearchResultMessage\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Type guard for search setup messages\n *\n * @param message - Search worker message\n *\n * @returns Test result\n */\nexport function isSearchSetupMessage(\n message: SearchMessage\n): message is SearchSetupMessage {\n return message.type === SearchMessageType.SETUP\n}\n\n/**\n * Type guard for search ready messages\n *\n * @param message - Search worker message\n *\n * @returns Test result\n */\nexport function isSearchReadyMessage(\n message: SearchMessage\n): message is SearchReadyMessage {\n return message.type === SearchMessageType.READY\n}\n\n/**\n * Type guard for search query messages\n *\n * @param message - Search worker message\n *\n * @returns Test result\n */\nexport function isSearchQueryMessage(\n message: SearchMessage\n): message is SearchQueryMessage {\n return message.type === SearchMessageType.QUERY\n}\n\n/**\n * Type guard for search result messages\n *\n * @param message - Search worker message\n *\n * @returns Test result\n */\nexport function isSearchResultMessage(\n message: SearchMessage\n): message is SearchResultMessage {\n return message.type === SearchMessageType.RESULT\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A RTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n ObservableInput,\n Subject,\n from,\n map,\n share\n} from \"rxjs\"\n\nimport { configuration, feature, translation } from \"~/_\"\nimport { WorkerHandler, watchWorker } from \"~/browser\"\n\nimport { SearchIndex } from \"../../_\"\nimport {\n SearchOptions,\n SearchPipeline\n} from \"../../options\"\nimport {\n SearchMessage,\n SearchMessageType,\n SearchSetupMessage,\n isSearchResultMessage\n} from \"../message\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search worker\n */\nexport type SearchWorker = WorkerHandler\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up search index\n *\n * @param data - Search index\n *\n * @returns Search index\n */\nfunction setupSearchIndex({ config, docs }: SearchIndex): SearchIndex {\n\n /* Override default language with value from translation */\n if (config.lang.length === 1 && config.lang[0] === \"en\")\n config.lang = [\n translation(\"search.config.lang\")\n ]\n\n /* Override default separator with value from translation */\n if (config.separator === \"[\\\\s\\\\-]+\")\n config.separator = translation(\"search.config.separator\")\n\n /* Set pipeline from translation */\n const pipeline = translation(\"search.config.pipeline\")\n .split(/\\s*,\\s*/)\n .filter(Boolean) as SearchPipeline\n\n /* Determine search options */\n const options: SearchOptions = {\n pipeline,\n suggestions: feature(\"search.suggest\")\n }\n\n /* Return search index after defaulting */\n return { config, docs, options }\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up search worker\n *\n * This function creates a web worker to set up and query the search index,\n * which is done using Lunr.js. The index must be passed as an observable to\n * enable hacks like _localsearch_ via search index embedding as JSON.\n *\n * @param url - Worker URL\n * @param index - Search index observable input\n *\n * @returns Search worker\n */\nexport function setupSearchWorker(\n url: string, index: ObservableInput\n): SearchWorker {\n const config = configuration()\n const worker = new Worker(url)\n\n /* Create communication channels and resolve relative links */\n const tx$ = new Subject()\n const rx$ = watchWorker(worker, { tx$ })\n .pipe(\n map(message => {\n if (isSearchResultMessage(message)) {\n for (const result of message.data.items)\n for (const document of result)\n document.location = `${new URL(document.location, config.base)}`\n }\n return message\n }),\n share()\n )\n\n /* Set up search index */\n from(index)\n .pipe(\n map(data => ({\n type: SearchMessageType.SETUP,\n data: setupSearchIndex(data)\n } as SearchSetupMessage))\n )\n .subscribe(tx$.next.bind(tx$))\n\n /* Return search worker */\n return { tx$, rx$ }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Subject,\n catchError,\n combineLatest,\n filter,\n fromEvent,\n map,\n of,\n switchMap,\n withLatestFrom\n} from \"rxjs\"\n\nimport { configuration } from \"~/_\"\nimport {\n getElement,\n getLocation,\n requestJSON,\n setLocation\n} from \"~/browser\"\nimport { getComponentElements } from \"~/components\"\nimport {\n Version,\n renderVersionSelector\n} from \"~/templates\"\n\nimport { fetchSitemap } from \"../sitemap\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Setup options\n */\ninterface SetupOptions {\n document$: Subject /* Document subject */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up version selector\n *\n * @param options - Options\n */\nexport function setupVersionSelector(\n { document$ }: SetupOptions\n): void {\n const config = configuration()\n const versions$ = requestJSON(\n new URL(\"../versions.json\", config.base)\n )\n .pipe(\n catchError(() => EMPTY) // @todo refactor instant loading\n )\n\n /* Determine current version */\n const current$ = versions$\n .pipe(\n map(versions => {\n const [, current] = config.base.match(/([^/]+)\\/?$/)!\n return versions.find(({ version, aliases }) => (\n version === current || aliases.includes(current)\n )) || versions[0]\n })\n )\n\n /* Intercept inter-version navigation */\n versions$\n .pipe(\n map(versions => new Map(versions.map(version => [\n `${new URL(`../${version.version}/`, config.base)}`,\n version\n ]))),\n switchMap(urls => fromEvent(document.body, \"click\")\n .pipe(\n filter(ev => !ev.metaKey && !ev.ctrlKey),\n withLatestFrom(current$),\n switchMap(([ev, current]) => {\n if (ev.target instanceof Element) {\n const el = ev.target.closest(\"a\")\n if (el && !el.target && urls.has(el.href)) {\n const url = el.href\n // This is a temporary hack to detect if a version inside the\n // version selector or on another part of the site was clicked.\n // If we're inside the version selector, we definitely want to\n // find the same page, as we might have different deployments\n // due to aliases. However, if we're outside the version\n // selector, we must abort here, because we might otherwise\n // interfere with instant loading. We need to refactor this\n // at some point together with instant loading.\n //\n // See https://github.com/squidfunk/mkdocs-material/issues/4012\n if (!ev.target.closest(\".md-version\")) {\n const version = urls.get(url)!\n if (version === current)\n return EMPTY\n }\n ev.preventDefault()\n return of(url)\n }\n }\n return EMPTY\n }),\n switchMap(url => {\n const { version } = urls.get(url)!\n return fetchSitemap(new URL(url))\n .pipe(\n map(sitemap => {\n const location = getLocation()\n const path = location.href.replace(config.base, \"\")\n return sitemap.includes(path)\n ? new URL(`../${version}/${path}`, config.base)\n : new URL(url)\n })\n )\n })\n )\n )\n )\n .subscribe(url => setLocation(url))\n\n /* Render version selector and warning */\n combineLatest([versions$, current$])\n .subscribe(([versions, current]) => {\n const topic = getElement(\".md-header__topic\")\n topic.appendChild(renderVersionSelector(versions, current))\n })\n\n /* Integrate outdated version banner with instant loading */\n document$.pipe(switchMap(() => current$))\n .subscribe(current => {\n\n /* Check if version state was already determined */\n let outdated = __md_get(\"__outdated\", sessionStorage)\n if (outdated === null) {\n const latest = config.version?.default || \"latest\"\n outdated = !current.aliases.includes(latest)\n\n /* Persist version state in session storage */\n __md_set(\"__outdated\", outdated, sessionStorage)\n }\n\n /* Unhide outdated version banner */\n if (outdated)\n for (const warning of getComponentElements(\"outdated\"))\n warning.hidden = false\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n combineLatest,\n delay,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n filter,\n finalize,\n fromEvent,\n map,\n merge,\n share,\n shareReplay,\n startWith,\n take,\n takeLast,\n takeUntil,\n tap\n} from \"rxjs\"\n\nimport { translation } from \"~/_\"\nimport {\n getLocation,\n setToggle,\n watchElementFocus,\n watchToggle\n} from \"~/browser\"\nimport {\n SearchMessageType,\n SearchQueryMessage,\n SearchWorker,\n defaultTransform,\n isSearchReadyMessage\n} from \"~/integrations\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search query\n */\nexport interface SearchQuery {\n value: string /* Query value */\n focus: boolean /* Query focus */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch search query\n *\n * Note that the focus event which triggers re-reading the current query value\n * is delayed by `1ms` so the input's empty state is allowed to propagate.\n *\n * @param el - Search query element\n * @param worker - Search worker\n *\n * @returns Search query observable\n */\nexport function watchSearchQuery(\n el: HTMLInputElement, { rx$ }: SearchWorker\n): Observable {\n const fn = __search?.transform || defaultTransform\n\n /* Immediately show search dialog */\n const { searchParams } = getLocation()\n if (searchParams.has(\"q\"))\n setToggle(\"search\", true)\n\n /* Intercept query parameter (deep link) */\n const param$ = rx$\n .pipe(\n filter(isSearchReadyMessage),\n take(1),\n map(() => searchParams.get(\"q\") || \"\")\n )\n\n /* Remove query parameter when search is closed */\n watchToggle(\"search\")\n .pipe(\n filter(active => !active),\n take(1)\n )\n .subscribe(() => {\n const url = new URL(location.href)\n url.searchParams.delete(\"q\")\n history.replaceState({}, \"\", `${url}`)\n })\n\n /* Set query from parameter */\n param$.subscribe(value => { // TODO: not ideal - find a better way\n if (value) {\n el.value = value\n el.focus()\n }\n })\n\n /* Intercept focus and input events */\n const focus$ = watchElementFocus(el)\n const value$ = merge(\n fromEvent(el, \"keyup\"),\n fromEvent(el, \"focus\").pipe(delay(1)),\n param$\n )\n .pipe(\n map(() => fn(el.value)),\n startWith(\"\"),\n distinctUntilChanged(),\n )\n\n /* Combine into single observable */\n return combineLatest([value$, focus$])\n .pipe(\n map(([value, focus]) => ({ value, focus })),\n shareReplay(1)\n )\n}\n\n/**\n * Mount search query\n *\n * @param el - Search query element\n * @param worker - Search worker\n *\n * @returns Search query component observable\n */\nexport function mountSearchQuery(\n el: HTMLInputElement, { tx$, rx$ }: SearchWorker\n): Observable> {\n const push$ = new Subject()\n const done$ = push$.pipe(takeLast(1))\n\n /* Handle value changes */\n push$\n .pipe(\n distinctUntilKeyChanged(\"value\"),\n map(({ value }): SearchQueryMessage => ({\n type: SearchMessageType.QUERY,\n data: value\n }))\n )\n .subscribe(tx$.next.bind(tx$))\n\n /* Handle focus changes */\n push$\n .pipe(\n distinctUntilKeyChanged(\"focus\")\n )\n .subscribe(({ focus }) => {\n if (focus) {\n setToggle(\"search\", focus)\n el.placeholder = \"\"\n } else {\n el.placeholder = translation(\"search.placeholder\")\n }\n })\n\n /* Handle reset */\n fromEvent(el.form!, \"reset\")\n .pipe(\n takeUntil(done$)\n )\n .subscribe(() => el.focus())\n\n /* Create and return component */\n return watchSearchQuery(el, { tx$, rx$ })\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state })),\n share()\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n bufferCount,\n filter,\n finalize,\n map,\n merge,\n of,\n skipUntil,\n switchMap,\n take,\n tap,\n withLatestFrom,\n zipWith\n} from \"rxjs\"\n\nimport { translation } from \"~/_\"\nimport {\n getElement,\n watchElementBoundary\n} from \"~/browser\"\nimport {\n SearchResult,\n SearchWorker,\n isSearchReadyMessage,\n isSearchResultMessage\n} from \"~/integrations\"\nimport { renderSearchResultItem } from \"~/templates\"\nimport { round } from \"~/utilities\"\n\nimport { Component } from \"../../_\"\nimport { SearchQuery } from \"../query\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n query$: Observable /* Search query observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search result list\n *\n * This function performs a lazy rendering of the search results, depending on\n * the vertical offset of the search result container.\n *\n * @param el - Search result list element\n * @param worker - Search worker\n * @param options - Options\n *\n * @returns Search result list component observable\n */\nexport function mountSearchResult(\n el: HTMLElement, { rx$ }: SearchWorker, { query$ }: MountOptions\n): Observable> {\n const push$ = new Subject()\n const boundary$ = watchElementBoundary(el.parentElement!)\n .pipe(\n filter(Boolean)\n )\n\n /* Retrieve nested components */\n const meta = getElement(\":scope > :first-child\", el)\n const list = getElement(\":scope > :last-child\", el)\n\n /* Wait until search is ready */\n const ready$ = rx$\n .pipe(\n filter(isSearchReadyMessage),\n take(1)\n )\n\n /* Update search result metadata */\n push$\n .pipe(\n withLatestFrom(query$),\n skipUntil(ready$)\n )\n .subscribe(([{ items }, { value }]) => {\n if (value) {\n switch (items.length) {\n\n /* No results */\n case 0:\n meta.textContent = translation(\"search.result.none\")\n break\n\n /* One result */\n case 1:\n meta.textContent = translation(\"search.result.one\")\n break\n\n /* Multiple result */\n default:\n meta.textContent = translation(\n \"search.result.other\",\n round(items.length)\n )\n }\n } else {\n meta.textContent = translation(\"search.result.placeholder\")\n }\n })\n\n /* Update search result list */\n push$\n .pipe(\n tap(() => list.innerHTML = \"\"),\n switchMap(({ items }) => merge(\n of(...items.slice(0, 10)),\n of(...items.slice(10))\n .pipe(\n bufferCount(4),\n zipWith(boundary$),\n switchMap(([chunk]) => chunk)\n )\n ))\n )\n .subscribe(result => list.appendChild(\n renderSearchResultItem(result)\n ))\n\n /* Filter search result message */\n const result$ = rx$\n .pipe(\n filter(isSearchResultMessage),\n map(({ data }) => data)\n )\n\n /* Create and return component */\n return result$\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n finalize,\n fromEvent,\n map,\n tap\n} from \"rxjs\"\n\nimport { getLocation } from \"~/browser\"\n\nimport { Component } from \"../../_\"\nimport { SearchQuery } from \"../query\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search sharing\n */\nexport interface SearchShare {\n url: URL /* Deep link for sharing */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n query$: Observable /* Search query observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n query$: Observable /* Search query observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search sharing\n *\n * @param _el - Search sharing element\n * @param options - Options\n *\n * @returns Search sharing observable\n */\nexport function watchSearchShare(\n _el: HTMLElement, { query$ }: WatchOptions\n): Observable {\n return query$\n .pipe(\n map(({ value }) => {\n const url = getLocation()\n url.hash = \"\"\n url.searchParams.delete(\"h\")\n url.searchParams.set(\"q\", value)\n return { url }\n })\n )\n}\n\n/**\n * Mount search sharing\n *\n * @param el - Search sharing element\n * @param options - Options\n *\n * @returns Search sharing component observable\n */\nexport function mountSearchShare(\n el: HTMLAnchorElement, options: MountOptions\n): Observable> {\n const push$ = new Subject()\n push$.subscribe(({ url }) => {\n el.setAttribute(\"data-clipboard-text\", el.href)\n el.href = `${url}`\n })\n\n /* Prevent following of link */\n fromEvent(el, \"click\")\n .subscribe(ev => ev.preventDefault())\n\n /* Create and return component */\n return watchSearchShare(el, options)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n asyncScheduler,\n combineLatestWith,\n distinctUntilChanged,\n filter,\n finalize,\n fromEvent,\n map,\n merge,\n observeOn,\n tap\n} from \"rxjs\"\n\nimport { Keyboard } from \"~/browser\"\nimport {\n SearchResult,\n SearchWorker,\n isSearchResultMessage\n} from \"~/integrations\"\n\nimport { Component, getComponentElement } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search suggestions\n */\nexport interface SearchSuggest {}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n keyboard$: Observable /* Keyboard observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search suggestions\n *\n * This function will perform a lazy rendering of the search results, depending\n * on the vertical offset of the search result container.\n *\n * @param el - Search result list element\n * @param worker - Search worker\n * @param options - Options\n *\n * @returns Search result list component observable\n */\nexport function mountSearchSuggest(\n el: HTMLElement, { rx$ }: SearchWorker, { keyboard$ }: MountOptions\n): Observable> {\n const push$ = new Subject()\n\n /* Retrieve query component and track all changes */\n const query = getComponentElement(\"search-query\")\n const query$ = merge(\n fromEvent(query, \"keydown\"),\n fromEvent(query, \"focus\")\n )\n .pipe(\n observeOn(asyncScheduler),\n map(() => query.value),\n distinctUntilChanged(),\n )\n\n /* Update search suggestions */\n push$\n .pipe(\n combineLatestWith(query$),\n map(([{ suggestions }, value]) => {\n const words = value.split(/([\\s-]+)/)\n if (suggestions?.length && words[words.length - 1]) {\n const last = suggestions[suggestions.length - 1]\n if (last.startsWith(words[words.length - 1]))\n words[words.length - 1] = last\n } else {\n words.length = 0\n }\n return words\n })\n )\n .subscribe(words => el.innerHTML = words\n .join(\"\")\n .replace(/\\s/g, \" \")\n )\n\n /* Set up search keyboard handlers */\n keyboard$\n .pipe(\n filter(({ mode }) => mode === \"search\")\n )\n .subscribe(key => {\n switch (key.type) {\n\n /* Right arrow: accept current suggestion */\n case \"ArrowRight\":\n if (\n el.innerText.length &&\n query.selectionStart === query.value.length\n )\n query.value = el.innerText\n break\n }\n })\n\n /* Filter search result message */\n const result$ = rx$\n .pipe(\n filter(isSearchResultMessage),\n map(({ data }) => data)\n )\n\n /* Create and return component */\n return result$\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(() => ({ ref: el }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n NEVER,\n Observable,\n ObservableInput,\n filter,\n merge,\n mergeWith,\n sample,\n take\n} from \"rxjs\"\n\nimport { configuration } from \"~/_\"\nimport {\n Keyboard,\n getActiveElement,\n getElements,\n setToggle\n} from \"~/browser\"\nimport {\n SearchIndex,\n SearchResult,\n isSearchQueryMessage,\n isSearchReadyMessage,\n setupSearchWorker\n} from \"~/integrations\"\n\nimport {\n Component,\n getComponentElement,\n getComponentElements\n} from \"../../_\"\nimport {\n SearchQuery,\n mountSearchQuery\n} from \"../query\"\nimport { mountSearchResult } from \"../result\"\nimport {\n SearchShare,\n mountSearchShare\n} from \"../share\"\nimport {\n SearchSuggest,\n mountSearchSuggest\n} from \"../suggest\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search\n */\nexport type Search =\n | SearchQuery\n | SearchResult\n | SearchShare\n | SearchSuggest\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n index$: ObservableInput /* Search index observable */\n keyboard$: Observable /* Keyboard observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search\n *\n * This function sets up the search functionality, including the underlying\n * web worker and all keyboard bindings.\n *\n * @param el - Search element\n * @param options - Options\n *\n * @returns Search component observable\n */\nexport function mountSearch(\n el: HTMLElement, { index$, keyboard$ }: MountOptions\n): Observable> {\n const config = configuration()\n try {\n const url = __search?.worker || config.search\n const worker = setupSearchWorker(url, index$)\n\n /* Retrieve query and result components */\n const query = getComponentElement(\"search-query\", el)\n const result = getComponentElement(\"search-result\", el)\n\n /* Re-emit query when search is ready */\n const { tx$, rx$ } = worker\n tx$\n .pipe(\n filter(isSearchQueryMessage),\n sample(rx$.pipe(filter(isSearchReadyMessage))),\n take(1)\n )\n .subscribe(tx$.next.bind(tx$))\n\n /* Set up search keyboard handlers */\n keyboard$\n .pipe(\n filter(({ mode }) => mode === \"search\")\n )\n .subscribe(key => {\n const active = getActiveElement()\n switch (key.type) {\n\n /* Enter: go to first (best) result */\n case \"Enter\":\n if (active === query) {\n const anchors = new Map()\n for (const anchor of getElements(\n \":first-child [href]\", result\n )) {\n const article = anchor.firstElementChild!\n anchors.set(anchor, parseFloat(\n article.getAttribute(\"data-md-score\")!\n ))\n }\n\n /* Go to result with highest score, if any */\n if (anchors.size) {\n const [[best]] = [...anchors].sort(([, a], [, b]) => b - a)\n best.click()\n }\n\n /* Otherwise omit form submission */\n key.claim()\n }\n break\n\n /* Escape or Tab: close search */\n case \"Escape\":\n case \"Tab\":\n setToggle(\"search\", false)\n query.blur()\n break\n\n /* Vertical arrows: select previous or next search result */\n case \"ArrowUp\":\n case \"ArrowDown\":\n if (typeof active === \"undefined\") {\n query.focus()\n } else {\n const els = [query, ...getElements(\n \":not(details) > [href], summary, details[open] [href]\",\n result\n )]\n const i = Math.max(0, (\n Math.max(0, els.indexOf(active)) + els.length + (\n key.type === \"ArrowUp\" ? -1 : +1\n )\n ) % els.length)\n els[i].focus()\n }\n\n /* Prevent scrolling of page */\n key.claim()\n break\n\n /* All other keys: hand to search query */\n default:\n if (query !== getActiveElement())\n query.focus()\n }\n })\n\n /* Set up global keyboard handlers */\n keyboard$\n .pipe(\n filter(({ mode }) => mode === \"global\"),\n )\n .subscribe(key => {\n switch (key.type) {\n\n /* Open search and select query */\n case \"f\":\n case \"s\":\n case \"/\":\n query.focus()\n query.select()\n\n /* Prevent scrolling of page */\n key.claim()\n break\n }\n })\n\n /* Create and return component */\n const query$ = mountSearchQuery(query, worker)\n const result$ = mountSearchResult(result, worker, { query$ })\n return merge(query$, result$)\n .pipe(\n mergeWith(\n\n /* Search sharing */\n ...getComponentElements(\"search-share\", el)\n .map(child => mountSearchShare(child, { query$ })),\n\n /* Search suggestions */\n ...getComponentElements(\"search-suggest\", el)\n .map(child => mountSearchSuggest(child, worker, { keyboard$ }))\n )\n )\n\n /* Gracefully handle broken search */\n } catch (err) {\n el.hidden = true\n return NEVER\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n ObservableInput,\n combineLatest,\n filter,\n map,\n startWith\n} from \"rxjs\"\n\nimport { getLocation } from \"~/browser\"\nimport {\n SearchIndex,\n setupSearchHighlighter\n} from \"~/integrations\"\nimport { h } from \"~/utilities\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search highlighting\n */\nexport interface SearchHighlight {\n nodes: Map /* Map of replacements */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n index$: ObservableInput /* Search index observable */\n location$: Observable /* Location observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search highlighting\n *\n * @param el - Content element\n * @param options - Options\n *\n * @returns Search highlighting component observable\n */\nexport function mountSearchHiglight(\n el: HTMLElement, { index$, location$ }: MountOptions\n): Observable> {\n return combineLatest([\n index$,\n location$\n .pipe(\n startWith(getLocation()),\n filter(url => !!url.searchParams.get(\"h\"))\n )\n ])\n .pipe(\n map(([index, url]) => setupSearchHighlighter(index.config, true)(\n url.searchParams.get(\"h\")!\n )),\n map(fn => {\n const nodes = new Map()\n\n /* Traverse text nodes and collect matches */\n const it = document.createNodeIterator(el, NodeFilter.SHOW_TEXT)\n for (let node = it.nextNode(); node; node = it.nextNode()) {\n if (node.parentElement?.offsetHeight) {\n const original = node.textContent!\n const replaced = fn(original)\n if (replaced.length > original.length)\n nodes.set(node as ChildNode, replaced)\n }\n }\n\n /* Replace original nodes with matches */\n for (const [node, text] of nodes) {\n const { childNodes } = h(\"span\", null, text)\n node.replaceWith(...Array.from(childNodes))\n }\n\n /* Return component */\n return { ref: el, nodes }\n })\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n animationFrameScheduler,\n auditTime,\n combineLatest,\n defer,\n distinctUntilChanged,\n finalize,\n map,\n tap,\n withLatestFrom\n} from \"rxjs\"\n\nimport {\n Viewport,\n getElement,\n getElementOffset\n} from \"~/browser\"\n\nimport { Component } from \"../_\"\nimport { Header } from \"../header\"\nimport { Main } from \"../main\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Sidebar\n */\nexport interface Sidebar {\n height: number /* Sidebar height */\n locked: boolean /* Sidebar is locked */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n main$: Observable
    /* Main area observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n main$: Observable
    /* Main area observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch sidebar\n *\n * This function returns an observable that computes the visual parameters of\n * the sidebar which depends on the vertical viewport offset, as well as the\n * height of the main area. When the page is scrolled beyond the header, the\n * sidebar is locked and fills the remaining space.\n *\n * @param el - Sidebar element\n * @param options - Options\n *\n * @returns Sidebar observable\n */\nexport function watchSidebar(\n el: HTMLElement, { viewport$, main$ }: WatchOptions\n): Observable {\n const parent = el.parentElement!\n const adjust =\n parent.offsetTop -\n parent.parentElement!.offsetTop\n\n /* Compute the sidebar's available height and if it should be locked */\n return combineLatest([main$, viewport$])\n .pipe(\n map(([{ offset, height }, { offset: { y } }]) => {\n height = height\n + Math.min(adjust, Math.max(0, y - offset))\n - adjust\n return {\n height,\n locked: y >= offset + adjust\n }\n }),\n distinctUntilChanged((a, b) => (\n a.height === b.height &&\n a.locked === b.locked\n ))\n )\n}\n\n/**\n * Mount sidebar\n *\n * This function doesn't set the height of the actual sidebar, but of its first\n * child \u2013 the `.md-sidebar__scrollwrap` element in order to mitigiate jittery\n * sidebars when the footer is scrolled into view. At some point we switched\n * from `absolute` / `fixed` positioning to `sticky` positioning, significantly\n * reducing jitter in some browsers (respectively Firefox and Safari) when\n * scrolling from the top. However, top-aligned sticky positioning means that\n * the sidebar snaps to the bottom when the end of the container is reached.\n * This is what leads to the mentioned jitter, as the sidebar's height may be\n * updated too slowly.\n *\n * This behaviour can be mitigiated by setting the height of the sidebar to `0`\n * while preserving the padding, and the height on its first element.\n *\n * @param el - Sidebar element\n * @param options - Options\n *\n * @returns Sidebar component observable\n */\nexport function mountSidebar(\n el: HTMLElement, { header$, ...options }: MountOptions\n): Observable> {\n const inner = getElement(\".md-sidebar__scrollwrap\", el)\n const { y } = getElementOffset(inner)\n return defer(() => {\n const push$ = new Subject()\n push$\n .pipe(\n auditTime(0, animationFrameScheduler),\n withLatestFrom(header$)\n )\n .subscribe({\n\n /* Handle emission */\n next([{ height }, { height: offset }]) {\n inner.style.height = `${height - 2 * y}px`\n el.style.top = `${offset}px`\n },\n\n /* Handle complete */\n complete() {\n inner.style.height = \"\"\n el.style.top = \"\"\n }\n })\n\n /* Create and return component */\n return watchSidebar(el, options)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Repo, User } from \"github-types\"\nimport {\n EMPTY,\n Observable,\n catchError,\n defaultIfEmpty,\n map,\n zip\n} from \"rxjs\"\n\nimport { requestJSON } from \"~/browser\"\n\nimport { SourceFacts } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * GitHub release (partial)\n */\ninterface Release {\n tag_name: string /* Tag name */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch GitHub repository facts\n *\n * @param user - GitHub user or organization\n * @param repo - GitHub repository\n *\n * @returns Repository facts observable\n */\nexport function fetchSourceFactsFromGitHub(\n user: string, repo?: string\n): Observable {\n if (typeof repo !== \"undefined\") {\n const url = `https://api.github.com/repos/${user}/${repo}`\n return zip(\n\n /* Fetch version */\n requestJSON(`${url}/releases/latest`)\n .pipe(\n catchError(() => EMPTY), // @todo refactor instant loading\n map(release => ({\n version: release.tag_name\n })),\n defaultIfEmpty({})\n ),\n\n /* Fetch stars and forks */\n requestJSON(url)\n .pipe(\n catchError(() => EMPTY), // @todo refactor instant loading\n map(info => ({\n stars: info.stargazers_count,\n forks: info.forks_count\n })),\n defaultIfEmpty({})\n )\n )\n .pipe(\n map(([release, info]) => ({ ...release, ...info }))\n )\n\n /* User or organization */\n } else {\n const url = `https://api.github.com/users/${user}`\n return requestJSON(url)\n .pipe(\n map(info => ({\n repositories: info.public_repos\n })),\n defaultIfEmpty({})\n )\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { ProjectSchema } from \"gitlab\"\nimport {\n EMPTY,\n Observable,\n catchError,\n defaultIfEmpty,\n map\n} from \"rxjs\"\n\nimport { requestJSON } from \"~/browser\"\n\nimport { SourceFacts } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch GitLab repository facts\n *\n * @param base - GitLab base\n * @param project - GitLab project\n *\n * @returns Repository facts observable\n */\nexport function fetchSourceFactsFromGitLab(\n base: string, project: string\n): Observable {\n const url = `https://${base}/api/v4/projects/${encodeURIComponent(project)}`\n return requestJSON(url)\n .pipe(\n catchError(() => EMPTY), // @todo refactor instant loading\n map(({ star_count, forks_count }) => ({\n stars: star_count,\n forks: forks_count\n })),\n defaultIfEmpty({})\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { EMPTY, Observable } from \"rxjs\"\n\nimport { fetchSourceFactsFromGitHub } from \"../github\"\nimport { fetchSourceFactsFromGitLab } from \"../gitlab\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Repository facts for repositories\n */\nexport interface RepositoryFacts {\n stars?: number /* Number of stars */\n forks?: number /* Number of forks */\n version?: string /* Latest version */\n}\n\n/**\n * Repository facts for organizations\n */\nexport interface OrganizationFacts {\n repositories?: number /* Number of repositories */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Repository facts\n */\nexport type SourceFacts =\n | RepositoryFacts\n | OrganizationFacts\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch repository facts\n *\n * @param url - Repository URL\n *\n * @returns Repository facts observable\n */\nexport function fetchSourceFacts(\n url: string\n): Observable {\n const [type] = url.match(/(git(?:hub|lab))/i) || []\n switch (type.toLowerCase()) {\n\n /* GitHub repository */\n case \"github\":\n const [, user, repo] = url.match(/^.+github\\.com\\/([^/]+)\\/?([^/]+)?/i)!\n return fetchSourceFactsFromGitHub(user, repo)\n\n /* GitLab repository */\n case \"gitlab\":\n const [, base, slug] = url.match(/^.+?([^/]*gitlab[^/]+)\\/(.+?)\\/?$/i)!\n return fetchSourceFactsFromGitLab(base, slug)\n\n /* Everything else */\n default:\n return EMPTY\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n Subject,\n catchError,\n defer,\n filter,\n finalize,\n map,\n of,\n shareReplay,\n tap\n} from \"rxjs\"\n\nimport { getElement } from \"~/browser\"\nimport { renderSourceFacts } from \"~/templates\"\n\nimport { Component } from \"../../_\"\nimport {\n SourceFacts,\n fetchSourceFacts\n} from \"../facts\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Repository information\n */\nexport interface Source {\n facts: SourceFacts /* Repository facts */\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Repository information observable\n */\nlet fetch$: Observable\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch repository information\n *\n * This function tries to read the repository facts from session storage, and\n * if unsuccessful, fetches them from the underlying provider.\n *\n * @param el - Repository information element\n *\n * @returns Repository information observable\n */\nexport function watchSource(\n el: HTMLAnchorElement\n): Observable {\n return fetch$ ||= defer(() => {\n const cached = __md_get(\"__source\", sessionStorage)\n if (cached)\n return of(cached)\n else\n return fetchSourceFacts(el.href)\n .pipe(\n tap(facts => __md_set(\"__source\", facts, sessionStorage))\n )\n })\n .pipe(\n catchError(() => EMPTY),\n filter(facts => Object.keys(facts).length > 0),\n map(facts => ({ facts })),\n shareReplay(1)\n )\n}\n\n/**\n * Mount repository information\n *\n * @param el - Repository information element\n *\n * @returns Repository information component observable\n */\nexport function mountSource(\n el: HTMLAnchorElement\n): Observable> {\n const inner = getElement(\":scope > :last-child\", el)\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe(({ facts }) => {\n inner.appendChild(renderSourceFacts(facts))\n inner.classList.add(\"md-source__repository--active\")\n })\n\n /* Create and return component */\n return watchSource(el)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n defer,\n distinctUntilKeyChanged,\n finalize,\n map,\n of,\n switchMap,\n tap\n} from \"rxjs\"\n\nimport { feature } from \"~/_\"\nimport {\n Viewport,\n watchElementSize,\n watchViewportAt\n} from \"~/browser\"\n\nimport { Component } from \"../_\"\nimport { Header } from \"../header\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Navigation tabs\n */\nexport interface Tabs {\n hidden: boolean /* Navigation tabs are hidden */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch navigation tabs\n *\n * @param el - Navigation tabs element\n * @param options - Options\n *\n * @returns Navigation tabs observable\n */\nexport function watchTabs(\n el: HTMLElement, { viewport$, header$ }: WatchOptions\n): Observable {\n return watchElementSize(document.body)\n .pipe(\n switchMap(() => watchViewportAt(el, { header$, viewport$ })),\n map(({ offset: { y } }) => {\n return {\n hidden: y >= 10\n }\n }),\n distinctUntilKeyChanged(\"hidden\")\n )\n}\n\n/**\n * Mount navigation tabs\n *\n * This function hides the navigation tabs when scrolling past the threshold\n * and makes them reappear in a nice CSS animation when scrolling back up.\n *\n * @param el - Navigation tabs element\n * @param options - Options\n *\n * @returns Navigation tabs component observable\n */\nexport function mountTabs(\n el: HTMLElement, options: MountOptions\n): Observable> {\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe({\n\n /* Handle emission */\n next({ hidden }) {\n el.hidden = hidden\n },\n\n /* Handle complete */\n complete() {\n el.hidden = false\n }\n })\n\n /* Create and return component */\n return (\n feature(\"navigation.tabs.sticky\")\n ? of({ hidden: false })\n : watchTabs(el, options)\n )\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n bufferCount,\n combineLatestWith,\n debounceTime,\n defer,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n finalize,\n map,\n of,\n repeat,\n scan,\n share,\n skip,\n startWith,\n switchMap,\n takeLast,\n takeUntil,\n tap,\n withLatestFrom\n} from \"rxjs\"\n\nimport { feature } from \"~/_\"\nimport {\n Viewport,\n getElement,\n getElements,\n getLocation,\n getOptionalElement,\n watchElementSize\n} from \"~/browser\"\n\nimport {\n Component,\n getComponentElement\n} from \"../_\"\nimport { Header } from \"../header\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Table of contents\n */\nexport interface TableOfContents {\n prev: HTMLAnchorElement[][] /* Anchors (previous) */\n next: HTMLAnchorElement[][] /* Anchors (next) */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n target$: Observable /* Location target observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch table of contents\n *\n * This is effectively a scroll spy implementation which will account for the\n * fixed header and automatically re-calculate anchor offsets when the viewport\n * is resized. The returned observable will only emit if the table of contents\n * needs to be repainted.\n *\n * This implementation tracks an anchor element's entire path starting from its\n * level up to the top-most anchor element, e.g. `[h3, h2, h1]`. Although the\n * Material theme currently doesn't make use of this information, it enables\n * the styling of the entire hierarchy through customization.\n *\n * Note that the current anchor is the last item of the `prev` anchor list.\n *\n * @param el - Table of contents element\n * @param options - Options\n *\n * @returns Table of contents observable\n */\nexport function watchTableOfContents(\n el: HTMLElement, { viewport$, header$ }: WatchOptions\n): Observable {\n const table = new Map()\n\n /* Compute anchor-to-target mapping */\n const anchors = getElements(\"[href^=\\\\#]\", el)\n for (const anchor of anchors) {\n const id = decodeURIComponent(anchor.hash.substring(1))\n const target = getOptionalElement(`[id=\"${id}\"]`)\n if (typeof target !== \"undefined\")\n table.set(anchor, target)\n }\n\n /* Compute necessary adjustment for header */\n const adjust$ = header$\n .pipe(\n distinctUntilKeyChanged(\"height\"),\n map(({ height }) => {\n const main = getComponentElement(\"main\")\n const grid = getElement(\":scope > :first-child\", main)\n return height + 0.8 * (\n grid.offsetTop -\n main.offsetTop\n )\n }),\n share()\n )\n\n /* Compute partition of previous and next anchors */\n const partition$ = watchElementSize(document.body)\n .pipe(\n distinctUntilKeyChanged(\"height\"),\n\n /* Build index to map anchor paths to vertical offsets */\n switchMap(body => defer(() => {\n let path: HTMLAnchorElement[] = []\n return of([...table].reduce((index, [anchor, target]) => {\n while (path.length) {\n const last = table.get(path[path.length - 1])!\n if (last.tagName >= target.tagName) {\n path.pop()\n } else {\n break\n }\n }\n\n /* If the current anchor is hidden, continue with its parent */\n let offset = target.offsetTop\n while (!offset && target.parentElement) {\n target = target.parentElement\n offset = target.offsetTop\n }\n\n /* Map reversed anchor path to vertical offset */\n return index.set(\n [...path = [...path, anchor]].reverse(),\n offset\n )\n }, new Map()))\n })\n .pipe(\n\n /* Sort index by vertical offset (see https://bit.ly/30z6QSO) */\n map(index => new Map([...index].sort(([, a], [, b]) => a - b))),\n combineLatestWith(adjust$),\n\n /* Re-compute partition when viewport offset changes */\n switchMap(([index, adjust]) => viewport$\n .pipe(\n scan(([prev, next], { offset: { y }, size }) => {\n const last = y + size.height >= Math.floor(body.height)\n\n /* Look forward */\n while (next.length) {\n const [, offset] = next[0]\n if (offset - adjust < y || last) {\n prev = [...prev, next.shift()!]\n } else {\n break\n }\n }\n\n /* Look backward */\n while (prev.length) {\n const [, offset] = prev[prev.length - 1]\n if (offset - adjust >= y && !last) {\n next = [prev.pop()!, ...next]\n } else {\n break\n }\n }\n\n /* Return partition */\n return [prev, next]\n }, [[], [...index]]),\n distinctUntilChanged((a, b) => (\n a[0] === b[0] &&\n a[1] === b[1]\n ))\n )\n )\n )\n )\n )\n\n /* Compute and return anchor list migrations */\n return partition$\n .pipe(\n map(([prev, next]) => ({\n prev: prev.map(([path]) => path),\n next: next.map(([path]) => path)\n })),\n\n /* Extract anchor list migrations */\n startWith({ prev: [], next: [] }),\n bufferCount(2, 1),\n map(([a, b]) => {\n\n /* Moving down */\n if (a.prev.length < b.prev.length) {\n return {\n prev: b.prev.slice(Math.max(0, a.prev.length - 1), b.prev.length),\n next: []\n }\n\n /* Moving up */\n } else {\n return {\n prev: b.prev.slice(-1),\n next: b.next.slice(0, b.next.length - a.next.length)\n }\n }\n })\n )\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Mount table of contents\n *\n * @param el - Table of contents element\n * @param options - Options\n *\n * @returns Table of contents component observable\n */\nexport function mountTableOfContents(\n el: HTMLElement, { viewport$, header$, target$ }: MountOptions\n): Observable> {\n return defer(() => {\n const push$ = new Subject()\n const done$ = push$.pipe(takeLast(1))\n push$.subscribe(({ prev, next }) => {\n\n /* Look forward */\n for (const [anchor] of next) {\n anchor.classList.remove(\"md-nav__link--passed\")\n anchor.classList.remove(\"md-nav__link--active\")\n }\n\n /* Look backward */\n for (const [index, [anchor]] of prev.entries()) {\n anchor.classList.add(\"md-nav__link--passed\")\n anchor.classList.toggle(\n \"md-nav__link--active\",\n index === prev.length - 1\n )\n }\n })\n\n /* Set up anchor tracking, if enabled */\n if (feature(\"navigation.tracking\"))\n viewport$\n .pipe(\n takeUntil(done$),\n distinctUntilKeyChanged(\"offset\"),\n debounceTime(250),\n skip(1),\n takeUntil(target$.pipe(skip(1))),\n repeat({ delay: 250 }),\n withLatestFrom(push$)\n )\n .subscribe(([, { prev }]) => {\n const url = getLocation()\n\n /* Set hash fragment to active anchor */\n const anchor = prev[prev.length - 1]\n if (anchor && anchor.length) {\n const [active] = anchor\n const { hash } = new URL(active.href)\n if (url.hash !== hash) {\n url.hash = hash\n history.replaceState({}, \"\", `${url}`)\n }\n\n /* Reset anchor when at the top */\n } else {\n url.hash = \"\"\n history.replaceState({}, \"\", `${url}`)\n }\n })\n\n /* Create and return component */\n return watchTableOfContents(el, { viewport$, header$ })\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n bufferCount,\n combineLatest,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n endWith,\n finalize,\n map,\n repeat,\n skip,\n takeLast,\n takeUntil,\n tap\n} from \"rxjs\"\n\nimport { Viewport } from \"~/browser\"\n\nimport { Component } from \"../_\"\nimport { Header } from \"../header\"\nimport { Main } from \"../main\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Back-to-top button\n */\nexport interface BackToTop {\n hidden: boolean /* Back-to-top button is hidden */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n main$: Observable
    /* Main area observable */\n target$: Observable /* Location target observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n main$: Observable
    /* Main area observable */\n target$: Observable /* Location target observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch back-to-top\n *\n * @param _el - Back-to-top element\n * @param options - Options\n *\n * @returns Back-to-top observable\n */\nexport function watchBackToTop(\n _el: HTMLElement, { viewport$, main$, target$ }: WatchOptions\n): Observable {\n\n /* Compute direction */\n const direction$ = viewport$\n .pipe(\n map(({ offset: { y } }) => y),\n bufferCount(2, 1),\n map(([a, b]) => a > b && b > 0),\n distinctUntilChanged()\n )\n\n /* Compute whether main area is active */\n const active$ = main$\n .pipe(\n map(({ active }) => active)\n )\n\n /* Compute threshold for hiding */\n return combineLatest([active$, direction$])\n .pipe(\n map(([active, direction]) => !(active && direction)),\n distinctUntilChanged(),\n takeUntil(target$.pipe(skip(1))),\n endWith(true),\n repeat({ delay: 250 }),\n map(hidden => ({ hidden }))\n )\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Mount back-to-top\n *\n * @param el - Back-to-top element\n * @param options - Options\n *\n * @returns Back-to-top component observable\n */\nexport function mountBackToTop(\n el: HTMLElement, { viewport$, header$, main$, target$ }: MountOptions\n): Observable> {\n const push$ = new Subject()\n const done$ = push$.pipe(takeLast(1))\n push$.subscribe({\n\n /* Handle emission */\n next({ hidden }) {\n el.hidden = hidden\n if (hidden) {\n el.setAttribute(\"tabindex\", \"-1\")\n el.blur()\n } else {\n el.removeAttribute(\"tabindex\")\n }\n },\n\n /* Handle complete */\n complete() {\n el.style.top = \"\"\n el.hidden = true\n el.removeAttribute(\"tabindex\")\n }\n })\n\n /* Watch header height */\n header$\n .pipe(\n takeUntil(done$),\n distinctUntilKeyChanged(\"height\")\n )\n .subscribe(({ height }) => {\n el.style.top = `${height + 16}px`\n })\n\n /* Create and return component */\n return watchBackToTop(el, { viewport$, main$, target$ })\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n fromEvent,\n map,\n mergeMap,\n switchMap,\n takeWhile,\n tap,\n withLatestFrom\n} from \"rxjs\"\n\nimport { getElements } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch options\n */\ninterface PatchOptions {\n document$: Observable /* Document observable */\n tablet$: Observable /* Media tablet observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch indeterminate checkboxes\n *\n * This function replaces the indeterminate \"pseudo state\" with the actual\n * indeterminate state, which is used to keep navigation always expanded.\n *\n * @param options - Options\n */\nexport function patchIndeterminate(\n { document$, tablet$ }: PatchOptions\n): void {\n document$\n .pipe(\n switchMap(() => getElements(\n // @todo `data-md-state` is deprecated and removed in v9\n \".md-toggle--indeterminate, [data-md-state=indeterminate]\"\n )),\n tap(el => {\n el.indeterminate = true\n el.checked = false\n }),\n mergeMap(el => fromEvent(el, \"change\")\n .pipe(\n takeWhile(() => el.classList.contains(\"md-toggle--indeterminate\")),\n map(() => el)\n )\n ),\n withLatestFrom(tablet$)\n )\n .subscribe(([el, tablet]) => {\n el.classList.remove(\"md-toggle--indeterminate\")\n if (tablet)\n el.checked = false\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n filter,\n fromEvent,\n map,\n mergeMap,\n switchMap,\n tap\n} from \"rxjs\"\n\nimport { getElements } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch options\n */\ninterface PatchOptions {\n document$: Observable /* Document observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Check whether the given device is an Apple device\n *\n * @returns Test result\n */\nfunction isAppleDevice(): boolean {\n return /(iPad|iPhone|iPod)/.test(navigator.userAgent)\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch all elements with `data-md-scrollfix` attributes\n *\n * This is a year-old patch which ensures that overflow scrolling works at the\n * top and bottom of containers on iOS by ensuring a `1px` scroll offset upon\n * the start of a touch event.\n *\n * @see https://bit.ly/2SCtAOO - Original source\n *\n * @param options - Options\n */\nexport function patchScrollfix(\n { document$ }: PatchOptions\n): void {\n document$\n .pipe(\n switchMap(() => getElements(\"[data-md-scrollfix]\")),\n tap(el => el.removeAttribute(\"data-md-scrollfix\")),\n filter(isAppleDevice),\n mergeMap(el => fromEvent(el, \"touchstart\")\n .pipe(\n map(() => el)\n )\n )\n )\n .subscribe(el => {\n const top = el.scrollTop\n\n /* We're at the top of the container */\n if (top === 0) {\n el.scrollTop = 1\n\n /* We're at the bottom of the container */\n } else if (top + el.offsetHeight === el.scrollHeight) {\n el.scrollTop = top - 1\n }\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n combineLatest,\n delay,\n map,\n of,\n switchMap,\n withLatestFrom\n} from \"rxjs\"\n\nimport {\n Viewport,\n watchToggle\n} from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch options\n */\ninterface PatchOptions {\n viewport$: Observable /* Viewport observable */\n tablet$: Observable /* Media tablet observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch the document body to lock when search is open\n *\n * For mobile and tablet viewports, the search is rendered full screen, which\n * leads to scroll leaking when at the top or bottom of the search result. This\n * function locks the body when the search is in full screen mode, and restores\n * the scroll position when leaving.\n *\n * @param options - Options\n */\nexport function patchScrolllock(\n { viewport$, tablet$ }: PatchOptions\n): void {\n combineLatest([watchToggle(\"search\"), tablet$])\n .pipe(\n map(([active, tablet]) => active && !tablet),\n switchMap(active => of(active)\n .pipe(\n delay(active ? 400 : 100)\n )\n ),\n withLatestFrom(viewport$)\n )\n .subscribe(([active, { offset: { y }}]) => {\n if (active) {\n document.body.setAttribute(\"data-md-scrolllock\", \"\")\n document.body.style.top = `-${y}px`\n } else {\n const value = -1 * parseInt(document.body.style.top, 10)\n document.body.removeAttribute(\"data-md-scrolllock\")\n document.body.style.top = \"\"\n if (value)\n window.scrollTo(0, value)\n }\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Polyfills\n * ------------------------------------------------------------------------- */\n\n/* Polyfill `Object.entries` */\nif (!Object.entries)\n Object.entries = function (obj: object) {\n const data: [string, string][] = []\n for (const key of Object.keys(obj))\n // @ts-expect-error - ignore property access warning\n data.push([key, obj[key]])\n\n /* Return entries */\n return data\n }\n\n/* Polyfill `Object.values` */\nif (!Object.values)\n Object.values = function (obj: object) {\n const data: string[] = []\n for (const key of Object.keys(obj))\n // @ts-expect-error - ignore property access warning\n data.push(obj[key])\n\n /* Return values */\n return data\n }\n\n/* ------------------------------------------------------------------------- */\n\n/* Polyfills for `Element` */\nif (typeof Element !== \"undefined\") {\n\n /* Polyfill `Element.scrollTo` */\n if (!Element.prototype.scrollTo)\n Element.prototype.scrollTo = function (\n x?: ScrollToOptions | number, y?: number\n ): void {\n if (typeof x === \"object\") {\n this.scrollLeft = x.left!\n this.scrollTop = x.top!\n } else {\n this.scrollLeft = x!\n this.scrollTop = y!\n }\n }\n\n /* Polyfill `Element.replaceWith` */\n if (!Element.prototype.replaceWith)\n Element.prototype.replaceWith = function (\n ...nodes: Array\n ): void {\n const parent = this.parentNode\n if (parent) {\n if (nodes.length === 0)\n parent.removeChild(this)\n\n /* Replace children and create text nodes */\n for (let i = nodes.length - 1; i >= 0; i--) {\n let node = nodes[i]\n if (typeof node !== \"object\")\n node = document.createTextNode(node)\n else if (node.parentNode)\n node.parentNode.removeChild(node)\n\n /* Replace child or insert before previous sibling */\n if (!i)\n parent.replaceChild(node, this)\n else\n parent.insertBefore(this.previousSibling!, node)\n }\n }\n }\n}\n"], + "mappings": "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", + "names": ["require_focus_visible", "__commonJSMin", "exports", "module", "global", "factory", "applyFocusVisiblePolyfill", "scope", "hadKeyboardEvent", "hadFocusVisibleRecently", "hadFocusVisibleRecentlyTimeout", "inputTypesAllowlist", "isValidFocusTarget", "el", "focusTriggersKeyboardModality", "type", "tagName", "addFocusVisibleClass", "removeFocusVisibleClass", "onKeyDown", "e", "onPointerDown", "onFocus", "onBlur", "onVisibilityChange", "addInitialPointerMoveListeners", "onInitialPointerMove", "removeInitialPointerMoveListeners", "event", "error", "require_url_polyfill", "__commonJSMin", "exports", "global", "checkIfIteratorIsSupported", "error", "iteratorSupported", "createIterator", "items", "iterator", "value", "serializeParam", "deserializeParam", "polyfillURLSearchParams", "URLSearchParams", "searchString", "typeofSearchString", "_this", "name", "i", "entry", "key", "proto", "callback", "thisArg", "entries", "searchArray", "checkIfURLSearchParamsSupported", "e", "a", "b", "keys", "attributes", "attribute", "checkIfURLIsSupported", "u", "polyfillURL", "_URL", "URL", "url", "base", "doc", "baseElement", "err", "anchorElement", "inputElement", "searchParams", "enableSearchUpdate", "enableSearchParamsUpdate", "methodName", "method", "search", "linkURLWithAnchorAttribute", "attributeName", "expectedPort", "addPortToOrigin", "blob", "getOrigin", "require_tslib", "__commonJSMin", "exports", "module", "__extends", "__assign", "__rest", "__decorate", "__param", "__metadata", "__awaiter", "__generator", "__exportStar", "__values", "__read", "__spread", "__spreadArrays", "__spreadArray", "__await", "__asyncGenerator", "__asyncDelegator", "__asyncValues", "__makeTemplateObject", "__importStar", "__importDefault", "__classPrivateFieldGet", "__classPrivateFieldSet", "__createBinding", "factory", "root", "createExporter", "previous", "id", "v", "exporter", "extendStatics", "d", "b", "p", "__", "t", "s", "n", "e", "i", "decorators", "target", "key", "desc", "c", "r", "paramIndex", "decorator", "metadataKey", "metadataValue", "thisArg", "_arguments", "P", "generator", "adopt", "value", "resolve", "reject", "fulfilled", "step", "rejected", "result", "body", "_", "f", "y", "g", "verb", "op", "m", "o", "k", "k2", "ar", "error", "il", "a", "j", "jl", "to", "from", "pack", "l", "q", "resume", "settle", "fulfill", "cooked", "raw", "__setModuleDefault", "mod", "receiver", "state", "kind", "require_clipboard", "__commonJSMin", "exports", "module", "root", "factory", "__webpack_modules__", "__unused_webpack_module", "__webpack_exports__", "__webpack_require__", "clipboard", "tiny_emitter", "tiny_emitter_default", "listen", "listen_default", "src_select", "select_default", "command", "type", "err", "ClipboardActionCut", "target", "selectedText", "actions_cut", "createFakeElement", "value", "isRTL", "fakeElement", "yPosition", "fakeCopyAction", "options", "ClipboardActionCopy", "actions_copy", "_typeof", "obj", "ClipboardActionDefault", "_options$action", "action", "container", "text", "actions_default", "clipboard_typeof", "_classCallCheck", "instance", "Constructor", "_defineProperties", "props", "i", "descriptor", "_createClass", "protoProps", "staticProps", "_inherits", "subClass", "superClass", "_setPrototypeOf", "o", "p", "_createSuper", "Derived", "hasNativeReflectConstruct", "_isNativeReflectConstruct", "Super", "_getPrototypeOf", "result", "NewTarget", "_possibleConstructorReturn", "self", "call", "_assertThisInitialized", "e", "getAttributeValue", "suffix", "element", "attribute", "Clipboard", "_Emitter", "_super", "trigger", "_this", "_this2", "selector", "actions", "support", "DOCUMENT_NODE_TYPE", "proto", "closest", "__unused_webpack_exports", "_delegate", "callback", "useCapture", "listenerFn", "listener", "delegate", "elements", "is", "listenNode", "listenNodeList", "listenSelector", "node", "nodeList", "select", "isReadOnly", "selection", "range", "E", "name", "ctx", "data", "evtArr", "len", "evts", "liveEvents", "__webpack_module_cache__", "moduleId", "getter", "definition", "key", "prop", "require_escape_html", "__commonJSMin", "exports", "module", "matchHtmlRegExp", "escapeHtml", "string", "str", "match", "escape", "html", "index", "lastIndex", "r", "a", "e", "import_focus_visible", "n", "t", "s", "r", "o", "u", "i", "a", "e", "c", "import_url_polyfill", "import_tslib", "__extends", "__assign", "__rest", "__decorate", "__param", "__metadata", "__awaiter", "__generator", "__exportStar", "__createBinding", "__values", "__read", "__spread", "__spreadArrays", "__spreadArray", "__await", "__asyncGenerator", "__asyncDelegator", "__asyncValues", "__makeTemplateObject", "__importStar", "__importDefault", "__classPrivateFieldGet", "__classPrivateFieldSet", "tslib", "isFunction", "value", "createErrorClass", "createImpl", "_super", "instance", "ctorFunc", "UnsubscriptionError", "createErrorClass", "_super", "errors", "err", "i", "arrRemove", "arr", "item", "index", "Subscription", "initialTeardown", "errors", "_parentage", "_parentage_1", "__values", "_parentage_1_1", "parent_1", "initialFinalizer", "isFunction", "e", "UnsubscriptionError", "_finalizers", "_finalizers_1", "_finalizers_1_1", "finalizer", "execFinalizer", "err", "__spreadArray", "__read", "teardown", "_a", "parent", "arrRemove", "empty", "EMPTY_SUBSCRIPTION", "Subscription", "isSubscription", "value", "isFunction", "execFinalizer", "finalizer", "config", "timeoutProvider", "handler", "timeout", "args", "_i", "delegate", "__spreadArray", "__read", "handle", "reportUnhandledError", "err", "timeoutProvider", "onUnhandledError", "config", "noop", "COMPLETE_NOTIFICATION", "createNotification", "errorNotification", "error", "nextNotification", "value", "kind", "context", "errorContext", "cb", "config", "isRoot", "_a", "errorThrown", "error", "captureError", "err", "Subscriber", "_super", "__extends", "destination", "_this", "isSubscription", "EMPTY_OBSERVER", "next", "error", "complete", "SafeSubscriber", "value", "handleStoppedNotification", "nextNotification", "err", "errorNotification", "COMPLETE_NOTIFICATION", "Subscription", "_bind", "bind", "fn", "thisArg", "ConsumerObserver", "partialObserver", "value", "error", "handleUnhandledError", "err", "SafeSubscriber", "_super", "__extends", "observerOrNext", "complete", "_this", "isFunction", "context_1", "config", "Subscriber", "handleUnhandledError", "error", "config", "captureError", "reportUnhandledError", "defaultErrorHandler", "err", "handleStoppedNotification", "notification", "subscriber", "onStoppedNotification", "timeoutProvider", "EMPTY_OBSERVER", "noop", "observable", "identity", "x", "pipe", "fns", "_i", "pipeFromArray", "identity", "input", "prev", "fn", "Observable", "subscribe", "operator", "observable", "observerOrNext", "error", "complete", "_this", "subscriber", "isSubscriber", "SafeSubscriber", "errorContext", "_a", "source", "sink", "err", "next", "promiseCtor", "getPromiseCtor", "resolve", "reject", "value", "operations", "_i", "pipeFromArray", "x", "getPromiseCtor", "promiseCtor", "_a", "config", "isObserver", "value", "isFunction", "isSubscriber", "Subscriber", "isSubscription", "hasLift", "source", "isFunction", "operate", "init", "liftedSource", "err", "createOperatorSubscriber", "destination", "onNext", "onComplete", "onError", "onFinalize", "OperatorSubscriber", "_super", "__extends", "shouldUnsubscribe", "_this", "value", "err", "closed_1", "_a", "Subscriber", "animationFrameProvider", "callback", "request", "cancel", "delegate", "handle", "timestamp", "Subscription", "args", "_i", "__spreadArray", "__read", "ObjectUnsubscribedError", "createErrorClass", "_super", "Subject", "_super", "__extends", "_this", "operator", "subject", "AnonymousSubject", "ObjectUnsubscribedError", "value", "errorContext", "_b", "__values", "_c", "observer", "err", "observers", "_a", "subscriber", "hasError", "isStopped", "EMPTY_SUBSCRIPTION", "Subscription", "arrRemove", "thrownError", "observable", "Observable", "destination", "source", "AnonymousSubject", "_super", "__extends", "destination", "source", "_this", "value", "_b", "_a", "err", "subscriber", "EMPTY_SUBSCRIPTION", "Subject", "dateTimestampProvider", "ReplaySubject", "_super", "__extends", "_bufferSize", "_windowTime", "_timestampProvider", "dateTimestampProvider", "_this", "value", "_a", "isStopped", "_buffer", "_infiniteTimeWindow", "subscriber", "subscription", "copy", "i", "adjustedBufferSize", "now", "last", "Subject", "Action", "_super", "__extends", "scheduler", "work", "state", "delay", "Subscription", "intervalProvider", "handler", "timeout", "args", "_i", "delegate", "__spreadArray", "__read", "handle", "AsyncAction", "_super", "__extends", "scheduler", "work", "_this", "state", "delay", "id", "_id", "intervalProvider", "_scheduler", "error", "_delay", "errored", "errorValue", "e", "_a", "actions", "arrRemove", "Action", "Scheduler", "schedulerActionCtor", "now", "work", "delay", "state", "dateTimestampProvider", "AsyncScheduler", "_super", "__extends", "SchedulerAction", "now", "Scheduler", "_this", "action", "actions", "error", "asyncScheduler", "AsyncScheduler", "AsyncAction", "async", "AnimationFrameAction", "_super", "__extends", "scheduler", "work", "_this", "id", "delay", "animationFrameProvider", "action", "AsyncAction", "AnimationFrameScheduler", "_super", "__extends", "action", "flushId", "actions", "error", "AsyncScheduler", "animationFrameScheduler", "AnimationFrameScheduler", "AnimationFrameAction", "EMPTY", "Observable", "subscriber", "isScheduler", "value", "isFunction", "last", "arr", "popResultSelector", "args", "isFunction", "popScheduler", "isScheduler", "popNumber", "defaultValue", "isArrayLike", "x", "isPromise", "value", "isFunction", "isInteropObservable", "input", "isFunction", "observable", "isAsyncIterable", "obj", "isFunction", "createInvalidObservableTypeError", "input", "getSymbolIterator", "iterator", "isIterable", "input", "isFunction", "iterator", "readableStreamLikeToAsyncGenerator", "readableStream", "reader", "__await", "_a", "_b", "value", "done", "isReadableStreamLike", "obj", "isFunction", "innerFrom", "input", "Observable", "isInteropObservable", "fromInteropObservable", "isArrayLike", "fromArrayLike", "isPromise", "fromPromise", "isAsyncIterable", "fromAsyncIterable", "isIterable", "fromIterable", "isReadableStreamLike", "fromReadableStreamLike", "createInvalidObservableTypeError", "obj", "subscriber", "obs", "observable", "isFunction", "array", "i", "promise", "value", "err", "reportUnhandledError", "iterable", "iterable_1", "__values", "iterable_1_1", "asyncIterable", "process", "readableStream", "readableStreamLikeToAsyncGenerator", "asyncIterable_1", "__asyncValues", "asyncIterable_1_1", "executeSchedule", "parentSubscription", "scheduler", "work", "delay", "repeat", "scheduleSubscription", "observeOn", "scheduler", "delay", "operate", "source", "subscriber", "createOperatorSubscriber", "value", "executeSchedule", "err", "subscribeOn", "scheduler", "delay", "operate", "source", "subscriber", "scheduleObservable", "input", "scheduler", "innerFrom", "subscribeOn", "observeOn", "schedulePromise", "input", "scheduler", "innerFrom", "subscribeOn", "observeOn", "scheduleArray", "input", "scheduler", "Observable", "subscriber", "i", "scheduleIterable", "input", "scheduler", "Observable", "subscriber", "iterator", "executeSchedule", "value", "done", "_a", "err", "isFunction", "scheduleAsyncIterable", "input", "scheduler", "Observable", "subscriber", "executeSchedule", "iterator", "result", "scheduleReadableStreamLike", "input", "scheduler", "scheduleAsyncIterable", "readableStreamLikeToAsyncGenerator", "scheduled", "input", "scheduler", "isInteropObservable", "scheduleObservable", "isArrayLike", "scheduleArray", "isPromise", "schedulePromise", "isAsyncIterable", "scheduleAsyncIterable", "isIterable", "scheduleIterable", "isReadableStreamLike", "scheduleReadableStreamLike", "createInvalidObservableTypeError", "from", "input", "scheduler", "scheduled", "innerFrom", "of", "args", "_i", "scheduler", "popScheduler", "from", "throwError", "errorOrErrorFactory", "scheduler", "errorFactory", "isFunction", "init", "subscriber", "Observable", "isValidDate", "value", "map", "project", "thisArg", "operate", "source", "subscriber", "index", "createOperatorSubscriber", "value", "isArray", "callOrApply", "fn", "args", "__spreadArray", "__read", "mapOneOrManyArgs", "map", "isArray", "getPrototypeOf", "objectProto", "getKeys", "argsArgArrayOrObject", "args", "first_1", "isPOJO", "keys", "key", "obj", "createObject", "keys", "values", "result", "key", "i", "combineLatest", "args", "_i", "scheduler", "popScheduler", "resultSelector", "popResultSelector", "_a", "argsArgArrayOrObject", "observables", "keys", "from", "result", "Observable", "combineLatestInit", "values", "createObject", "identity", "mapOneOrManyArgs", "valueTransform", "subscriber", "maybeSchedule", "length", "active", "remainingFirstValues", "i", "source", "hasFirstValue", "createOperatorSubscriber", "value", "execute", "subscription", "executeSchedule", "mergeInternals", "source", "subscriber", "project", "concurrent", "onBeforeNext", "expand", "innerSubScheduler", "additionalFinalizer", "buffer", "active", "index", "isComplete", "checkComplete", "outerNext", "value", "doInnerSub", "innerComplete", "innerFrom", "createOperatorSubscriber", "innerValue", "bufferedValue", "executeSchedule", "err", "mergeMap", "project", "resultSelector", "concurrent", "isFunction", "a", "i", "map", "b", "ii", "innerFrom", "operate", "source", "subscriber", "mergeInternals", "mergeAll", "concurrent", "mergeMap", "identity", "concatAll", "mergeAll", "concat", "args", "_i", "concatAll", "from", "popScheduler", "defer", "observableFactory", "Observable", "subscriber", "innerFrom", "nodeEventEmitterMethods", "eventTargetMethods", "jqueryMethods", "fromEvent", "target", "eventName", "options", "resultSelector", "isFunction", "mapOneOrManyArgs", "_a", "__read", "isEventTarget", "methodName", "handler", "isNodeStyleEventEmitter", "toCommonHandlerRegistry", "isJQueryStyleEventEmitter", "add", "remove", "isArrayLike", "mergeMap", "subTarget", "innerFrom", "Observable", "subscriber", "args", "_i", "fromEventPattern", "addHandler", "removeHandler", "resultSelector", "mapOneOrManyArgs", "Observable", "subscriber", "handler", "e", "_i", "retValue", "isFunction", "timer", "dueTime", "intervalOrScheduler", "scheduler", "async", "intervalDuration", "isScheduler", "Observable", "subscriber", "due", "isValidDate", "n", "merge", "args", "_i", "scheduler", "popScheduler", "concurrent", "popNumber", "sources", "innerFrom", "mergeAll", "from", "EMPTY", "NEVER", "Observable", "noop", "isArray", "argsOrArgArray", "args", "filter", "predicate", "thisArg", "operate", "source", "subscriber", "index", "createOperatorSubscriber", "value", "zip", "args", "_i", "resultSelector", "popResultSelector", "sources", "argsOrArgArray", "Observable", "subscriber", "buffers", "completed", "sourceIndex", "innerFrom", "createOperatorSubscriber", "value", "buffer", "result", "__spreadArray", "__read", "i", "EMPTY", "audit", "durationSelector", "operate", "source", "subscriber", "hasValue", "lastValue", "durationSubscriber", "isComplete", "endDuration", "value", "cleanupDuration", "createOperatorSubscriber", "innerFrom", "auditTime", "duration", "scheduler", "asyncScheduler", "audit", "timer", "bufferCount", "bufferSize", "startBufferEvery", "operate", "source", "subscriber", "buffers", "count", "createOperatorSubscriber", "value", "toEmit", "buffers_1", "__values", "buffers_1_1", "buffer", "toEmit_1", "toEmit_1_1", "arrRemove", "buffers_2", "buffers_2_1", "catchError", "selector", "operate", "source", "subscriber", "innerSub", "syncUnsub", "handledResult", "createOperatorSubscriber", "err", "innerFrom", "scanInternals", "accumulator", "seed", "hasSeed", "emitOnNext", "emitBeforeComplete", "source", "subscriber", "hasState", "state", "index", "createOperatorSubscriber", "value", "i", "combineLatest", "args", "_i", "resultSelector", "popResultSelector", "pipe", "__spreadArray", "__read", "mapOneOrManyArgs", "operate", "source", "subscriber", "combineLatestInit", "argsOrArgArray", "combineLatestWith", "otherSources", "_i", "combineLatest", "__spreadArray", "__read", "concatMap", "project", "resultSelector", "isFunction", "mergeMap", "debounceTime", "dueTime", "scheduler", "asyncScheduler", "operate", "source", "subscriber", "activeTask", "lastValue", "lastTime", "emit", "value", "emitWhenIdle", "targetTime", "now", "createOperatorSubscriber", "defaultIfEmpty", "defaultValue", "operate", "source", "subscriber", "hasValue", "createOperatorSubscriber", "value", "take", "count", "EMPTY", "operate", "source", "subscriber", "seen", "createOperatorSubscriber", "value", "ignoreElements", "operate", "source", "subscriber", "createOperatorSubscriber", "noop", "mapTo", "value", "map", "delayWhen", "delayDurationSelector", "subscriptionDelay", "source", "concat", "take", "ignoreElements", "mergeMap", "value", "index", "mapTo", "delay", "due", "scheduler", "asyncScheduler", "duration", "timer", "delayWhen", "distinctUntilChanged", "comparator", "keySelector", "identity", "defaultCompare", "operate", "source", "subscriber", "previousKey", "first", "createOperatorSubscriber", "value", "currentKey", "a", "b", "distinctUntilKeyChanged", "key", "compare", "distinctUntilChanged", "x", "y", "endWith", "values", "_i", "source", "concat", "of", "__spreadArray", "__read", "finalize", "callback", "operate", "source", "subscriber", "takeLast", "count", "EMPTY", "operate", "source", "subscriber", "buffer", "createOperatorSubscriber", "value", "buffer_1", "__values", "buffer_1_1", "merge", "args", "_i", "scheduler", "popScheduler", "concurrent", "popNumber", "argsOrArgArray", "operate", "source", "subscriber", "mergeAll", "from", "__spreadArray", "__read", "mergeWith", "otherSources", "_i", "merge", "__spreadArray", "__read", "repeat", "countOrConfig", "count", "delay", "_a", "EMPTY", "operate", "source", "subscriber", "soFar", "sourceSub", "resubscribe", "notifier", "timer", "innerFrom", "notifierSubscriber_1", "createOperatorSubscriber", "subscribeToSource", "syncUnsub", "sample", "notifier", "operate", "source", "subscriber", "hasValue", "lastValue", "createOperatorSubscriber", "value", "noop", "scan", "accumulator", "seed", "operate", "scanInternals", "share", "options", "_a", "connector", "Subject", "_b", "resetOnError", "_c", "resetOnComplete", "_d", "resetOnRefCountZero", "wrapperSource", "connection", "resetConnection", "subject", "refCount", "hasCompleted", "hasErrored", "cancelReset", "reset", "resetAndUnsubscribe", "conn", "operate", "source", "subscriber", "dest", "handleReset", "SafeSubscriber", "value", "err", "innerFrom", "on", "args", "_i", "onSubscriber", "__spreadArray", "__read", "shareReplay", "configOrBufferSize", "windowTime", "scheduler", "bufferSize", "refCount", "_a", "_b", "_c", "share", "ReplaySubject", "skip", "count", "filter", "_", "index", "skipUntil", "notifier", "operate", "source", "subscriber", "taking", "skipSubscriber", "createOperatorSubscriber", "noop", "innerFrom", "value", "startWith", "values", "_i", "scheduler", "popScheduler", "operate", "source", "subscriber", "concat", "switchMap", "project", "resultSelector", "operate", "source", "subscriber", "innerSubscriber", "index", "isComplete", "checkComplete", "createOperatorSubscriber", "value", "innerIndex", "outerIndex", "innerFrom", "innerValue", "takeUntil", "notifier", "operate", "source", "subscriber", "innerFrom", "createOperatorSubscriber", "noop", "takeWhile", "predicate", "inclusive", "operate", "source", "subscriber", "index", "createOperatorSubscriber", "value", "result", "tap", "observerOrNext", "error", "complete", "tapObserver", "isFunction", "operate", "source", "subscriber", "_a", "isUnsub", "createOperatorSubscriber", "value", "err", "_b", "identity", "defaultThrottleConfig", "throttle", "durationSelector", "config", "operate", "source", "subscriber", "leading", "trailing", "hasValue", "sendValue", "throttled", "isComplete", "endThrottling", "send", "cleanupThrottling", "startThrottle", "value", "innerFrom", "createOperatorSubscriber", "throttleTime", "duration", "scheduler", "config", "asyncScheduler", "defaultThrottleConfig", "duration$", "timer", "throttle", "withLatestFrom", "inputs", "_i", "project", "popResultSelector", "operate", "source", "subscriber", "len", "otherValues", "hasValue", "ready", "i", "innerFrom", "createOperatorSubscriber", "value", "identity", "noop", "values", "__spreadArray", "__read", "zip", "sources", "_i", "operate", "source", "subscriber", "__spreadArray", "__read", "zipWith", "otherInputs", "_i", "zip", "__spreadArray", "__read", "watchDocument", "document$", "ReplaySubject", "fromEvent", "getElements", "selector", "node", "getElement", "el", "getOptionalElement", "getActiveElement", "watchElementFocus", "el", "merge", "fromEvent", "debounceTime", "map", "active", "getActiveElement", "startWith", "distinctUntilChanged", "getElementOffset", "el", "watchElementOffset", "merge", "fromEvent", "auditTime", "animationFrameScheduler", "map", "startWith", "getElementContentOffset", "el", "watchElementContentOffset", "merge", "fromEvent", "auditTime", "animationFrameScheduler", "map", "startWith", "MapShim", "getIndex", "arr", "key", "result", "entry", "index", "class_1", "value", "entries", "callback", "ctx", "_i", "_a", "isBrowser", "global$1", "requestAnimationFrame$1", "trailingTimeout", "throttle", "delay", "leadingCall", "trailingCall", "lastCallTime", "resolvePending", "proxy", "timeoutCallback", "timeStamp", "REFRESH_DELAY", "transitionKeys", "mutationObserverSupported", "ResizeObserverController", "observer", "observers", "changesDetected", "activeObservers", "_b", "propertyName", "isReflowProperty", "defineConfigurable", "target", "props", "getWindowOf", "ownerGlobal", "emptyRect", "createRectInit", "toFloat", "getBordersSize", "styles", "positions", "size", "position", "getPaddings", "paddings", "positions_1", "getSVGContentRect", "bbox", "getHTMLElementContentRect", "clientWidth", "clientHeight", "horizPad", "vertPad", "width", "height", "isDocumentElement", "vertScrollbar", "horizScrollbar", "isSVGGraphicsElement", "getContentRect", "createReadOnlyRect", "x", "y", "Constr", "rect", "ResizeObservation", "ResizeObserverEntry", "rectInit", "contentRect", "ResizeObserverSPI", "controller", "callbackCtx", "observations", "_this", "observation", "ResizeObserver", "method", "ResizeObserver_es_default", "entry$", "Subject", "observer$", "defer", "of", "ResizeObserver_es_default", "entries", "entry", "switchMap", "observer", "merge", "NEVER", "finalize", "shareReplay", "getElementSize", "el", "watchElementSize", "tap", "filter", "target", "map", "startWith", "getElementContentSize", "el", "entry$", "Subject", "observer$", "defer", "of", "entries", "entry", "switchMap", "observer", "merge", "NEVER", "finalize", "shareReplay", "watchElementVisibility", "el", "tap", "filter", "target", "map", "isIntersecting", "watchElementBoundary", "threshold", "watchElementContentOffset", "y", "visible", "getElementSize", "content", "getElementContentSize", "distinctUntilChanged", "toggles", "getElement", "getToggle", "name", "setToggle", "value", "watchToggle", "el", "fromEvent", "map", "startWith", "isSusceptibleToKeyboard", "el", "type", "watchKeyboard", "fromEvent", "filter", "ev", "map", "getToggle", "mode", "active", "getActiveElement", "share", "getLocation", "setLocation", "url", "watchLocation", "Subject", "appendChild", "el", "child", "node", "h", "tag", "attributes", "children", "attr", "truncate", "value", "n", "i", "round", "digits", "getLocationHash", "setLocationHash", "hash", "el", "h", "ev", "watchLocationHash", "fromEvent", "map", "startWith", "filter", "shareReplay", "watchLocationTarget", "id", "getOptionalElement", "watchMedia", "query", "media", "fromEventPattern", "next", "startWith", "watchPrint", "merge", "fromEvent", "map", "at", "query$", "factory", "switchMap", "active", "EMPTY", "request", "url", "options", "from", "catchError", "EMPTY", "switchMap", "res", "throwError", "of", "requestJSON", "shareReplay", "requestXML", "dom", "map", "watchScript", "src", "script", "h", "defer", "merge", "fromEvent", "switchMap", "throwError", "map", "finalize", "take", "getViewportOffset", "watchViewportOffset", "merge", "fromEvent", "map", "startWith", "getViewportSize", "watchViewportSize", "fromEvent", "map", "startWith", "watchViewport", "combineLatest", "watchViewportOffset", "watchViewportSize", "map", "offset", "size", "shareReplay", "watchViewportAt", "el", "viewport$", "header$", "size$", "distinctUntilKeyChanged", "offset$", "combineLatest", "map", "getElementOffset", "height", "offset", "size", "x", "y", "watchWorker", "worker", "tx$", "rx$", "fromEvent", "map", "data", "throttle", "tap", "message", "switchMap", "share", "script", "getElement", "config", "getLocation", "configuration", "feature", "flag", "translation", "key", "value", "getComponentElement", "type", "node", "getElement", "getComponentElements", "getElements", "watchAnnounce", "el", "button", "getElement", "fromEvent", "map", "content", "mountAnnounce", "feature", "EMPTY", "defer", "push$", "Subject", "startWith", "hash", "_a", "tap", "state", "finalize", "__spreadValues", "watchConsent", "el", "target$", "map", "target", "mountConsent", "options", "internal$", "Subject", "hidden", "tap", "state", "finalize", "__spreadValues", "import_clipboard", "renderAnnotation", "id", "h", "renderClipboardButton", "id", "h", "translation", "renderSearchDocument", "document", "flag", "parent", "teaser", "missing", "key", "list", "h", "url", "feature", "match", "highlight", "value", "truncate", "tag", "translation", "renderSearchResultItem", "result", "threshold", "docs", "doc", "article", "index", "best", "more", "children", "section", "renderSourceFacts", "facts", "h", "key", "value", "round", "renderTabbedControl", "type", "classes", "h", "renderTable", "table", "h", "renderVersion", "version", "config", "configuration", "url", "h", "renderVersionSelector", "versions", "active", "translation", "watchAnnotation", "el", "container", "offset$", "defer", "combineLatest", "watchElementOffset", "watchElementContentOffset", "map", "x", "y", "scroll", "width", "getElementSize", "watchElementFocus", "switchMap", "active", "offset", "take", "mountAnnotation", "push$", "Subject", "done$", "takeLast", "watchElementVisibility", "takeUntil", "visible", "throttleTime", "animationFrameScheduler", "origin", "index", "getElement", "blur$", "fromEvent", "EMPTY", "tap", "ev", "state", "finalize", "__spreadValues", "findAnnotationMarkers", "container", "markers", "comment", "getElements", "match", "text", "marker", "swap", "source", "target", "mountAnnotationList", "el", "print$", "annotations", "id", "getOptionalElement", "renderAnnotation", "EMPTY", "defer", "done$", "Subject", "takeUntil", "takeLast", "active", "annotation", "inner", "getElement", "child", "merge", "mountAnnotation", "finalize", "share", "sequence", "findCandidateList", "el", "sibling", "watchCodeBlock", "watchElementSize", "map", "width", "getElementContentSize", "distinctUntilKeyChanged", "mountCodeBlock", "options", "hover", "factory$", "defer", "push$", "Subject", "scrollable", "ClipboardJS", "parent", "renderClipboardButton", "container", "list", "feature", "annotations$", "mountAnnotationList", "tap", "state", "finalize", "__spreadValues", "mergeWith", "takeUntil", "takeLast", "height", "distinctUntilChanged", "switchMap", "active", "EMPTY", "watchElementVisibility", "filter", "visible", "take", "mermaid$", "sequence", "fetchScripts", "watchScript", "of", "mountMermaid", "el", "tap", "mermaid_default", "map", "shareReplay", "id", "host", "h", "svg", "shadow", "watchDetails", "el", "target$", "print$", "open", "merge", "map", "target", "filter", "details", "active", "tap", "mountDetails", "options", "defer", "push$", "Subject", "action", "reveal", "state", "finalize", "__spreadValues", "sentinel", "h", "mountDataTable", "el", "renderTable", "of", "watchContentTabs", "el", "inputs", "getElements", "initial", "input", "merge", "fromEvent", "map", "getElement", "startWith", "active", "mountContentTabs", "prev", "renderTabbedControl", "next", "container", "defer", "push$", "Subject", "done$", "takeLast", "combineLatest", "watchElementSize", "auditTime", "animationFrameScheduler", "takeUntil", "size", "offset", "getElementOffset", "width", "getElementSize", "content", "getElementContentOffset", "watchElementContentOffset", "getElementContentSize", "direction", "feature", "skip", "tab", "set", "tabs", "tap", "state", "finalize", "__spreadValues", "subscribeOn", "asyncScheduler", "mountContent", "el", "target$", "print$", "merge", "getElements", "child", "mountCodeBlock", "mountMermaid", "mountDataTable", "mountDetails", "mountContentTabs", "watchDialog", "_el", "alert$", "switchMap", "message", "merge", "of", "delay", "map", "active", "mountDialog", "el", "options", "inner", "getElement", "defer", "push$", "Subject", "tap", "state", "finalize", "__spreadValues", "isHidden", "viewport$", "feature", "of", "direction$", "map", "y", "bufferCount", "a", "b", "distinctUntilKeyChanged", "hidden$", "combineLatest", "filter", "offset", "direction", "distinctUntilChanged", "search$", "watchToggle", "search", "switchMap", "active", "startWith", "watchHeader", "el", "options", "defer", "watchElementSize", "height", "hidden", "shareReplay", "mountHeader", "header$", "main$", "push$", "Subject", "done$", "takeLast", "combineLatestWith", "takeUntil", "state", "__spreadValues", "watchHeaderTitle", "el", "viewport$", "header$", "watchViewportAt", "map", "y", "height", "getElementSize", "distinctUntilKeyChanged", "mountHeaderTitle", "options", "defer", "push$", "Subject", "active", "heading", "getOptionalElement", "EMPTY", "tap", "state", "finalize", "__spreadValues", "watchMain", "el", "viewport$", "header$", "adjust$", "map", "height", "distinctUntilChanged", "border$", "switchMap", "watchElementSize", "distinctUntilKeyChanged", "combineLatest", "header", "top", "bottom", "y", "a", "b", "watchPalette", "inputs", "current", "input", "of", "mergeMap", "fromEvent", "map", "startWith", "shareReplay", "mountPalette", "el", "defer", "push$", "Subject", "palette", "key", "value", "index", "label", "observeOn", "asyncScheduler", "getElements", "tap", "state", "finalize", "__spreadValues", "import_clipboard", "extract", "el", "text", "setupClipboardJS", "alert$", "ClipboardJS", "Observable", "subscriber", "getElement", "ev", "tap", "map", "translation", "preprocess", "urls", "root", "next", "a", "b", "url", "index", "fetchSitemap", "base", "cached", "of", "config", "configuration", "requestXML", "map", "sitemap", "getElements", "node", "catchError", "EMPTY", "defaultIfEmpty", "tap", "setupInstantLoading", "document$", "location$", "viewport$", "config", "configuration", "fromEvent", "favicon", "getOptionalElement", "push$", "fetchSitemap", "map", "paths", "path", "switchMap", "urls", "filter", "ev", "el", "url", "of", "NEVER", "share", "pop$", "merge", "distinctUntilChanged", "a", "b", "response$", "distinctUntilKeyChanged", "request", "catchError", "setLocation", "sample", "dom", "res", "skip", "replacement", "selector", "feature", "source", "target", "getComponentElement", "getElements", "concatMap", "script", "h", "name", "Observable", "observer", "EMPTY", "offset", "setLocationHash", "skipUntil", "debounceTime", "bufferCount", "state", "import_escape_html", "import_escape_html", "setupSearchHighlighter", "config", "escape", "separator", "highlight", "_", "data", "term", "query", "match", "value", "escapeHTML", "defaultTransform", "query", "terms", "index", "isSearchReadyMessage", "message", "isSearchQueryMessage", "isSearchResultMessage", "setupSearchIndex", "config", "docs", "translation", "options", "feature", "setupSearchWorker", "url", "index", "configuration", "worker", "tx$", "Subject", "rx$", "watchWorker", "map", "message", "isSearchResultMessage", "result", "document", "share", "from", "data", "setupVersionSelector", "document$", "config", "configuration", "versions$", "requestJSON", "catchError", "EMPTY", "current$", "map", "versions", "current", "version", "aliases", "switchMap", "urls", "fromEvent", "filter", "ev", "withLatestFrom", "el", "url", "of", "fetchSitemap", "sitemap", "path", "getLocation", "setLocation", "combineLatest", "getElement", "renderVersionSelector", "_a", "outdated", "latest", "warning", "getComponentElements", "watchSearchQuery", "el", "rx$", "fn", "defaultTransform", "searchParams", "getLocation", "setToggle", "param$", "filter", "isSearchReadyMessage", "take", "map", "watchToggle", "active", "url", "value", "focus$", "watchElementFocus", "value$", "merge", "fromEvent", "delay", "startWith", "distinctUntilChanged", "combineLatest", "focus", "shareReplay", "mountSearchQuery", "tx$", "push$", "Subject", "done$", "takeLast", "distinctUntilKeyChanged", "translation", "takeUntil", "tap", "state", "finalize", "__spreadValues", "share", "mountSearchResult", "el", "rx$", "query$", "push$", "Subject", "boundary$", "watchElementBoundary", "filter", "meta", "getElement", "list", "ready$", "isSearchReadyMessage", "take", "withLatestFrom", "skipUntil", "items", "value", "translation", "round", "tap", "switchMap", "merge", "of", "bufferCount", "zipWith", "chunk", "result", "renderSearchResultItem", "isSearchResultMessage", "map", "data", "state", "finalize", "__spreadValues", "watchSearchShare", "_el", "query$", "map", "value", "url", "getLocation", "mountSearchShare", "el", "options", "push$", "Subject", "fromEvent", "ev", "tap", "state", "finalize", "__spreadValues", "mountSearchSuggest", "el", "rx$", "keyboard$", "push$", "Subject", "query", "getComponentElement", "query$", "merge", "fromEvent", "observeOn", "asyncScheduler", "map", "distinctUntilChanged", "combineLatestWith", "suggestions", "value", "words", "last", "filter", "mode", "key", "isSearchResultMessage", "data", "tap", "state", "finalize", "mountSearch", "el", "index$", "keyboard$", "config", "configuration", "url", "worker", "setupSearchWorker", "query", "getComponentElement", "result", "tx$", "rx$", "filter", "isSearchQueryMessage", "sample", "isSearchReadyMessage", "take", "mode", "key", "active", "getActiveElement", "anchors", "anchor", "getElements", "article", "best", "a", "b", "setToggle", "els", "i", "query$", "mountSearchQuery", "result$", "mountSearchResult", "merge", "mergeWith", "getComponentElements", "child", "mountSearchShare", "mountSearchSuggest", "err", "NEVER", "mountSearchHiglight", "el", "index$", "location$", "combineLatest", "startWith", "getLocation", "filter", "url", "map", "index", "setupSearchHighlighter", "fn", "_a", "nodes", "it", "node", "original", "replaced", "text", "childNodes", "h", "watchSidebar", "el", "viewport$", "main$", "parent", "adjust", "combineLatest", "map", "offset", "height", "y", "distinctUntilChanged", "a", "b", "mountSidebar", "_a", "_b", "header$", "options", "__objRest", "inner", "getElement", "getElementOffset", "defer", "push$", "Subject", "auditTime", "animationFrameScheduler", "withLatestFrom", "tap", "state", "finalize", "__spreadValues", "fetchSourceFactsFromGitHub", "user", "repo", "url", "zip", "requestJSON", "catchError", "EMPTY", "map", "release", "defaultIfEmpty", "info", "__spreadValues", "fetchSourceFactsFromGitLab", "base", "project", "url", "requestJSON", "catchError", "EMPTY", "map", "star_count", "forks_count", "defaultIfEmpty", "fetchSourceFacts", "url", "type", "user", "repo", "fetchSourceFactsFromGitHub", "base", "slug", "fetchSourceFactsFromGitLab", "EMPTY", "fetch$", "watchSource", "el", "defer", "cached", "of", "fetchSourceFacts", "tap", "facts", "catchError", "EMPTY", "filter", "map", "shareReplay", "mountSource", "inner", "getElement", "push$", "Subject", "renderSourceFacts", "state", "finalize", "__spreadValues", "watchTabs", "el", "viewport$", "header$", "watchElementSize", "switchMap", "watchViewportAt", "map", "y", "distinctUntilKeyChanged", "mountTabs", "options", "defer", "push$", "Subject", "hidden", "feature", "of", "tap", "state", "finalize", "__spreadValues", "watchTableOfContents", "el", "viewport$", "header$", "table", "anchors", "getElements", "anchor", "id", "target", "getOptionalElement", "adjust$", "distinctUntilKeyChanged", "map", "height", "main", "getComponentElement", "grid", "getElement", "share", "watchElementSize", "switchMap", "body", "defer", "path", "of", "index", "offset", "a", "b", "combineLatestWith", "adjust", "scan", "prev", "next", "y", "size", "last", "distinctUntilChanged", "startWith", "bufferCount", "mountTableOfContents", "target$", "push$", "Subject", "done$", "takeLast", "feature", "takeUntil", "debounceTime", "skip", "repeat", "withLatestFrom", "url", "getLocation", "active", "hash", "tap", "state", "finalize", "__spreadValues", "watchBackToTop", "_el", "viewport$", "main$", "target$", "direction$", "map", "y", "bufferCount", "b", "distinctUntilChanged", "active$", "active", "combineLatest", "direction", "takeUntil", "skip", "endWith", "repeat", "hidden", "mountBackToTop", "el", "header$", "push$", "Subject", "done$", "takeLast", "distinctUntilKeyChanged", "height", "tap", "state", "finalize", "__spreadValues", "patchIndeterminate", "document$", "tablet$", "switchMap", "getElements", "tap", "el", "mergeMap", "fromEvent", "takeWhile", "map", "withLatestFrom", "tablet", "isAppleDevice", "patchScrollfix", "document$", "switchMap", "getElements", "tap", "el", "filter", "mergeMap", "fromEvent", "map", "top", "patchScrolllock", "viewport$", "tablet$", "combineLatest", "watchToggle", "map", "active", "tablet", "switchMap", "of", "delay", "withLatestFrom", "y", "value", "obj", "data", "key", "x", "y", "nodes", "parent", "i", "node", "document$", "watchDocument", "location$", "watchLocation", "target$", "watchLocationTarget", "keyboard$", "watchKeyboard", "viewport$", "watchViewport", "tablet$", "watchMedia", "screen$", "print$", "watchPrint", "config", "configuration", "index$", "requestJSON", "NEVER", "alert$", "Subject", "setupClipboardJS", "feature", "setupInstantLoading", "_a", "setupVersionSelector", "merge", "delay", "setToggle", "filter", "mode", "key", "prev", "getOptionalElement", "next", "patchIndeterminate", "patchScrollfix", "patchScrolllock", "header$", "watchHeader", "getComponentElement", "main$", "map", "switchMap", "el", "watchMain", "shareReplay", "control$", "getComponentElements", "mountConsent", "mountDialog", "mountHeader", "mountPalette", "mountSearch", "mountSource", "content$", "defer", "mountAnnounce", "mountContent", "mountSearchHiglight", "EMPTY", "mountHeaderTitle", "at", "mountSidebar", "mountTabs", "mountTableOfContents", "mountBackToTop", "component$", "mergeWith"] +} diff --git a/assets/javascripts/ethers-6.3.esm.min.js b/assets/javascripts/ethers-6.3.esm.min.js new file mode 100644 index 000000000..7c3e5057b --- /dev/null +++ b/assets/javascripts/ethers-6.3.esm.min.js @@ -0,0 +1 @@ +const __$G=typeof globalThis!=="undefined"?globalThis:typeof window!=="undefined"?window:typeof global!=="undefined"?global:typeof self!=="undefined"?self:{};const version="6.3.0";function checkType(value,type,name){const types=type.split("|").map(t=>t.trim());for(let i=0;iPromise.resolve(value[k])));return results.reduce((accum,v,index)=>{accum[keys[index]]=v;return accum},{})}function defineProperties(target,values,types){for(let key in values){let value=values[key];const type=types?types[key]:null;if(type){checkType(value,type,key)}Object.defineProperty(target,key,{enumerable:true,value:value,writable:false})}}function stringify$1(value){if(value==null){return"null"}if(Array.isArray(value)){return"[ "+value.map(stringify$1).join(", ")+" ]"}if(value instanceof Uint8Array){const HEX="0123456789abcdef";let result="0x";for(let i=0;i>4];result+=HEX[value[i]&15]}return result}if(typeof value==="object"&&typeof value.toJSON==="function"){return stringify$1(value.toJSON())}switch(typeof value){case"boolean":case"symbol":return value.toString();case"bigint":return BigInt(value).toString();case"number":return value.toString();case"string":return JSON.stringify(value);case"object":{const keys=Object.keys(value);keys.sort();return"{ "+keys.map(k=>`${stringify$1(k)}: ${stringify$1(value[k])}`).join(", ")+" }"}}return`[ COULD NOT SERIALIZE ]`}function isError(error,code){return error&&error.code===code}function isCallException(error){return isError(error,"CALL_EXCEPTION")}function makeError(message,code,info){{const details=[];if(info){if("message"in info||"code"in info||"name"in info){throw new Error(`value will overwrite populated values: ${stringify$1(info)}`)}for(const key in info){const value=info[key];details.push(key+"="+stringify$1(value))}}details.push(`code=${code}`);details.push(`version=${version}`);if(details.length){message+=" ("+details.join(", ")+")"}}let error;switch(code){case"INVALID_ARGUMENT":error=new TypeError(message);break;case"NUMERIC_FAULT":case"BUFFER_OVERRUN":error=new RangeError(message);break;default:error=new Error(message)}defineProperties(error,{code:code});if(info){Object.assign(error,info)}return error}function assert$1(check,message,code,info){if(!check){throw makeError(message,code,info)}}function assertArgument(check,message,name,value){assert$1(check,message,"INVALID_ARGUMENT",{argument:name,value:value})}function assertArgumentCount(count,expectedCount,message){if(message==null){message=""}if(message){message=": "+message}assert$1(count>=expectedCount,"missing arguemnt"+message,"MISSING_ARGUMENT",{count:count,expectedCount:expectedCount});assert$1(count<=expectedCount,"too many arguemnts"+message,"UNEXPECTED_ARGUMENT",{count:count,expectedCount:expectedCount})}const _normalizeForms=["NFD","NFC","NFKD","NFKC"].reduce((accum,form)=>{try{if("test".normalize(form)!=="test"){throw new Error("bad")}if(form==="NFD"){const check=String.fromCharCode(233).normalize("NFD");const expected=String.fromCharCode(101,769);if(check!==expected){throw new Error("broken")}}accum.push(form)}catch(error){}return accum},[]);function assertNormalize(form){assert$1(_normalizeForms.indexOf(form)>=0,"platform missing String.prototype.normalize","UNSUPPORTED_OPERATION",{operation:"String.prototype.normalize",info:{form:form}})}function assertPrivate(givenGuard,guard,className){if(className==null){className=""}if(givenGuard!==guard){let method=className,operation="new";if(className){method+=".";operation+=" "+className}assert$1(false,`private constructor; use ${method}from* methods`,"UNSUPPORTED_OPERATION",{operation:operation})}}function _getBytes(value,name,copy){if(value instanceof Uint8Array){if(copy){return new Uint8Array(value)}return value}if(typeof value==="string"&&value.match(/^0x([0-9a-f][0-9a-f])*$/i)){const result=new Uint8Array((value.length-2)/2);let offset=2;for(let i=0;i>4]+HexCharacters[v&15]}return result}function concat(datas){return"0x"+datas.map(d=>hexlify(d).substring(2)).join("")}function dataLength(data){if(isHexString(data,true)){return(data.length-2)/2}return getBytes(data).length}function dataSlice(data,start,end){const bytes=getBytes(data);if(end!=null&&end>bytes.length){assert$1(false,"cannot slice beyond data bounds","BUFFER_OVERRUN",{buffer:bytes,length:bytes.length,offset:end})}return hexlify(bytes.slice(start==null?0:start,end==null?bytes.length:end))}function stripZerosLeft(data){let bytes=hexlify(data).substring(2);while(bytes.startsWith("00")){bytes=bytes.substring(2)}return"0x"+bytes}function zeroPad(data,length,left){const bytes=getBytes(data);assert$1(length>=bytes.length,"padding exceeds data length","BUFFER_OVERRUN",{buffer:new Uint8Array(bytes),length:length,offset:length+1});const result=new Uint8Array(length);result.fill(0);if(left){result.set(bytes,length-bytes.length)}else{result.set(bytes,0)}return hexlify(result)}function zeroPadValue(data,length){return zeroPad(data,length,true)}function zeroPadBytes(data,length){return zeroPad(data,length,false)}const BN_0$a=BigInt(0);const BN_1$5=BigInt(1);const maxValue=9007199254740991;function fromTwos(_value,_width){const value=getUint(_value,"value");const width=BigInt(getNumber(_width,"width"));assert$1(value>>width===BN_0$a,"overflow","NUMERIC_FAULT",{operation:"fromTwos",fault:"overflow",value:_value});if(value>>width-BN_1$5){const mask=(BN_1$5<=-maxValue&&value<=maxValue,"overflow",name||"value",value);return BigInt(value);case"string":try{if(value===""){throw new Error("empty string")}if(value[0]==="-"&&value[1]!=="-"){return-BigInt(value.substring(1))}return BigInt(value)}catch(e){assertArgument(false,`invalid BigNumberish string: ${e.message}`,name||"value",value)}}assertArgument(false,"invalid BigNumberish value",name||"value",value)}function getUint(value,name){const result=getBigInt(value,name);assert$1(result>=BN_0$a,"unsigned value cannot be negative","NUMERIC_FAULT",{fault:"overflow",operation:"getUint",value:value});return result}const Nibbles$1="0123456789abcdef";function toBigInt(value){if(value instanceof Uint8Array){let result="0x0";for(const v of value){result+=Nibbles$1[v>>4];result+=Nibbles$1[v&15]}return BigInt(result)}return getBigInt(value)}function getNumber(value,name){switch(typeof value){case"bigint":assertArgument(value>=-maxValue&&value<=maxValue,"overflow",name||"value",value);return Number(value);case"number":assertArgument(Number.isInteger(value),"underflow",name||"value",value);assertArgument(value>=-maxValue&&value<=maxValue,"overflow",name||"value",value);return value;case"string":try{if(value===""){throw new Error("empty string")}return getNumber(BigInt(value),name)}catch(e){assertArgument(false,`invalid numeric string: ${e.message}`,name||"value",value)}}assertArgument(false,"invalid numeric value",name||"value",value)}function toNumber(value){return getNumber(toBigInt(value))}function toBeHex(_value,_width){const value=getUint(_value,"value");let result=value.toString(16);if(_width==null){if(result.length%2){result="0"+result}}else{const width=getNumber(_width,"width");assert$1(width*2>=result.length,`value exceeds width (${width} bits)`,"NUMERIC_FAULT",{operation:"toBeHex",fault:"overflow",value:_value});while(result.length>6!==2){break}i++}return i}if(reason==="OVERRUN"){return bytes.length-offset-1}return 0}function replaceFunc(reason,offset,bytes,output,badCodepoint){if(reason==="OVERLONG"){assertArgument(typeof badCodepoint==="number","invalid bad code point for replacement","badCodepoint",badCodepoint);output.push(badCodepoint);return 0}output.push(65533);return ignoreFunc(reason,offset,bytes,output,badCodepoint)}const Utf8ErrorFuncs=Object.freeze({error:errorFunc,ignore:ignoreFunc,replace:replaceFunc});function getUtf8CodePoints(_bytes,onError){if(onError==null){onError=Utf8ErrorFuncs.error}const bytes=getBytes(_bytes,"bytes");const result=[];let i=0;while(i>7===0){result.push(c);continue}let extraLength=null;let overlongMask=null;if((c&224)===192){extraLength=1;overlongMask=127}else if((c&240)===224){extraLength=2;overlongMask=2047}else if((c&248)===240){extraLength=3;overlongMask=65535}else{if((c&192)===128){i+=onError("UNEXPECTED_CONTINUE",i-1,bytes,result)}else{i+=onError("BAD_PREFIX",i-1,bytes,result)}continue}if(i-1+extraLength>=bytes.length){i+=onError("OVERRUN",i-1,bytes,result);continue}let res=c&(1<<8-extraLength-1)-1;for(let j=0;j1114111){i+=onError("OUT_OF_RANGE",i-1-extraLength,bytes,result,res);continue}if(res>=55296&&res<=57343){i+=onError("UTF16_SURROGATE",i-1-extraLength,bytes,result,res);continue}if(res<=overlongMask){i+=onError("OVERLONG",i-1-extraLength,bytes,result,res);continue}result.push(res)}return result}function toUtf8Bytes(str,form){if(form!=null){assertNormalize(form);str=str.normalize(form)}let result=[];for(let i=0;i>6|192);result.push(c&63|128)}else if((c&64512)==55296){i++;const c2=str.charCodeAt(i);assertArgument(i>18|240);result.push(pair>>12&63|128);result.push(pair>>6&63|128);result.push(pair&63|128)}else{result.push(c>>12|224);result.push(c>>6&63|128);result.push(c&63|128)}}return new Uint8Array(result)}function _toUtf8String(codePoints){return codePoints.map(codePoint=>{if(codePoint<=65535){return String.fromCharCode(codePoint)}codePoint-=65536;return String.fromCharCode((codePoint>>10&1023)+55296,(codePoint&1023)+56320)}).join("")}function toUtf8String(bytes,onError){return _toUtf8String(getUtf8CodePoints(bytes,onError))}function toUtf8CodePoints(str,form){return getUtf8CodePoints(toUtf8Bytes(str,form))}async function getUrl(req,_signal){const protocol=req.url.split(":")[0].toLowerCase();assert$1(protocol==="http"||protocol==="https",`unsupported protocol ${protocol}`,"UNSUPPORTED_OPERATION",{info:{protocol:protocol},operation:"request"});assert$1(protocol==="https"||!req.credentials||req.allowInsecureAuthentication,"insecure authorized connections unsupported","UNSUPPORTED_OPERATION",{operation:"request"});let signal=undefined;if(_signal){const controller=new AbortController;signal=controller.signal;_signal.addListener(()=>{controller.abort()})}const init={method:req.method,headers:new Headers(Array.from(req)),body:req.body||undefined,signal:signal};const resp=await fetch(req.url,init);const headers={};resp.headers.forEach((value,key)=>{headers[key.toLowerCase()]=value});const respBody=await resp.arrayBuffer();const body=respBody==null?null:new Uint8Array(respBody);return{statusCode:resp.status,statusMessage:resp.statusText,headers:headers,body:body}}const MAX_ATTEMPTS=12;const SLOT_INTERVAL=250;let getUrlFunc=getUrl;const reData=new RegExp("^data:([^;:]*)?(;base64)?,(.*)$","i");const reIpfs=new RegExp("^ipfs://(ipfs/)?(.*)$","i");let locked$5=false;async function dataGatewayFunc(url,signal){try{const match=url.match(reData);if(!match){throw new Error("invalid data")}return new FetchResponse(200,"OK",{"content-type":match[1]||"text/plain"},match[2]?decodeBase64(match[3]):unpercent(match[3]))}catch(error){return new FetchResponse(599,"BAD REQUEST (invalid data: URI)",{},null,new FetchRequest(url))}}function getIpfsGatewayFunc(baseUrl){async function gatewayIpfs(url,signal){try{const match=url.match(reIpfs);if(!match){throw new Error("invalid link")}return new FetchRequest(`${baseUrl}${match[2]}`)}catch(error){return new FetchResponse(599,"BAD REQUEST (invalid IPFS URI)",{},null,new FetchRequest(url))}}return gatewayIpfs}const Gateways={data:dataGatewayFunc,ipfs:getIpfsGatewayFunc("https://gateway.ipfs.io/ipfs/")};const fetchSignals=new WeakMap;class FetchCancelSignal{#listeners;#cancelled;constructor(request){this.#listeners=[];this.#cancelled=false;fetchSignals.set(request,()=>{if(this.#cancelled){return}this.#cancelled=true;for(const listener of this.#listeners){setTimeout(()=>{listener()},0)}this.#listeners=[]})}addListener(listener){assert$1(!this.#cancelled,"singal already cancelled","UNSUPPORTED_OPERATION",{operation:"fetchCancelSignal.addCancelListener"});this.#listeners.push(listener)}get cancelled(){return this.#cancelled}checkSignal(){assert$1(!this.cancelled,"cancelled","CANCELLED",{})}}function checkSignal(signal){if(signal==null){throw new Error("missing signal; should not happen")}signal.checkSignal();return signal}class FetchRequest{#allowInsecure;#gzip;#headers;#method;#timeout;#url;#body;#bodyType;#creds;#preflight;#process;#retry;#signal;#throttle;get url(){return this.#url}set url(url){this.#url=String(url)}get body(){if(this.#body==null){return null}return new Uint8Array(this.#body)}set body(body){if(body==null){this.#body=undefined;this.#bodyType=undefined}else if(typeof body==="string"){this.#body=toUtf8Bytes(body);this.#bodyType="text/plain"}else if(body instanceof Uint8Array){this.#body=body;this.#bodyType="application/octet-stream"}else if(typeof body==="object"){this.#body=toUtf8Bytes(JSON.stringify(body));this.#bodyType="application/json"}else{throw new Error("invalid body")}}hasBody(){return this.#body!=null}get method(){if(this.#method){return this.#method}if(this.hasBody()){return"POST"}return"GET"}set method(method){if(method==null){method=""}this.#method=String(method).toUpperCase()}get headers(){const headers=Object.assign({},this.#headers);if(this.#creds){headers["authorization"]=`Basic ${encodeBase64(toUtf8Bytes(this.#creds))}`}if(this.allowGzip){headers["accept-encoding"]="gzip"}if(headers["content-type"]==null&&this.#bodyType){headers["content-type"]=this.#bodyType}if(this.body){headers["content-length"]=String(this.body.length)}return headers}getHeader(key){return this.headers[key.toLowerCase()]}setHeader(key,value){this.#headers[String(key).toLowerCase()]=String(value)}clearHeaders(){this.#headers={}}[Symbol.iterator](){const headers=this.headers;const keys=Object.keys(headers);let index=0;return{next:()=>{if(index=0,"timeout must be non-zero","timeout",timeout);this.#timeout=timeout}get preflightFunc(){return this.#preflight||null}set preflightFunc(preflight){this.#preflight=preflight}get processFunc(){return this.#process||null}set processFunc(process){this.#process=process}get retryFunc(){return this.#retry||null}set retryFunc(retry){this.#retry=retry}constructor(url){this.#url=String(url);this.#allowInsecure=false;this.#gzip=true;this.#headers={};this.#method="";this.#timeout=3e5;this.#throttle={slotInterval:SLOT_INTERVAL,maxAttempts:MAX_ATTEMPTS}}toString(){return``}setThrottleParams(params){if(params.slotInterval!=null){this.#throttle.slotInterval=params.slotInterval}if(params.maxAttempts!=null){this.#throttle.maxAttempts=params.maxAttempts}}async#send(attempt,expires,delay,_request,_response){if(attempt>=this.#throttle.maxAttempts){return _response.makeServerError("exceeded maximum retry limit")}assert$1(getTime$2()<=expires,"timeout","TIMEOUT",{operation:"request.send",reason:"timeout",request:_request});if(delay>0){await wait(delay)}let req=this.clone();const scheme=(req.url.split(":")[0]||"").toLowerCase();if(scheme in Gateways){const result=await Gateways[scheme](req.url,checkSignal(_request.#signal));if(result instanceof FetchResponse){let response=result;if(this.processFunc){checkSignal(_request.#signal);try{response=await this.processFunc(req,response)}catch(error){if(error.throttle==null||typeof error.stall!=="number"){response.makeServerError("error in post-processing function",error).assertOk()}}}return response}req=result}if(this.preflightFunc){req=await this.preflightFunc(req)}const resp=await getUrlFunc(req,checkSignal(_request.#signal));let response=new FetchResponse(resp.statusCode,resp.statusMessage,resp.headers,resp.body,_request);if(response.statusCode===301||response.statusCode===302){try{const location=response.headers.location||"";return req.redirect(location).#send(attempt+1,expires,0,_request,response)}catch(error){}return response}else if(response.statusCode===429){if(this.retryFunc==null||await this.retryFunc(req,response,attempt)){const retryAfter=response.headers["retry-after"];let delay=this.#throttle.slotInterval*Math.trunc(Math.random()*Math.pow(2,attempt));if(typeof retryAfter==="string"&&retryAfter.match(/^[1-9][0-9]*$/)){delay=parseInt(retryAfter)}return req.clone().#send(attempt+1,expires,delay,_request,response)}}if(this.processFunc){checkSignal(_request.#signal);try{response=await this.processFunc(req,response)}catch(error){if(error.throttle==null||typeof error.stall!=="number"){response.makeServerError("error in post-processing function",error).assertOk()}let delay=this.#throttle.slotInterval*Math.trunc(Math.random()*Math.pow(2,attempt));if(error.stall>=0){delay=error.stall}return req.clone().#send(attempt+1,expires,delay,_request,response)}}return response}send(){assert$1(this.#signal==null,"request already sent","UNSUPPORTED_OPERATION",{operation:"fetchRequest.send"});this.#signal=new FetchCancelSignal(this);return this.#send(0,getTime$2()+this.timeout,0,this,new FetchResponse(0,"",{},null,this))}cancel(){assert$1(this.#signal!=null,"request has not been sent","UNSUPPORTED_OPERATION",{operation:"fetchRequest.cancel"});const signal=fetchSignals.get(this);if(!signal){throw new Error("missing signal; should not happen")}signal()}redirect(location){const current=this.url.split(":")[0].toLowerCase();const target=location.split(":")[0].toLowerCase();assert$1(this.method==="GET"&&(current!=="https"||target!=="http")&&location.match(/^https?:/),`unsupported redirect`,"UNSUPPORTED_OPERATION",{operation:`redirect(${this.method} ${JSON.stringify(this.url)} => ${JSON.stringify(location)})`});const req=new FetchRequest(location);req.method="GET";req.allowGzip=this.allowGzip;req.timeout=this.timeout;req.#headers=Object.assign({},this.#headers);if(this.#body){req.#body=new Uint8Array(this.#body)}req.#bodyType=this.#bodyType;return req}clone(){const clone=new FetchRequest(this.url);clone.#method=this.#method;if(this.#body){clone.#body=this.#body}clone.#bodyType=this.#bodyType;clone.#headers=Object.assign({},this.#headers);clone.#creds=this.#creds;if(this.allowGzip){clone.allowGzip=true}clone.timeout=this.timeout;if(this.allowInsecureAuthentication){clone.allowInsecureAuthentication=true}clone.#preflight=this.#preflight;clone.#process=this.#process;clone.#retry=this.#retry;return clone}static lockConfig(){locked$5=true}static getGateway(scheme){return Gateways[scheme.toLowerCase()]||null}static registerGateway(scheme,func){scheme=scheme.toLowerCase();if(scheme==="http"||scheme==="https"){throw new Error(`cannot intercept ${scheme}; use registerGetUrl`)}if(locked$5){throw new Error("gateways locked")}Gateways[scheme]=func}static registerGetUrl(getUrl){if(locked$5){throw new Error("gateways locked")}getUrlFunc=getUrl}static createDataGateway(){return dataGatewayFunc}static createIpfsGatewayFunc(baseUrl){return getIpfsGatewayFunc(baseUrl)}}class FetchResponse{#statusCode;#statusMessage;#headers;#body;#request;#error;toString(){return``}get statusCode(){return this.#statusCode}get statusMessage(){return this.#statusMessage}get headers(){return Object.assign({},this.#headers)}get body(){return this.#body==null?null:new Uint8Array(this.#body)}get bodyText(){try{return this.#body==null?"":toUtf8String(this.#body)}catch(error){assert$1(false,"response body is not valid UTF-8 data","UNSUPPORTED_OPERATION",{operation:"bodyText",info:{response:this}})}}get bodyJson(){try{return JSON.parse(this.bodyText)}catch(error){assert$1(false,"response body is not valid JSON","UNSUPPORTED_OPERATION",{operation:"bodyJson",info:{response:this}})}}[Symbol.iterator](){const headers=this.headers;const keys=Object.keys(headers);let index=0;return{next:()=>{if(index{accum[k.toLowerCase()]=String(headers[k]);return accum},{});this.#body=body==null?null:new Uint8Array(body);this.#request=request||null;this.#error={message:""}}makeServerError(message,error){let statusMessage;if(!message){message=`${this.statusCode} ${this.statusMessage}`;statusMessage=`CLIENT ESCALATED SERVER ERROR (${message})`}else{statusMessage=`CLIENT ESCALATED SERVER ERROR (${this.statusCode} ${this.statusMessage}; ${message})`}const response=new FetchResponse(599,statusMessage,this.headers,this.body,this.#request||undefined);response.#error={message:message,error:error};return response}throwThrottleError(message,stall){if(stall==null){stall=-1}else{assertArgument(Number.isInteger(stall)&&stall>=0,"invalid stall timeout","stall",stall)}const error=new Error(message||"throttling requests");defineProperties(error,{stall:stall,throttle:true});throw error}getHeader(key){return this.headers[key.toLowerCase()]}hasBody(){return this.#body!=null}get request(){return this.#request}ok(){return this.#error.message===""&&this.statusCode>=200&&this.statusCode<300}assertOk(){if(this.ok()){return}let{message,error}=this.#error;if(message===""){message=`server response ${this.statusCode} ${this.statusMessage}`}assert$1(false,message,"SERVER_ERROR",{request:this.request||"unknown request",response:this,error:error})}}function getTime$2(){return(new Date).getTime()}function unpercent(value){return toUtf8Bytes(value.replace(/%([0-9a-f][0-9a-f])/gi,(all,code)=>{return String.fromCharCode(parseInt(code,16))}))}function wait(delay){return new Promise(resolve=>setTimeout(resolve,delay))}const BN_N1=BigInt(-1);const BN_0$8=BigInt(0);const BN_1$4=BigInt(1);const BN_5=BigInt(5);const _guard$5={};let Zeros$1="0000";while(Zeros$1.length<80){Zeros$1+=Zeros$1}function getTens(decimals){let result=Zeros$1;while(result.length=-limit&&valBN_0$8){val=fromTwos(mask(val,width),width)}else{val=-fromTwos(mask(-val,width),width)}}else{const limit=BN_1$4<=0&&val{if(v[key]==null){return defaultValue}assertArgument(typeof v[key]===type,"invalid fixed format ("+key+" not "+type+")","format."+key,v[key]);return v[key]};signed=check("signed","boolean",signed);width=check("width","number",width);decimals=check("decimals","number",decimals)}assertArgument(width%8===0,"invalid FixedNumber width (not byte aligned)","format.width",width);assertArgument(decimals<=80,"invalid FixedNumber decimals (too large)","format.decimals",decimals);const name=(signed?"":"u")+"fixed"+String(width)+"x"+String(decimals);return{signed:signed,width:width,decimals:decimals,name:name}}function toString(val,decimals){let negative="";if(val0){b*=getTens(delta)}else if(delta<0){a*=getTens(-delta)}if(ab){return-1}return 0}eq(other){return this.cmp(other)===0}lt(other){return this.cmp(other)<0}lte(other){return this.cmp(other)<=0}gt(other){return this.cmp(other)>0}gte(other){return this.cmp(other)>=0}floor(){let val=this.#val;if(this.#valBN_0$8){val+=this.#tens-BN_1$4}val=this.#val/this.#tens*this.#tens;return this.#checkValue(val,"ceiling")}round(decimals){if(decimals==null){decimals=0}if(decimals>=this.decimals){return this}const delta=this.decimals-decimals;const bump=BN_5*getTens(delta-1);let value=this.value+bump;const tens=getTens(delta);value=value/tens*tens;checkValue(value,this.#format,"round");return new FixedNumber(_guard$5,value,this.#format)}isZero(){return this.#val===BN_0$8}isNegative(){return this.#val0){const tens=getTens(delta);assert$1(value%tens===BN_0$8,"value loses precision for format","NUMERIC_FAULT",{operation:"fromValue",fault:"underflow",value:_value});value/=tens}else if(delta<0){value*=getTens(-delta)}checkValue(value,format,"fromValue");return new FixedNumber(_guard$5,value,format)}static fromString(_value,_format){const match=_value.match(/^(-?)([0-9]*)\.?([0-9]*)$/);assertArgument(match&&match[2].length+match[3].length>0,"invalid FixedNumber string value","value",_value);const format=getFormat(_format);let whole=match[2]||"0",decimal=match[3]||"";while(decimal.length{assert$1(offset<=data.length,"data short segment too short","BUFFER_OVERRUN",{buffer:data,length:data.length,offset:offset})};if(data[offset]>=248){const lengthLength=data[offset]-247;checkOffset(offset+1+lengthLength);const length=unarrayifyInteger(data,offset+1,lengthLength);checkOffset(offset+1+lengthLength+length);return _decodeChildren(data,offset,offset+1+lengthLength,lengthLength+length)}else if(data[offset]>=192){const length=data[offset]-192;checkOffset(offset+1+length);return _decodeChildren(data,offset,offset+1,length)}else if(data[offset]>=184){const lengthLength=data[offset]-183;checkOffset(offset+1+lengthLength);const length=unarrayifyInteger(data,offset+1,lengthLength);checkOffset(offset+1+lengthLength+length);const result=hexlify(data.slice(offset+1+lengthLength,offset+1+lengthLength+length));return{consumed:1+lengthLength+length,result:result}}else if(data[offset]>=128){const length=data[offset]-128;checkOffset(offset+1+length);const result=hexlify(data.slice(offset+1,offset+1+length));return{consumed:1+length,result:result}}return{consumed:1,result:hexlifyByte(data[offset])}}function decodeRlp(_data){const data=getBytes(_data,"data");const decoded=_decode(data,0);assertArgument(decoded.consumed===data.length,"unexpected junk after rlp payload","data",_data);return decoded.result}function arrayifyInteger(value){const result=[];while(value){result.unshift(value&255);value>>=8}return result}function _encode(object){if(Array.isArray(object)){let payload=[];object.forEach(function(child){payload=payload.concat(_encode(child))});if(payload.length<=55){payload.unshift(192+payload.length);return payload}const length=arrayifyInteger(payload.length);length.unshift(247+length.length);return length.concat(payload)}const data=Array.prototype.slice.call(getBytes(object,"object"));if(data.length===1&&data[0]<=127){return data}else if(data.length<=55){data.unshift(128+data.length);return data}const length=arrayifyInteger(data.length);length.unshift(183+length.length);return length.concat(data)}const nibbles="0123456789abcdef";function encodeRlp(object){let result="0x";for(const v of _encode(object)){result+=nibbles[v>>4];result+=nibbles[v&15]}return result}const names=["wei","kwei","mwei","gwei","szabo","finney","ether"];function formatUnits(value,unit){let decimals=18;if(typeof unit==="string"){const index=names.indexOf(unit);assertArgument(index>=0,"invalid unit","unit",unit);decimals=3*index}else if(unit!=null){decimals=getNumber(unit,"unit")}return FixedNumber.fromValue(value,decimals,{decimals:decimals}).toString()}function parseUnits(value,unit){assertArgument(typeof value==="string","value must be a string","value",value);let decimals=18;if(typeof unit==="string"){const index=names.indexOf(unit);assertArgument(index>=0,"invalid unit","unit",unit);decimals=3*index}else if(unit!=null){decimals=getNumber(unit,"unit")}return FixedNumber.fromString(value,{decimals:decimals}).value}function formatEther(wei){return formatUnits(wei,18)}function parseEther(ether){return parseUnits(ether,18)}function uuidV4(randomBytes){const bytes=getBytes(randomBytes,"randomBytes");bytes[6]=bytes[6]&15|64;bytes[8]=bytes[8]&63|128;const value=hexlify(bytes);return[value.substring(2,10),value.substring(10,14),value.substring(14,18),value.substring(18,22),value.substring(22,34)].join("-")}const WordSize=32;const Padding=new Uint8Array(WordSize);const passProperties$1=["then"];const _guard$4={};function throwError(name,error){const wrapped=new Error(`deferred error during ABI decoding triggered accessing ${name}`);wrapped.error=error;throw wrapped}class Result extends Array{#names;constructor(...args){const guard=args[0];let items=args[1];let names=(args[2]||[]).slice();let wrap=true;if(guard!==_guard$4){items=args;names=[];wrap=false}super(items.length);items.forEach((item,index)=>{this[index]=item});const nameCounts=names.reduce((accum,name)=>{if(typeof name==="string"){accum.set(name,(accum.get(name)||0)+1)}return accum},new Map);this.#names=Object.freeze(items.map((item,index)=>{const name=names[index];if(name!=null&&nameCounts.get(name)===1){return name}return null}));if(!wrap){return}Object.freeze(this);return new Proxy(this,{get:(target,prop,receiver)=>{if(typeof prop==="string"){if(prop.match(/^[0-9]+$/)){const index=getNumber(prop,"%index");if(index<0||index>=this.length){throw new RangeError("out of result range")}const item=target[index];if(item instanceof Error){throwError(`index ${index}`,item)}return item}if(passProperties$1.indexOf(prop)>=0){return Reflect.get(target,prop,receiver)}const value=target[prop];if(value instanceof Function){return function(...args){return value.apply(this===receiver?target:this,args)}}else if(!(prop in target)){return target.getValue.apply(this===receiver?target:this,[prop])}}return Reflect.get(target,prop,receiver)}})}toArray(){const result=[];this.forEach((item,index)=>{if(item instanceof Error){throwError(`index ${index}`,item)}result.push(item)});return result}toObject(){return this.#names.reduce((accum,name,index)=>{assert$1(name!=null,"value at index ${ index } unnamed","UNSUPPORTED_OPERATION",{operation:"toObject()"});if(!(name in accum)){accum[name]=this.getValue(name)}return accum},{})}slice(start,end){if(start==null){start=0}if(start<0){start+=this.length;if(start<0){start=0}}if(end==null){end=this.length}if(end<0){end+=this.length;if(end<0){end=0}}if(end>this.length){end=this.length}const result=[],names=[];for(let i=start;i{this.#data[offset]=getValue$1(value)}}}class Reader{allowLoose;#data;#offset;constructor(data,allowLoose){defineProperties(this,{allowLoose:!!allowLoose});this.#data=getBytesCopy(data);this.#offset=0}get data(){return hexlify(this.#data)}get dataLength(){return this.#data.length}get consumed(){return this.#offset}get bytes(){return new Uint8Array(this.#data)}#peekBytes(offset,length,loose){let alignedLength=Math.ceil(length/WordSize)*WordSize;if(this.#offset+alignedLength>this.#data.length){if(this.allowLoose&&loose&&this.#offset+length<=this.#data.length){alignedLength=length}else{assert$1(false,"data out-of-bounds","BUFFER_OVERRUN",{buffer:getBytesCopy(this.#data),length:this.#data.length,offset:this.#offset+alignedLength})}}return this.#data.slice(this.#offset,this.#offset+alignedLength)}subReader(offset){return new Reader(this.#data.slice(this.#offset+offset),this.allowLoose)}readBytes(length,loose){let bytes=this.#peekBytes(0,length,!!loose);this.#offset+=bytes.length;return bytes.slice(0,length)}readValue(){return toBigInt(this.readBytes(WordSize))}readIndex(){return toNumber(this.readBytes(WordSize))}}function number(n){if(!Number.isSafeInteger(n)||n<0)throw new Error(`Wrong positive integer: ${n}`)}function bool(b){if(typeof b!=="boolean")throw new Error(`Expected boolean, not ${b}`)}function bytes(b,...lengths){if(!(b instanceof Uint8Array))throw new TypeError("Expected Uint8Array");if(lengths.length>0&&!lengths.includes(b.length))throw new TypeError(`Expected Uint8Array of length ${lengths}, not of length=${b.length}`)}function hash(hash){if(typeof hash!=="function"||typeof hash.create!=="function")throw new Error("Hash should be wrapped by utils.wrapConstructor");number(hash.outputLen);number(hash.blockLen)}function exists(instance,checkFinished=true){if(instance.destroyed)throw new Error("Hash instance has been destroyed");if(checkFinished&&instance.finished)throw new Error("Hash#digest() has already been called")}function output(out,instance){bytes(out);const min=instance.outputLen;if(out.lengthnew Uint8Array(arr.buffer,arr.byteOffset,arr.byteLength);const u32=arr=>new Uint32Array(arr.buffer,arr.byteOffset,Math.floor(arr.byteLength/4));const createView=arr=>new DataView(arr.buffer,arr.byteOffset,arr.byteLength);const rotr=(word,shift)=>word<<32-shift|word>>>shift;const isLE=new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68;if(!isLE)throw new Error("Non little-endian hardware is not supported");const hexes$1=Array.from({length:256},(v,i)=>i.toString(16).padStart(2,"0"));function bytesToHex$1(uint8a){if(!(uint8a instanceof Uint8Array))throw new Error("Uint8Array expected");let hex="";for(let i=0;i{};async function asyncLoop(iters,tick,cb){let ts=Date.now();for(let i=0;i=0&&diffa instanceof Uint8Array))throw new Error("Uint8Array list expected");if(arrays.length===1)return arrays[0];const length=arrays.reduce((a,arr)=>a+arr.length,0);const result=new Uint8Array(length);for(let i=0,pad=0;iObject.prototype.toString.call(obj)==="[object Object]"&&obj.constructor===Object;function checkOpts(defaults,opts){if(opts!==undefined&&(typeof opts!=="object"||!isPlainObject(opts)))throw new TypeError("Options should be object or undefined");const merged=Object.assign(defaults,opts);return merged}function wrapConstructor(hashConstructor){const hashC=message=>hashConstructor().update(toBytes(message)).digest();const tmp=hashConstructor();hashC.outputLen=tmp.outputLen;hashC.blockLen=tmp.blockLen;hashC.create=()=>hashConstructor();return hashC}function wrapConstructorWithOpts(hashCons){const hashC=(msg,opts)=>hashCons(opts).update(toBytes(msg)).digest();const tmp=hashCons({});hashC.outputLen=tmp.outputLen;hashC.blockLen=tmp.blockLen;hashC.create=opts=>hashCons(opts);return hashC}function randomBytes$2(bytesLength=32){if(crypto$2.web){return crypto$2.web.getRandomValues(new Uint8Array(bytesLength))}else if(crypto$2.node){return new Uint8Array(crypto$2.node.randomBytes(bytesLength).buffer)}else{throw new Error("The environment doesn't have randomBytes function")}}class HMAC extends Hash{constructor(hash,_key){super();this.finished=false;this.destroyed=false;assert.hash(hash);const key=toBytes(_key);this.iHash=hash.create();if(!(this.iHash instanceof Hash))throw new TypeError("Expected instance of class which extends utils.Hash");const blockLen=this.blockLen=this.iHash.blockLen;this.outputLen=this.iHash.outputLen;const pad=new Uint8Array(blockLen);pad.set(key.length>this.iHash.blockLen?hash.create().update(key).digest():key);for(let i=0;inew HMAC(hash,key).update(message).digest();hmac.create=(hash,key)=>new HMAC(hash,key);function pbkdf2Init(hash,_password,_salt,_opts){assert.hash(hash);const opts=checkOpts({dkLen:32,asyncTick:10},_opts);const{c,dkLen,asyncTick}=opts;assert.number(c);assert.number(dkLen);assert.number(asyncTick);if(c<1)throw new Error("PBKDF2: iterations (c) should be >= 1");const password=toBytes(_password);const salt=toBytes(_salt);const DK=new Uint8Array(dkLen);const PRF=hmac.create(hash,password);const PRFSalt=PRF._cloneInto().update(salt);return{c:c,dkLen:dkLen,asyncTick:asyncTick,DK:DK,PRF:PRF,PRFSalt:PRFSalt}}function pbkdf2Output(PRF,PRFSalt,DK,prfW,u){PRF.destroy();PRFSalt.destroy();if(prfW)prfW.destroy();u.fill(0);return DK}function pbkdf2$1(hash,password,salt,opts){const{c,dkLen,DK,PRF,PRFSalt}=pbkdf2Init(hash,password,salt,opts);let prfW;const arr=new Uint8Array(4);const view=createView(arr);const u=new Uint8Array(PRF.outputLen);for(let ti=1,pos=0;pos{PRF._cloneInto(prfW).update(u).digestInto(u);for(let i=0;i>_32n&_u32_max);const wl=Number(value&_u32_max);const h=isLE?4:0;const l=isLE?0:4;view.setUint32(byteOffset+h,wh,isLE);view.setUint32(byteOffset+l,wl,isLE)}class SHA2 extends Hash{constructor(blockLen,outputLen,padOffset,isLE){super();this.blockLen=blockLen;this.outputLen=outputLen;this.padOffset=padOffset;this.isLE=isLE;this.finished=false;this.length=0;this.pos=0;this.destroyed=false;this.buffer=new Uint8Array(blockLen);this.view=createView(this.buffer)}update(data){assert.exists(this);const{view,buffer,blockLen}=this;data=toBytes(data);const len=data.length;for(let pos=0;posblockLen-pos){this.process(view,0);pos=0}for(let i=pos;ioview.setUint32(4*i,v,isLE))}digest(){const{buffer,outputLen}=this;this.digestInto(buffer);const res=buffer.slice(0,outputLen);this.destroy();return res}_cloneInto(to){to||(to=new this.constructor);to.set(...this.get());const{blockLen,buffer,length,finished,destroyed,pos}=this;to.length=length;to.pos=pos;to.finished=finished;to.destroyed=destroyed;if(length%blockLen)to.buffer.set(buffer);return to}}const Chi=(a,b,c)=>a&b^~a&c;const Maj=(a,b,c)=>a&b^a&c^b&c;const SHA256_K=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]);const IV=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]);const SHA256_W=new Uint32Array(64);class SHA256 extends SHA2{constructor(){super(64,32,8,false);this.A=IV[0]|0;this.B=IV[1]|0;this.C=IV[2]|0;this.D=IV[3]|0;this.E=IV[4]|0;this.F=IV[5]|0;this.G=IV[6]|0;this.H=IV[7]|0}get(){const{A,B,C,D,E,F,G,H}=this;return[A,B,C,D,E,F,G,H]}set(A,B,C,D,E,F,G,H){this.A=A|0;this.B=B|0;this.C=C|0;this.D=D|0;this.E=E|0;this.F=F|0;this.G=G|0;this.H=H|0}process(view,offset){for(let i=0;i<16;i++,offset+=4)SHA256_W[i]=view.getUint32(offset,false);for(let i=16;i<64;i++){const W15=SHA256_W[i-15];const W2=SHA256_W[i-2];const s0=rotr(W15,7)^rotr(W15,18)^W15>>>3;const s1=rotr(W2,17)^rotr(W2,19)^W2>>>10;SHA256_W[i]=s1+SHA256_W[i-7]+s0+SHA256_W[i-16]|0}let{A,B,C,D,E,F,G,H}=this;for(let i=0;i<64;i++){const sigma1=rotr(E,6)^rotr(E,11)^rotr(E,25);const T1=H+sigma1+Chi(E,F,G)+SHA256_K[i]+SHA256_W[i]|0;const sigma0=rotr(A,2)^rotr(A,13)^rotr(A,22);const T2=sigma0+Maj(A,B,C)|0;H=G;G=F;F=E;E=D+T1|0;D=C;C=B;B=A;A=T1+T2|0}A=A+this.A|0;B=B+this.B|0;C=C+this.C|0;D=D+this.D|0;E=E+this.E|0;F=F+this.F|0;G=G+this.G|0;H=H+this.H|0;this.set(A,B,C,D,E,F,G,H)}roundClean(){SHA256_W.fill(0)}destroy(){this.set(0,0,0,0,0,0,0,0);this.buffer.fill(0)}}const sha256$1=wrapConstructor(()=>new SHA256);const U32_MASK64=BigInt(2**32-1);const _32n=BigInt(32);function fromBig(n,le=false){if(le)return{h:Number(n&U32_MASK64),l:Number(n>>_32n&U32_MASK64)};return{h:Number(n>>_32n&U32_MASK64)|0,l:Number(n&U32_MASK64)|0}}function split(lst,le=false){let Ah=new Uint32Array(lst.length);let Al=new Uint32Array(lst.length);for(let i=0;iBigInt(h>>>0)<<_32n|BigInt(l>>>0);const shrSH=(h,l,s)=>h>>>s;const shrSL=(h,l,s)=>h<<32-s|l>>>s;const rotrSH=(h,l,s)=>h>>>s|l<<32-s;const rotrSL=(h,l,s)=>h<<32-s|l>>>s;const rotrBH=(h,l,s)=>h<<64-s|l>>>s-32;const rotrBL=(h,l,s)=>h>>>s-32|l<<64-s;const rotr32H=(h,l)=>l;const rotr32L=(h,l)=>h;const rotlSH=(h,l,s)=>h<>>32-s;const rotlSL=(h,l,s)=>l<>>32-s;const rotlBH=(h,l,s)=>l<>>64-s;const rotlBL=(h,l,s)=>h<>>64-s;function add(Ah,Al,Bh,Bl){const l=(Al>>>0)+(Bl>>>0);return{h:Ah+Bh+(l/2**32|0)|0,l:l|0}}const add3L=(Al,Bl,Cl)=>(Al>>>0)+(Bl>>>0)+(Cl>>>0);const add3H=(low,Ah,Bh,Ch)=>Ah+Bh+Ch+(low/2**32|0)|0;const add4L=(Al,Bl,Cl,Dl)=>(Al>>>0)+(Bl>>>0)+(Cl>>>0)+(Dl>>>0);const add4H=(low,Ah,Bh,Ch,Dh)=>Ah+Bh+Ch+Dh+(low/2**32|0)|0;const add5L=(Al,Bl,Cl,Dl,El)=>(Al>>>0)+(Bl>>>0)+(Cl>>>0)+(Dl>>>0)+(El>>>0);const add5H=(low,Ah,Bh,Ch,Dh,Eh)=>Ah+Bh+Ch+Dh+Eh+(low/2**32|0)|0;const u64={fromBig:fromBig,split:split,toBig:toBig,shrSH:shrSH,shrSL:shrSL,rotrSH:rotrSH,rotrSL:rotrSL,rotrBH:rotrBH,rotrBL:rotrBL,rotr32H:rotr32H,rotr32L:rotr32L,rotlSH:rotlSH,rotlSL:rotlSL,rotlBH:rotlBH,rotlBL:rotlBL,add:add,add3L:add3L,add3H:add3H,add4L:add4L,add4H:add4H,add5H:add5H,add5L:add5L};const[SHA512_Kh,SHA512_Kl]=u64.split(["0x428a2f98d728ae22","0x7137449123ef65cd","0xb5c0fbcfec4d3b2f","0xe9b5dba58189dbbc","0x3956c25bf348b538","0x59f111f1b605d019","0x923f82a4af194f9b","0xab1c5ed5da6d8118","0xd807aa98a3030242","0x12835b0145706fbe","0x243185be4ee4b28c","0x550c7dc3d5ffb4e2","0x72be5d74f27b896f","0x80deb1fe3b1696b1","0x9bdc06a725c71235","0xc19bf174cf692694","0xe49b69c19ef14ad2","0xefbe4786384f25e3","0x0fc19dc68b8cd5b5","0x240ca1cc77ac9c65","0x2de92c6f592b0275","0x4a7484aa6ea6e483","0x5cb0a9dcbd41fbd4","0x76f988da831153b5","0x983e5152ee66dfab","0xa831c66d2db43210","0xb00327c898fb213f","0xbf597fc7beef0ee4","0xc6e00bf33da88fc2","0xd5a79147930aa725","0x06ca6351e003826f","0x142929670a0e6e70","0x27b70a8546d22ffc","0x2e1b21385c26c926","0x4d2c6dfc5ac42aed","0x53380d139d95b3df","0x650a73548baf63de","0x766a0abb3c77b2a8","0x81c2c92e47edaee6","0x92722c851482353b","0xa2bfe8a14cf10364","0xa81a664bbc423001","0xc24b8b70d0f89791","0xc76c51a30654be30","0xd192e819d6ef5218","0xd69906245565a910","0xf40e35855771202a","0x106aa07032bbd1b8","0x19a4c116b8d2d0c8","0x1e376c085141ab53","0x2748774cdf8eeb99","0x34b0bcb5e19b48a8","0x391c0cb3c5c95a63","0x4ed8aa4ae3418acb","0x5b9cca4f7763e373","0x682e6ff3d6b2b8a3","0x748f82ee5defb2fc","0x78a5636f43172f60","0x84c87814a1f0ab72","0x8cc702081a6439ec","0x90befffa23631e28","0xa4506cebde82bde9","0xbef9a3f7b2c67915","0xc67178f2e372532b","0xca273eceea26619c","0xd186b8c721c0c207","0xeada7dd6cde0eb1e","0xf57d4f7fee6ed178","0x06f067aa72176fba","0x0a637dc5a2c898a6","0x113f9804bef90dae","0x1b710b35131c471b","0x28db77f523047d84","0x32caab7b40c72493","0x3c9ebe0a15c9bebc","0x431d67c49c100d4c","0x4cc5d4becb3e42b6","0x597f299cfc657e2a","0x5fcb6fab3ad6faec","0x6c44198c4a475817"].map(n=>BigInt(n)));const SHA512_W_H=new Uint32Array(80);const SHA512_W_L=new Uint32Array(80);class SHA512 extends SHA2{constructor(){super(128,64,16,false);this.Ah=1779033703|0;this.Al=4089235720|0;this.Bh=3144134277|0;this.Bl=2227873595|0;this.Ch=1013904242|0;this.Cl=4271175723|0;this.Dh=2773480762|0;this.Dl=1595750129|0;this.Eh=1359893119|0;this.El=2917565137|0;this.Fh=2600822924|0;this.Fl=725511199|0;this.Gh=528734635|0;this.Gl=4215389547|0;this.Hh=1541459225|0;this.Hl=327033209|0}get(){const{Ah,Al,Bh,Bl,Ch,Cl,Dh,Dl,Eh,El,Fh,Fl,Gh,Gl,Hh,Hl}=this;return[Ah,Al,Bh,Bl,Ch,Cl,Dh,Dl,Eh,El,Fh,Fl,Gh,Gl,Hh,Hl]}set(Ah,Al,Bh,Bl,Ch,Cl,Dh,Dl,Eh,El,Fh,Fl,Gh,Gl,Hh,Hl){this.Ah=Ah|0;this.Al=Al|0;this.Bh=Bh|0;this.Bl=Bl|0;this.Ch=Ch|0;this.Cl=Cl|0;this.Dh=Dh|0;this.Dl=Dl|0;this.Eh=Eh|0;this.El=El|0;this.Fh=Fh|0;this.Fl=Fl|0;this.Gh=Gh|0;this.Gl=Gl|0;this.Hh=Hh|0;this.Hl=Hl|0}process(view,offset){for(let i=0;i<16;i++,offset+=4){SHA512_W_H[i]=view.getUint32(offset);SHA512_W_L[i]=view.getUint32(offset+=4)}for(let i=16;i<80;i++){const W15h=SHA512_W_H[i-15]|0;const W15l=SHA512_W_L[i-15]|0;const s0h=u64.rotrSH(W15h,W15l,1)^u64.rotrSH(W15h,W15l,8)^u64.shrSH(W15h,W15l,7);const s0l=u64.rotrSL(W15h,W15l,1)^u64.rotrSL(W15h,W15l,8)^u64.shrSL(W15h,W15l,7);const W2h=SHA512_W_H[i-2]|0;const W2l=SHA512_W_L[i-2]|0;const s1h=u64.rotrSH(W2h,W2l,19)^u64.rotrBH(W2h,W2l,61)^u64.shrSH(W2h,W2l,6);const s1l=u64.rotrSL(W2h,W2l,19)^u64.rotrBL(W2h,W2l,61)^u64.shrSL(W2h,W2l,6);const SUMl=u64.add4L(s0l,s1l,SHA512_W_L[i-7],SHA512_W_L[i-16]);const SUMh=u64.add4H(SUMl,s0h,s1h,SHA512_W_H[i-7],SHA512_W_H[i-16]);SHA512_W_H[i]=SUMh|0;SHA512_W_L[i]=SUMl|0}let{Ah,Al,Bh,Bl,Ch,Cl,Dh,Dl,Eh,El,Fh,Fl,Gh,Gl,Hh,Hl}=this;for(let i=0;i<80;i++){const sigma1h=u64.rotrSH(Eh,El,14)^u64.rotrSH(Eh,El,18)^u64.rotrBH(Eh,El,41);const sigma1l=u64.rotrSL(Eh,El,14)^u64.rotrSL(Eh,El,18)^u64.rotrBL(Eh,El,41);const CHIh=Eh&Fh^~Eh&Gh;const CHIl=El&Fl^~El&Gl;const T1ll=u64.add5L(Hl,sigma1l,CHIl,SHA512_Kl[i],SHA512_W_L[i]);const T1h=u64.add5H(T1ll,Hh,sigma1h,CHIh,SHA512_Kh[i],SHA512_W_H[i]);const T1l=T1ll|0;const sigma0h=u64.rotrSH(Ah,Al,28)^u64.rotrBH(Ah,Al,34)^u64.rotrBH(Ah,Al,39);const sigma0l=u64.rotrSL(Ah,Al,28)^u64.rotrBL(Ah,Al,34)^u64.rotrBL(Ah,Al,39);const MAJh=Ah&Bh^Ah&Ch^Bh&Ch;const MAJl=Al&Bl^Al&Cl^Bl&Cl;Hh=Gh|0;Hl=Gl|0;Gh=Fh|0;Gl=Fl|0;Fh=Eh|0;Fl=El|0;({h:Eh,l:El}=u64.add(Dh|0,Dl|0,T1h|0,T1l|0));Dh=Ch|0;Dl=Cl|0;Ch=Bh|0;Cl=Bl|0;Bh=Ah|0;Bl=Al|0;const All=u64.add3L(T1l,sigma0l,MAJl);Ah=u64.add3H(All,T1h,sigma0h,MAJh);Al=All|0}({h:Ah,l:Al}=u64.add(this.Ah|0,this.Al|0,Ah|0,Al|0));({h:Bh,l:Bl}=u64.add(this.Bh|0,this.Bl|0,Bh|0,Bl|0));({h:Ch,l:Cl}=u64.add(this.Ch|0,this.Cl|0,Ch|0,Cl|0));({h:Dh,l:Dl}=u64.add(this.Dh|0,this.Dl|0,Dh|0,Dl|0));({h:Eh,l:El}=u64.add(this.Eh|0,this.El|0,Eh|0,El|0));({h:Fh,l:Fl}=u64.add(this.Fh|0,this.Fl|0,Fh|0,Fl|0));({h:Gh,l:Gl}=u64.add(this.Gh|0,this.Gl|0,Gh|0,Gl|0));({h:Hh,l:Hl}=u64.add(this.Hh|0,this.Hl|0,Hh|0,Hl|0));this.set(Ah,Al,Bh,Bl,Ch,Cl,Dh,Dl,Eh,El,Fh,Fl,Gh,Gl,Hh,Hl)}roundClean(){SHA512_W_H.fill(0);SHA512_W_L.fill(0)}destroy(){this.buffer.fill(0);this.set(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)}}class SHA512_256 extends SHA512{constructor(){super();this.Ah=573645204|0;this.Al=4230739756|0;this.Bh=2673172387|0;this.Bl=3360449730|0;this.Ch=596883563|0;this.Cl=1867755857|0;this.Dh=2520282905|0;this.Dl=1497426621|0;this.Eh=2519219938|0;this.El=2827943907|0;this.Fh=3193839141|0;this.Fl=1401305490|0;this.Gh=721525244|0;this.Gl=746961066|0;this.Hh=246885852|0;this.Hl=2177182882|0;this.outputLen=32}}class SHA384 extends SHA512{constructor(){super();this.Ah=3418070365|0;this.Al=3238371032|0;this.Bh=1654270250|0;this.Bl=914150663|0;this.Ch=2438529370|0;this.Cl=812702999|0;this.Dh=355462360|0;this.Dl=4144912697|0;this.Eh=1731405415|0;this.El=4290775857|0;this.Fh=2394180231|0;this.Fl=1750603025|0;this.Gh=3675008525|0;this.Gl=1694076839|0;this.Hh=1203062813|0;this.Hl=3204075428|0;this.outputLen=48}}const sha512$1=wrapConstructor(()=>new SHA512);const sha512_256=wrapConstructor(()=>new SHA512_256);const sha384=wrapConstructor(()=>new SHA384);function getGlobal$1(){if(typeof self!=="undefined"){return self}if(typeof window!=="undefined"){return window}if(typeof global!=="undefined"){return global}throw new Error("unable to locate global object")}const anyGlobal=getGlobal$1();const crypto$1=anyGlobal.crypto||anyGlobal.msCrypto;function createHash(algo){switch(algo){case"sha256":return sha256$1.create();case"sha512":return sha512$1.create()}assertArgument(false,"invalid hashing algorithm name","algorithm",algo)}function createHmac(_algo,key){const algo={sha256:sha256$1,sha512:sha512$1}[_algo];assertArgument(algo!=null,"invalid hmac algorithm","algorithm",_algo);return hmac.create(algo,key)}function pbkdf2Sync(password,salt,iterations,keylen,_algo){const algo={sha256:sha256$1,sha512:sha512$1}[_algo];assertArgument(algo!=null,"invalid pbkdf2 algorithm","algorithm",_algo);return pbkdf2$1(algo,password,salt,{c:iterations,dkLen:keylen})}function randomBytes$1(length){assert$1(crypto$1!=null,"platform does not support secure random numbers","UNSUPPORTED_OPERATION",{operation:"randomBytes"});assertArgument(Number.isInteger(length)&&length>0&&length<=1024,"invalid length","length",length);const result=new Uint8Array(length);crypto$1.getRandomValues(result);return result}let locked$4=false;const _computeHmac=function(algorithm,key,data){return createHmac(algorithm,key).update(data).digest()};let __computeHmac=_computeHmac;function computeHmac(algorithm,_key,_data){const key=getBytes(_key,"key");const data=getBytes(_data,"data");return hexlify(__computeHmac(algorithm,key,data))}computeHmac._=_computeHmac;computeHmac.lock=function(){locked$4=true};computeHmac.register=function(func){if(locked$4){throw new Error("computeHmac is locked")}__computeHmac=func};Object.freeze(computeHmac);const[SHA3_PI,SHA3_ROTL,_SHA3_IOTA]=[[],[],[]];const _0n$1=BigInt(0);const _1n$1=BigInt(1);const _2n$1=BigInt(2);const _7n=BigInt(7);const _256n=BigInt(256);const _0x71n=BigInt(113);for(let round=0,R=_1n$1,x=1,y=0;round<24;round++){[x,y]=[y,(2*x+3*y)%5];SHA3_PI.push(2*(5*y+x));SHA3_ROTL.push((round+1)*(round+2)/2%64);let t=_0n$1;for(let j=0;j<7;j++){R=(R<<_1n$1^(R>>_7n)*_0x71n)%_256n;if(R&_2n$1)t^=_1n$1<<(_1n$1<s>32?u64.rotlBH(h,l,s):u64.rotlSH(h,l,s);const rotlL=(h,l,s)=>s>32?u64.rotlBL(h,l,s):u64.rotlSL(h,l,s);function keccakP(s,rounds=24){const B=new Uint32Array(5*2);for(let round=24-rounds;round<24;round++){for(let x=0;x<10;x++)B[x]=s[x]^s[x+10]^s[x+20]^s[x+30]^s[x+40];for(let x=0;x<10;x+=2){const idx1=(x+8)%10;const idx0=(x+2)%10;const B0=B[idx0];const B1=B[idx0+1];const Th=rotlH(B0,B1,1)^B[idx1];const Tl=rotlL(B0,B1,1)^B[idx1+1];for(let y=0;y<50;y+=10){s[x+y]^=Th;s[x+y+1]^=Tl}}let curH=s[2];let curL=s[3];for(let t=0;t<24;t++){const shift=SHA3_ROTL[t];const Th=rotlH(curH,curL,shift);const Tl=rotlL(curH,curL,shift);const PI=SHA3_PI[t];curH=s[PI];curL=s[PI+1];s[PI]=Th;s[PI+1]=Tl}for(let y=0;y<50;y+=10){for(let x=0;x<10;x++)B[x]=s[y+x];for(let x=0;x<10;x++)s[y+x]^=~B[(x+2)%10]&B[(x+4)%10]}s[0]^=SHA3_IOTA_H[round];s[1]^=SHA3_IOTA_L[round]}B.fill(0)}class Keccak extends Hash{constructor(blockLen,suffix,outputLen,enableXOF=false,rounds=24){super();this.blockLen=blockLen;this.suffix=suffix;this.outputLen=outputLen;this.enableXOF=enableXOF;this.rounds=rounds;this.pos=0;this.posOut=0;this.finished=false;this.destroyed=false;assert.number(outputLen);if(0>=this.blockLen||this.blockLen>=200)throw new Error("Sha3 supports only keccak-f1600 function");this.state=new Uint8Array(200);this.state32=u32(this.state)}keccak(){keccakP(this.state32,this.rounds);this.posOut=0;this.pos=0}update(data){assert.exists(this);const{blockLen,state}=this;data=toBytes(data);const len=data.length;for(let pos=0;pos=blockLen)this.keccak();const take=Math.min(blockLen-this.posOut,len-pos);out.set(bufferOut.subarray(this.posOut,this.posOut+take),pos);this.posOut+=take;pos+=take}return out}xofInto(out){if(!this.enableXOF)throw new Error("XOF is not possible for this instance");return this.writeInto(out)}xof(bytes){assert.number(bytes);return this.xofInto(new Uint8Array(bytes))}digestInto(out){assert.output(out,this);if(this.finished)throw new Error("digest() was already called");this.writeInto(out);this.destroy();return out}digest(){return this.digestInto(new Uint8Array(this.outputLen))}destroy(){this.destroyed=true;this.state.fill(0)}_cloneInto(to){const{blockLen,suffix,outputLen,rounds,enableXOF}=this;to||(to=new Keccak(blockLen,suffix,outputLen,enableXOF,rounds));to.state32.set(this.state32);to.pos=this.pos;to.posOut=this.posOut;to.finished=this.finished;to.rounds=rounds;to.suffix=suffix;to.outputLen=outputLen;to.enableXOF=enableXOF;to.destroyed=this.destroyed;return to}}const gen=(suffix,blockLen,outputLen)=>wrapConstructor(()=>new Keccak(blockLen,suffix,outputLen));const sha3_224=gen(6,144,224/8);const sha3_256=gen(6,136,256/8);const sha3_384=gen(6,104,384/8);const sha3_512=gen(6,72,512/8);const keccak_224=gen(1,144,224/8);const keccak_256=gen(1,136,256/8);const keccak_384=gen(1,104,384/8);const keccak_512=gen(1,72,512/8);const genShake=(suffix,blockLen,outputLen)=>wrapConstructorWithOpts((opts={})=>new Keccak(blockLen,suffix,opts.dkLen===undefined?outputLen:opts.dkLen,true));const shake128=genShake(31,168,128/8);const shake256=genShake(31,136,256/8);let locked$3=false;const _keccak256=function(data){return keccak_256(data)};let __keccak256=_keccak256;function keccak256(_data){const data=getBytes(_data,"data");return hexlify(__keccak256(data))}keccak256._=_keccak256;keccak256.lock=function(){locked$3=true};keccak256.register=function(func){if(locked$3){throw new TypeError("keccak256 is locked")}__keccak256=func};Object.freeze(keccak256);const Rho=new Uint8Array([7,4,13,1,10,6,15,3,12,0,9,5,2,14,11,8]);const Id=Uint8Array.from({length:16},(_,i)=>i);const Pi=Id.map(i=>(9*i+5)%16);let idxL=[Id];let idxR=[Pi];for(let i=0;i<4;i++)for(let j of[idxL,idxR])j.push(j[i].map(k=>Rho[k]));const shifts=[[11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8],[12,13,11,15,6,9,9,7,12,15,11,13,7,8,7,7],[13,15,14,11,7,7,6,8,13,14,13,12,5,5,6,9],[14,11,12,14,8,6,5,5,15,12,15,14,9,9,8,6],[15,12,13,13,9,5,8,6,14,11,12,11,8,6,5,5]].map(i=>new Uint8Array(i));const shiftsL=idxL.map((idx,i)=>idx.map(j=>shifts[i][j]));const shiftsR=idxR.map((idx,i)=>idx.map(j=>shifts[i][j]));const Kl=new Uint32Array([0,1518500249,1859775393,2400959708,2840853838]);const Kr=new Uint32Array([1352829926,1548603684,1836072691,2053994217,0]);const rotl$1=(word,shift)=>word<>>32-shift;function f(group,x,y,z){if(group===0)return x^y^z;else if(group===1)return x&y|~x&z;else if(group===2)return(x|~y)^z;else if(group===3)return x&z|y&~z;else return x^(y|~z)}const BUF=new Uint32Array(16);class RIPEMD160 extends SHA2{constructor(){super(64,20,8,true);this.h0=1732584193|0;this.h1=4023233417|0;this.h2=2562383102|0;this.h3=271733878|0;this.h4=3285377520|0}get(){const{h0,h1,h2,h3,h4}=this;return[h0,h1,h2,h3,h4]}set(h0,h1,h2,h3,h4){this.h0=h0|0;this.h1=h1|0;this.h2=h2|0;this.h3=h3|0;this.h4=h4|0}process(view,offset){for(let i=0;i<16;i++,offset+=4)BUF[i]=view.getUint32(offset,true);let al=this.h0|0,ar=al,bl=this.h1|0,br=bl,cl=this.h2|0,cr=cl,dl=this.h3|0,dr=dl,el=this.h4|0,er=el;for(let group=0;group<5;group++){const rGroup=4-group;const hbl=Kl[group],hbr=Kr[group];const rl=idxL[group],rr=idxR[group];const sl=shiftsL[group],sr=shiftsR[group];for(let i=0;i<16;i++){const tl=rotl$1(al+f(group,bl,cl,dl)+BUF[rl[i]]+hbl,sl[i])+el|0;al=el,el=dl,dl=rotl$1(cl,10)|0,cl=bl,bl=tl}for(let i=0;i<16;i++){const tr=rotl$1(ar+f(rGroup,br,cr,dr)+BUF[rr[i]]+hbr,sr[i])+er|0;ar=er,er=dr,dr=rotl$1(cr,10)|0,cr=br,br=tr}}this.set(this.h1+cl+dr|0,this.h2+dl+er|0,this.h3+el+ar|0,this.h4+al+br|0,this.h0+bl+cr|0)}roundClean(){BUF.fill(0)}destroy(){this.destroyed=true;this.buffer.fill(0);this.set(0,0,0,0,0)}}const ripemd160$1=wrapConstructor(()=>new RIPEMD160);let locked$2=false;const _ripemd160=function(data){return ripemd160$1(data)};let __ripemd160=_ripemd160;function ripemd160(_data){const data=getBytes(_data,"data");return hexlify(__ripemd160(data))}ripemd160._=_ripemd160;ripemd160.lock=function(){locked$2=true};ripemd160.register=function(func){if(locked$2){throw new TypeError("ripemd160 is locked")}__ripemd160=func};Object.freeze(ripemd160);let locked$1=false;const _pbkdf2=function(password,salt,iterations,keylen,algo){return pbkdf2Sync(password,salt,iterations,keylen,algo)};let __pbkdf2=_pbkdf2;function pbkdf2(_password,_salt,iterations,keylen,algo){const password=getBytes(_password,"password");const salt=getBytes(_salt,"salt");return hexlify(__pbkdf2(password,salt,iterations,keylen,algo))}pbkdf2._=_pbkdf2;pbkdf2.lock=function(){locked$1=true};pbkdf2.register=function(func){if(locked$1){throw new Error("pbkdf2 is locked")}__pbkdf2=func};Object.freeze(pbkdf2);let locked=false;const _randomBytes=function(length){return new Uint8Array(randomBytes$1(length))};let __randomBytes=_randomBytes;function randomBytes(length){return __randomBytes(length)}randomBytes._=_randomBytes;randomBytes.lock=function(){locked=true};randomBytes.register=function(func){if(locked){throw new Error("randomBytes is locked")}__randomBytes=func};Object.freeze(randomBytes);const rotl=(a,b)=>a<>>32-b;function XorAndSalsa(prev,pi,input,ii,out,oi){let y00=prev[pi++]^input[ii++],y01=prev[pi++]^input[ii++];let y02=prev[pi++]^input[ii++],y03=prev[pi++]^input[ii++];let y04=prev[pi++]^input[ii++],y05=prev[pi++]^input[ii++];let y06=prev[pi++]^input[ii++],y07=prev[pi++]^input[ii++];let y08=prev[pi++]^input[ii++],y09=prev[pi++]^input[ii++];let y10=prev[pi++]^input[ii++],y11=prev[pi++]^input[ii++];let y12=prev[pi++]^input[ii++],y13=prev[pi++]^input[ii++];let y14=prev[pi++]^input[ii++],y15=prev[pi++]^input[ii++];let x00=y00,x01=y01,x02=y02,x03=y03,x04=y04,x05=y05,x06=y06,x07=y07,x08=y08,x09=y09,x10=y10,x11=y11,x12=y12,x13=y13,x14=y14,x15=y15;for(let i=0;i<8;i+=2){x04^=rotl(x00+x12|0,7);x08^=rotl(x04+x00|0,9);x12^=rotl(x08+x04|0,13);x00^=rotl(x12+x08|0,18);x09^=rotl(x05+x01|0,7);x13^=rotl(x09+x05|0,9);x01^=rotl(x13+x09|0,13);x05^=rotl(x01+x13|0,18);x14^=rotl(x10+x06|0,7);x02^=rotl(x14+x10|0,9);x06^=rotl(x02+x14|0,13);x10^=rotl(x06+x02|0,18);x03^=rotl(x15+x11|0,7);x07^=rotl(x03+x15|0,9);x11^=rotl(x07+x03|0,13);x15^=rotl(x11+x07|0,18);x01^=rotl(x00+x03|0,7);x02^=rotl(x01+x00|0,9);x03^=rotl(x02+x01|0,13);x00^=rotl(x03+x02|0,18);x06^=rotl(x05+x04|0,7);x07^=rotl(x06+x05|0,9);x04^=rotl(x07+x06|0,13);x05^=rotl(x04+x07|0,18);x11^=rotl(x10+x09|0,7);x08^=rotl(x11+x10|0,9);x09^=rotl(x08+x11|0,13);x10^=rotl(x09+x08|0,18);x12^=rotl(x15+x14|0,7);x13^=rotl(x12+x15|0,9);x14^=rotl(x13+x12|0,13);x15^=rotl(x14+x13|0,18)}out[oi++]=y00+x00|0;out[oi++]=y01+x01|0;out[oi++]=y02+x02|0;out[oi++]=y03+x03|0;out[oi++]=y04+x04|0;out[oi++]=y05+x05|0;out[oi++]=y06+x06|0;out[oi++]=y07+x07|0;out[oi++]=y08+x08|0;out[oi++]=y09+x09|0;out[oi++]=y10+x10|0;out[oi++]=y11+x11|0;out[oi++]=y12+x12|0;out[oi++]=y13+x13|0;out[oi++]=y14+x14|0;out[oi++]=y15+x15|0}function BlockMix(input,ii,out,oi,r){let head=oi+0;let tail=oi+16*r;for(let i=0;i<16;i++)out[tail+i]=input[ii+(2*r-1)*16+i];for(let i=0;i0)tail+=16;XorAndSalsa(out,head,input,ii+=16,out,tail)}}function scryptInit(password,salt,_opts){const opts=checkOpts({dkLen:32,asyncTick:10,maxmem:1024**3+1024},_opts);const{N,r,p,dkLen,asyncTick,maxmem,onProgress}=opts;assert.number(N);assert.number(r);assert.number(p);assert.number(dkLen);assert.number(asyncTick);assert.number(maxmem);if(onProgress!==undefined&&typeof onProgress!=="function")throw new Error("progressCb should be function");const blockSize=128*r;const blockSize32=blockSize/4;if(N<=1||(N&N-1)!==0||N>=2**(blockSize/8)||N>2**32){throw new Error("Scrypt: N must be larger than 1, a power of 2, less than 2^(128 * r / 8) and less than 2^32")}if(p<0||p>(2**32-1)*32/blockSize){throw new Error("Scrypt: p must be a positive integer less than or equal to ((2^32 - 1) * 32) / (128 * r)")}if(dkLen<0||dkLen>(2**32-1)*32){throw new Error("Scrypt: dkLen should be positive integer less than or equal to (2^32 - 1) * 32")}const memUsed=blockSize*(N+p);if(memUsed>maxmem){throw new Error(`Scrypt: parameters too large, ${memUsed} (128 * r * (N + p)) > ${maxmem} (maxmem)`)}const B=pbkdf2$1(sha256$1,password,salt,{c:1,dkLen:blockSize*p});const B32=u32(B);const V=u32(new Uint8Array(blockSize*N));const tmp=u32(new Uint8Array(blockSize));let blockMixCb=()=>{};if(onProgress){const totalBlockMix=2*N*p;const callbackPer=Math.max(Math.floor(totalBlockMix/1e4),1);let blockMixCnt=0;blockMixCb=()=>{blockMixCnt++;if(onProgress&&(!(blockMixCnt%callbackPer)||blockMixCnt===totalBlockMix))onProgress(blockMixCnt/totalBlockMix)}}return{N:N,r:r,p:p,dkLen:dkLen,blockSize32:blockSize32,V:V,B32:B32,B:B,tmp:tmp,blockMixCb:blockMixCb,asyncTick:asyncTick}}function scryptOutput(password,dkLen,B,V,tmp){const res=pbkdf2$1(sha256$1,password,B,{c:1,dkLen:dkLen});B.fill(0);V.fill(0);tmp.fill(0);return res}function scrypt$1(password,salt,opts){const{N,r,p,dkLen,blockSize32,V,B32,B,tmp,blockMixCb}=scryptInit(password,salt,opts);for(let pi=0;pi{BlockMix(V,pos,V,pos+=blockSize32,r);blockMixCb()});BlockMix(V,(N-1)*blockSize32,B32,Pi,r);blockMixCb();await asyncLoop(N,asyncTick,i=>{const j=B32[Pi+blockSize32-16]%N;for(let k=0;k(a+b/_2n)/b;const endo={beta:BigInt("0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee"),splitScalar(k){const{n}=CURVE;const a1=BigInt("0x3086d221a7d46bcde86c90e49284eb15");const b1=-_1n*BigInt("0xe4437ed6010e88286f547fa90abfe4c3");const a2=BigInt("0x114ca50f7a8e2f3f657c1108d9d44cfd8");const b2=a1;const POW_2_128=BigInt("0x100000000000000000000000000000000");const c1=divNearest(b2*k,n);const c2=divNearest(-b1*k,n);let k1=mod(k-c1*a1-c2*a2,n);let k2=mod(-c1*b1-c2*b2,n);const k1neg=k1>POW_2_128;const k2neg=k2>POW_2_128;if(k1neg)k1=n-k1;if(k2neg)k2=n-k2;if(k1>POW_2_128||k2>POW_2_128){throw new Error("splitScalarEndo: Endomorphism failed, k="+k)}return{k1neg:k1neg,k1:k1,k2neg:k2neg,k2:k2}}};const fieldLen=32;const groupLen=32;const hashLen=32;const compressedLen=fieldLen+1;const uncompressedLen=2*fieldLen+1;function weierstrass(x){const{a,b}=CURVE;const x2=mod(x*x);const x3=mod(x2*x);return mod(x3+a*x+b)}const USE_ENDOMORPHISM=CURVE.a===_0n;class ShaError extends Error{constructor(message){super(message)}}function assertJacPoint(other){if(!(other instanceof JacobianPoint))throw new TypeError("JacobianPoint expected")}class JacobianPoint{constructor(x,y,z){this.x=x;this.y=y;this.z=z}static fromAffine(p){if(!(p instanceof Point)){throw new TypeError("JacobianPoint#fromAffine: expected Point")}if(p.equals(Point.ZERO))return JacobianPoint.ZERO;return new JacobianPoint(p.x,p.y,_1n)}static toAffineBatch(points){const toInv=invertBatch(points.map(p=>p.z));return points.map((p,i)=>p.toAffine(toInv[i]))}static normalizeZ(points){return JacobianPoint.toAffineBatch(points).map(JacobianPoint.fromAffine)}equals(other){assertJacPoint(other);const{x:X1,y:Y1,z:Z1}=this;const{x:X2,y:Y2,z:Z2}=other;const Z1Z1=mod(Z1*Z1);const Z2Z2=mod(Z2*Z2);const U1=mod(X1*Z2Z2);const U2=mod(X2*Z1Z1);const S1=mod(mod(Y1*Z2)*Z2Z2);const S2=mod(mod(Y2*Z1)*Z1Z1);return U1===U2&&S1===S2}negate(){return new JacobianPoint(this.x,mod(-this.y),this.z)}double(){const{x:X1,y:Y1,z:Z1}=this;const A=mod(X1*X1);const B=mod(Y1*Y1);const C=mod(B*B);const x1b=X1+B;const D=mod(_2n*(mod(x1b*x1b)-A-C));const E=mod(_3n*A);const F=mod(E*E);const X3=mod(F-_2n*D);const Y3=mod(E*(D-X3)-_8n*C);const Z3=mod(_2n*Y1*Z1);return new JacobianPoint(X3,Y3,Z3)}add(other){assertJacPoint(other);const{x:X1,y:Y1,z:Z1}=this;const{x:X2,y:Y2,z:Z2}=other;if(X2===_0n||Y2===_0n)return this;if(X1===_0n||Y1===_0n)return other;const Z1Z1=mod(Z1*Z1);const Z2Z2=mod(Z2*Z2);const U1=mod(X1*Z2Z2);const U2=mod(X2*Z1Z1);const S1=mod(mod(Y1*Z2)*Z2Z2);const S2=mod(mod(Y2*Z1)*Z1Z1);const H=mod(U2-U1);const r=mod(S2-S1);if(H===_0n){if(r===_0n){return this.double()}else{return JacobianPoint.ZERO}}const HH=mod(H*H);const HHH=mod(H*HH);const V=mod(U1*HH);const X3=mod(r*r-HHH-_2n*V);const Y3=mod(r*(V-X3)-S1*HHH);const Z3=mod(Z1*Z2*H);return new JacobianPoint(X3,Y3,Z3)}subtract(other){return this.add(other.negate())}multiplyUnsafe(scalar){const P0=JacobianPoint.ZERO;if(typeof scalar==="bigint"&&scalar===_0n)return P0;let n=normalizeScalar(scalar);if(n===_1n)return this;if(!USE_ENDOMORPHISM){let p=P0;let d=this;while(n>_0n){if(n&_1n)p=p.add(d);d=d.double();n>>=_1n}return p}let{k1neg,k1,k2neg,k2}=endo.splitScalar(n);let k1p=P0;let k2p=P0;let d=this;while(k1>_0n||k2>_0n){if(k1&_1n)k1p=k1p.add(d);if(k2&_1n)k2p=k2p.add(d);d=d.double();k1>>=_1n;k2>>=_1n}if(k1neg)k1p=k1p.negate();if(k2neg)k2p=k2p.negate();k2p=new JacobianPoint(mod(k2p.x*endo.beta),k2p.y,k2p.z);return k1p.add(k2p)}precomputeWindow(W){const windows=USE_ENDOMORPHISM?128/W+1:256/W+1;const points=[];let p=this;let base=p;for(let window=0;window>=shiftBy;if(wbits>windowSize){wbits-=maxNumber;n+=_1n}const offset1=offset;const offset2=offset+Math.abs(wbits)-1;const cond1=window%2!==0;const cond2=wbits<0;if(wbits===0){f=f.add(constTimeNegate(cond1,precomputes[offset1]))}else{p=p.add(constTimeNegate(cond2,precomputes[offset2]))}}return{p:p,f:f}}multiply(scalar,affinePoint){let n=normalizeScalar(scalar);let point;let fake;if(USE_ENDOMORPHISM){const{k1neg,k1,k2neg,k2}=endo.splitScalar(n);let{p:k1p,f:f1p}=this.wNAF(k1,affinePoint);let{p:k2p,f:f2p}=this.wNAF(k2,affinePoint);k1p=constTimeNegate(k1neg,k1p);k2p=constTimeNegate(k2neg,k2p);k2p=new JacobianPoint(mod(k2p.x*endo.beta),k2p.y,k2p.z);point=k1p.add(k2p);fake=f1p.add(f2p)}else{const{p,f}=this.wNAF(n,affinePoint);point=p;fake=f}return JacobianPoint.normalizeZ([point,fake])[0]}toAffine(invZ){const{x,y,z}=this;const is0=this.equals(JacobianPoint.ZERO);if(invZ==null)invZ=is0?_8n:invert(z);const iz1=invZ;const iz2=mod(iz1*iz1);const iz3=mod(iz2*iz1);const ax=mod(x*iz2);const ay=mod(y*iz3);const zz=mod(z*iz1);if(is0)return Point.ZERO;if(zz!==_1n)throw new Error("invZ was invalid");return new Point(ax,ay)}}JacobianPoint.BASE=new JacobianPoint(CURVE.Gx,CURVE.Gy,_1n);JacobianPoint.ZERO=new JacobianPoint(_0n,_1n,_0n);function constTimeNegate(condition,item){const neg=item.negate();return condition?neg:item}const pointPrecomputes=new WeakMap;class Point{constructor(x,y){this.x=x;this.y=y}_setWindowSize(windowSize){this._WINDOW_SIZE=windowSize;pointPrecomputes.delete(this)}hasEvenY(){return this.y%_2n===_0n}static fromCompressedHex(bytes){const isShort=bytes.length===32;const x=bytesToNumber(isShort?bytes:bytes.subarray(1));if(!isValidFieldElement(x))throw new Error("Point is not on curve");const y2=weierstrass(x);let y=sqrtMod(y2);const isYOdd=(y&_1n)===_1n;if(isShort){if(isYOdd)y=mod(-y)}else{const isFirstByteOdd=(bytes[0]&1)===1;if(isFirstByteOdd!==isYOdd)y=mod(-y)}const point=new Point(x,y);point.assertValidity();return point}static fromUncompressedHex(bytes){const x=bytesToNumber(bytes.subarray(1,fieldLen+1));const y=bytesToNumber(bytes.subarray(fieldLen+1,fieldLen*2+1));const point=new Point(x,y);point.assertValidity();return point}static fromHex(hex){const bytes=ensureBytes(hex);const len=bytes.length;const header=bytes[0];if(len===fieldLen)return this.fromCompressedHex(bytes);if(len===compressedLen&&(header===2||header===3)){return this.fromCompressedHex(bytes)}if(len===uncompressedLen&&header===4)return this.fromUncompressedHex(bytes);throw new Error(`Point.fromHex: received invalid point. Expected 32-${compressedLen} compressed bytes or ${uncompressedLen} uncompressed bytes, not ${len}`)}static fromPrivateKey(privateKey){return Point.BASE.multiply(normalizePrivateKey(privateKey))}static fromSignature(msgHash,signature,recovery){const{r,s}=normalizeSignature(signature);if(![0,1,2,3].includes(recovery))throw new Error("Cannot recover: invalid recovery bit");const h=truncateHash(ensureBytes(msgHash));const{n}=CURVE;const radj=recovery===2||recovery===3?r+n:r;const rinv=invert(radj,n);const u1=mod(-h*rinv,n);const u2=mod(s*rinv,n);const prefix=recovery&1?"03":"02";const R=Point.fromHex(prefix+numTo32bStr(radj));const Q=Point.BASE.multiplyAndAddUnsafe(R,u1,u2);if(!Q)throw new Error("Cannot recover signature: point at infinify");Q.assertValidity();return Q}toRawBytes(isCompressed=false){return hexToBytes(this.toHex(isCompressed))}toHex(isCompressed=false){const x=numTo32bStr(this.x);if(isCompressed){const prefix=this.hasEvenY()?"02":"03";return`${prefix}${x}`}else{return`04${x}${numTo32bStr(this.y)}`}}toHexX(){return this.toHex(true).slice(2)}toRawX(){return this.toRawBytes(true).slice(1)}assertValidity(){const msg="Point is not on elliptic curve";const{x,y}=this;if(!isValidFieldElement(x)||!isValidFieldElement(y))throw new Error(msg);const left=mod(y*y);const right=weierstrass(x);if(mod(left-right)!==_0n)throw new Error(msg)}equals(other){return this.x===other.x&&this.y===other.y}negate(){return new Point(this.x,mod(-this.y))}double(){return JacobianPoint.fromAffine(this).double().toAffine()}add(other){return JacobianPoint.fromAffine(this).add(JacobianPoint.fromAffine(other)).toAffine()}subtract(other){return this.add(other.negate())}multiply(scalar){return JacobianPoint.fromAffine(this).multiply(scalar,this).toAffine()}multiplyAndAddUnsafe(Q,a,b){const P=JacobianPoint.fromAffine(this);const aP=a===_0n||a===_1n||this!==Point.BASE?P.multiplyUnsafe(a):P.multiply(a);const bQ=JacobianPoint.fromAffine(Q).multiplyUnsafe(b);const sum=aP.add(bQ);return sum.equals(JacobianPoint.ZERO)?undefined:sum.toAffine()}}Point.BASE=new Point(CURVE.Gx,CURVE.Gy);Point.ZERO=new Point(_0n,_0n);function sliceDER(s){return Number.parseInt(s[0],16)>=8?"00"+s:s}function parseDERInt(data){if(data.length<2||data[0]!==2){throw new Error(`Invalid signature integer tag: ${bytesToHex(data)}`)}const len=data[1];const res=data.subarray(2,len+2);if(!len||res.length!==len){throw new Error(`Invalid signature integer: wrong length`)}if(res[0]===0&&res[1]<=127){throw new Error("Invalid signature integer: trailing length")}return{data:bytesToNumber(res),left:data.subarray(len+2)}}function parseDERSignature(data){if(data.length<2||data[0]!=48){throw new Error(`Invalid signature tag: ${bytesToHex(data)}`)}if(data[1]!==data.length-2){throw new Error("Invalid signature: incorrect length")}const{data:r,left:sBytes}=parseDERInt(data.subarray(2));const{data:s,left:rBytesLeft}=parseDERInt(sBytes);if(rBytesLeft.length){throw new Error(`Invalid signature: left bytes after parsing: ${bytesToHex(rBytesLeft)}`)}return{r:r,s:s}}class Signature$1{constructor(r,s){this.r=r;this.s=s;this.assertValidity()}static fromCompact(hex){const arr=hex instanceof Uint8Array;const name="Signature.fromCompact";if(typeof hex!=="string"&&!arr)throw new TypeError(`${name}: Expected string or Uint8Array`);const str=arr?bytesToHex(hex):hex;if(str.length!==128)throw new Error(`${name}: Expected 64-byte hex`);return new Signature$1(hexToNumber(str.slice(0,64)),hexToNumber(str.slice(64,128)))}static fromDER(hex){const arr=hex instanceof Uint8Array;if(typeof hex!=="string"&&!arr)throw new TypeError(`Signature.fromDER: Expected string or Uint8Array`);const{r,s}=parseDERSignature(arr?hex:hexToBytes(hex));return new Signature$1(r,s)}static fromHex(hex){return this.fromDER(hex)}assertValidity(){const{r,s}=this;if(!isWithinCurveOrder(r))throw new Error("Invalid Signature: r must be 0 < r < n");if(!isWithinCurveOrder(s))throw new Error("Invalid Signature: s must be 0 < s < n")}hasHighS(){const HALF=CURVE.n>>_1n;return this.s>HALF}normalizeS(){return this.hasHighS()?new Signature$1(this.r,mod(-this.s,CURVE.n)):this}toDERRawBytes(){return hexToBytes(this.toDERHex())}toDERHex(){const sHex=sliceDER(numberToHexUnpadded(this.s));const rHex=sliceDER(numberToHexUnpadded(this.r));const sHexL=sHex.length/2;const rHexL=rHex.length/2;const sLen=numberToHexUnpadded(sHexL);const rLen=numberToHexUnpadded(rHexL);const length=numberToHexUnpadded(rHexL+sHexL+4);return`30${length}02${rLen}${rHex}02${sLen}${sHex}`}toRawBytes(){return this.toDERRawBytes()}toHex(){return this.toDERHex()}toCompactRawBytes(){return hexToBytes(this.toCompactHex())}toCompactHex(){return numTo32bStr(this.r)+numTo32bStr(this.s)}}function concatBytes(...arrays){if(!arrays.every(b=>b instanceof Uint8Array))throw new Error("Uint8Array list expected");if(arrays.length===1)return arrays[0];const length=arrays.reduce((a,arr)=>a+arr.length,0);const result=new Uint8Array(length);for(let i=0,pad=0;ii.toString(16).padStart(2,"0"));function bytesToHex(uint8a){if(!(uint8a instanceof Uint8Array))throw new Error("Expected Uint8Array");let hex="";for(let i=0;i0)return BigInt(num);if(typeof num==="bigint"&&isWithinCurveOrder(num))return num;throw new TypeError("Expected valid private scalar: 0 < scalar < curve.n")}function mod(a,b=CURVE.P){const result=a%b;return result>=_0n?result:b+result}function pow2(x,power){const{P}=CURVE;let res=x;while(power-- >_0n){res*=res;res%=P}return res}function sqrtMod(x){const{P}=CURVE;const _6n=BigInt(6);const _11n=BigInt(11);const _22n=BigInt(22);const _23n=BigInt(23);const _44n=BigInt(44);const _88n=BigInt(88);const b2=x*x*x%P;const b3=b2*b2*x%P;const b6=pow2(b3,_3n)*b3%P;const b9=pow2(b6,_3n)*b3%P;const b11=pow2(b9,_2n)*b2%P;const b22=pow2(b11,_11n)*b11%P;const b44=pow2(b22,_22n)*b22%P;const b88=pow2(b44,_44n)*b44%P;const b176=pow2(b88,_88n)*b88%P;const b220=pow2(b176,_44n)*b44%P;const b223=pow2(b220,_3n)*b3%P;const t1=pow2(b223,_23n)*b22%P;const t2=pow2(t1,_6n)*b2%P;const rt=pow2(t2,_2n);const xc=rt*rt%P;if(xc!==x)throw new Error("Cannot find square root");return rt}function invert(number,modulo=CURVE.P){if(number===_0n||modulo<=_0n){throw new Error(`invert: expected positive integers, got n=${number} mod=${modulo}`)}let a=mod(number,modulo);let b=modulo;let x=_0n,y=_1n,u=_1n,v=_0n;while(a!==_0n){const q=b/a;const r=b%a;const m=x-u*q;const n=y-v*q;b=a,a=r,x=u,y=v,u=m,v=n}const gcd=b;if(gcd!==_1n)throw new Error("invert: does not exist");return mod(x,modulo)}function invertBatch(nums,p=CURVE.P){const scratch=new Array(nums.length);const lastMultiplied=nums.reduce((acc,num,i)=>{if(num===_0n)return acc;scratch[i]=acc;return mod(acc*num,p)},_1n);const inverted=invert(lastMultiplied,p);nums.reduceRight((acc,num,i)=>{if(num===_0n)return acc;scratch[i]=mod(acc*scratch[i],p);return mod(acc*num,p)},inverted);return scratch}function bits2int_2(bytes){const delta=bytes.length*8-groupLen*8;const num=bytesToNumber(bytes);return delta>0?num>>BigInt(delta):num}function truncateHash(hash,truncateOnly=false){const h=bits2int_2(hash);if(truncateOnly)return h;const{n}=CURVE;return h>=n?h-n:h}let _sha256Sync;let _hmacSha256Sync;class HmacDrbg{constructor(hashLen,qByteLen){this.hashLen=hashLen;this.qByteLen=qByteLen;if(typeof hashLen!=="number"||hashLen<2)throw new Error("hashLen must be a number");if(typeof qByteLen!=="number"||qByteLen<2)throw new Error("qByteLen must be a number");this.v=new Uint8Array(hashLen).fill(1);this.k=new Uint8Array(hashLen).fill(0);this.counter=0}hmac(...values){return utils.hmacSha256(this.k,...values)}hmacSync(...values){return _hmacSha256Sync(this.k,...values)}checkSync(){if(typeof _hmacSha256Sync!=="function")throw new ShaError("hmacSha256Sync needs to be set")}incr(){if(this.counter>=1e3)throw new Error("Tried 1,000 k values for sign(), all were invalid");this.counter+=1}async reseed(seed=new Uint8Array){this.k=await this.hmac(this.v,Uint8Array.from([0]),seed);this.v=await this.hmac(this.v);if(seed.length===0)return;this.k=await this.hmac(this.v,Uint8Array.from([1]),seed);this.v=await this.hmac(this.v)}reseedSync(seed=new Uint8Array){this.checkSync();this.k=this.hmacSync(this.v,Uint8Array.from([0]),seed);this.v=this.hmacSync(this.v);if(seed.length===0)return;this.k=this.hmacSync(this.v,Uint8Array.from([1]),seed);this.v=this.hmacSync(this.v)}async generate(){this.incr();let len=0;const out=[];while(len0){num=BigInt(key)}else if(typeof key==="string"){if(key.length!==2*groupLen)throw new Error("Expected 32 bytes of private key");num=hexToNumber(key)}else if(key instanceof Uint8Array){if(key.length!==groupLen)throw new Error("Expected 32 bytes of private key");num=bytesToNumber(key)}else{throw new TypeError("Expected valid private key")}if(!isWithinCurveOrder(num))throw new Error("Expected private key: 0 < key < n");return num}function normalizePublicKey(publicKey){if(publicKey instanceof Point){publicKey.assertValidity();return publicKey}else{return Point.fromHex(publicKey)}}function normalizeSignature(signature){if(signature instanceof Signature$1){signature.assertValidity();return signature}try{return Signature$1.fromDER(signature)}catch(error){return Signature$1.fromCompact(signature)}}function getPublicKey(privateKey,isCompressed=false){return Point.fromPrivateKey(privateKey).toRawBytes(isCompressed)}function recoverPublicKey(msgHash,signature,recovery,isCompressed=false){return Point.fromSignature(msgHash,signature,recovery).toRawBytes(isCompressed)}function isProbPub(item){const arr=item instanceof Uint8Array;const str=typeof item==="string";const len=(arr||str)&&item.length;if(arr)return len===compressedLen||len===uncompressedLen;if(str)return len===compressedLen*2||len===uncompressedLen*2;if(item instanceof Point)return true;return false}function getSharedSecret(privateA,publicB,isCompressed=false){if(isProbPub(privateA))throw new TypeError("getSharedSecret: first arg must be private key");if(!isProbPub(publicB))throw new TypeError("getSharedSecret: second arg must be public key");const b=normalizePublicKey(publicB);b.assertValidity();return b.multiply(normalizePrivateKey(privateA)).toRawBytes(isCompressed)}function bits2int(bytes){const slice=bytes.length>fieldLen?bytes.slice(0,fieldLen):bytes;return bytesToNumber(slice)}function bits2octets(bytes){const z1=bits2int(bytes);const z2=mod(z1,CURVE.n);return int2octets(z2<_0n?z1:z2)}function int2octets(num){return numTo32b(num)}function initSigArgs(msgHash,privateKey,extraEntropy){if(msgHash==null)throw new Error(`sign: expected valid message hash, not "${msgHash}"`);const h1=ensureBytes(msgHash);const d=normalizePrivateKey(privateKey);const seedArgs=[int2octets(d),bits2octets(h1)];if(extraEntropy!=null){if(extraEntropy===true)extraEntropy=utils.randomBytes(fieldLen);const e=ensureBytes(extraEntropy);if(e.length!==fieldLen)throw new Error(`sign: Expected ${fieldLen} bytes of extra data`);seedArgs.push(e)}const seed=concatBytes(...seedArgs);const m=bits2int(h1);return{seed:seed,m:m,d:d}}function finalizeSig(recSig,opts){const{sig,recovery}=recSig;const{der,recovered}=Object.assign({canonical:true,der:true},opts);const hashed=der?sig.toDERRawBytes():sig.toCompactRawBytes();return recovered?[hashed,recovery]:hashed}async function sign(msgHash,privKey,opts={}){const{seed,m,d}=initSigArgs(msgHash,privKey,opts.extraEntropy);const drbg=new HmacDrbg(hashLen,groupLen);await drbg.reseed(seed);let sig;while(!(sig=kmdToSig(await drbg.generate(),m,d,opts.canonical)))await drbg.reseed();return finalizeSig(sig,opts)}function signSync(msgHash,privKey,opts={}){const{seed,m,d}=initSigArgs(msgHash,privKey,opts.extraEntropy);const drbg=new HmacDrbg(hashLen,groupLen);drbg.reseedSync(seed);let sig;while(!(sig=kmdToSig(drbg.generateSync(),m,d,opts.canonical)))drbg.reseedSync();return finalizeSig(sig,opts)}const vopts={strict:true};function verify(signature,msgHash,publicKey,opts=vopts){let sig;try{sig=normalizeSignature(signature);msgHash=ensureBytes(msgHash)}catch(error){return false}const{r,s}=sig;if(opts.strict&&sig.hasHighS())return false;const h=truncateHash(msgHash);let P;try{P=normalizePublicKey(publicKey)}catch(error){return false}const{n}=CURVE;const sinv=invert(s,n);const u1=mod(h*sinv,n);const u2=mod(r*sinv,n);const R=Point.BASE.multiplyAndAddUnsafe(P,u1,u2);if(!R)return false;const v=mod(R.x,n);return v===r}function schnorrChallengeFinalize(ch){return mod(bytesToNumber(ch),CURVE.n)}class SchnorrSignature{constructor(r,s){this.r=r;this.s=s;this.assertValidity()}static fromHex(hex){const bytes=ensureBytes(hex);if(bytes.length!==64)throw new TypeError(`SchnorrSignature.fromHex: expected 64 bytes, not ${bytes.length}`);const r=bytesToNumber(bytes.subarray(0,32));const s=bytesToNumber(bytes.subarray(32,64));return new SchnorrSignature(r,s)}assertValidity(){const{r,s}=this;if(!isValidFieldElement(r)||!isWithinCurveOrder(s))throw new Error("Invalid signature")}toHex(){return numTo32bStr(this.r)+numTo32bStr(this.s)}toRawBytes(){return hexToBytes(this.toHex())}}function schnorrGetPublicKey(privateKey){return Point.fromPrivateKey(privateKey).toRawX()}class InternalSchnorrSignature{constructor(message,privateKey,auxRand=utils.randomBytes()){if(message==null)throw new TypeError(`sign: Expected valid message, not "${message}"`);this.m=ensureBytes(message);const{x,scalar}=this.getScalar(normalizePrivateKey(privateKey));this.px=x;this.d=scalar;this.rand=ensureBytes(auxRand);if(this.rand.length!==32)throw new TypeError("sign: Expected 32 bytes of aux randomness")}getScalar(priv){const point=Point.fromPrivateKey(priv);const scalar=point.hasEvenY()?priv:CURVE.n-priv;return{point:point,scalar:scalar,x:point.toRawX()}}initNonce(d,t0h){return numTo32b(d^bytesToNumber(t0h))}finalizeNonce(k0h){const k0=mod(bytesToNumber(k0h),CURVE.n);if(k0===_0n)throw new Error("sign: Creation of signature failed. k is zero");const{point:R,x:rx,scalar:k}=this.getScalar(k0);return{R:R,rx:rx,k:k}}finalizeSig(R,k,e,d){return new SchnorrSignature(R.x,mod(k+e*d,CURVE.n)).toRawBytes()}error(){throw new Error("sign: Invalid signature produced")}async calc(){const{m,d,px,rand}=this;const tag=utils.taggedHash;const t=this.initNonce(d,await tag(TAGS.aux,rand));const{R,rx,k}=this.finalizeNonce(await tag(TAGS.nonce,t,px,m));const e=schnorrChallengeFinalize(await tag(TAGS.challenge,rx,px,m));const sig=this.finalizeSig(R,k,e,d);if(!await schnorrVerify(sig,m,px))this.error();return sig}calcSync(){const{m,d,px,rand}=this;const tag=utils.taggedHashSync;const t=this.initNonce(d,tag(TAGS.aux,rand));const{R,rx,k}=this.finalizeNonce(tag(TAGS.nonce,t,px,m));const e=schnorrChallengeFinalize(tag(TAGS.challenge,rx,px,m));const sig=this.finalizeSig(R,k,e,d);if(!schnorrVerifySync(sig,m,px))this.error();return sig}}async function schnorrSign(msg,privKey,auxRand){return new InternalSchnorrSignature(msg,privKey,auxRand).calc()}function schnorrSignSync(msg,privKey,auxRand){return new InternalSchnorrSignature(msg,privKey,auxRand).calcSync()}function initSchnorrVerify(signature,message,publicKey){const raw=signature instanceof SchnorrSignature;const sig=raw?signature:SchnorrSignature.fromHex(signature);if(raw)sig.assertValidity();return{...sig,m:ensureBytes(message),P:normalizePublicKey(publicKey)}}function finalizeSchnorrVerify(r,P,s,e){const R=Point.BASE.multiplyAndAddUnsafe(P,normalizePrivateKey(s),mod(-e,CURVE.n));if(!R||!R.hasEvenY()||R.x!==r)return false;return true}async function schnorrVerify(signature,message,publicKey){try{const{r,s,m,P}=initSchnorrVerify(signature,message,publicKey);const e=schnorrChallengeFinalize(await utils.taggedHash(TAGS.challenge,numTo32b(r),P.toRawX(),m));return finalizeSchnorrVerify(r,P,s,e)}catch(error){return false}}function schnorrVerifySync(signature,message,publicKey){try{const{r,s,m,P}=initSchnorrVerify(signature,message,publicKey);const e=schnorrChallengeFinalize(utils.taggedHashSync(TAGS.challenge,numTo32b(r),P.toRawX(),m));return finalizeSchnorrVerify(r,P,s,e)}catch(error){if(error instanceof ShaError)throw error;return false}}const schnorr={Signature:SchnorrSignature,getPublicKey:schnorrGetPublicKey,sign:schnorrSign,verify:schnorrVerify,signSync:schnorrSignSync,verifySync:schnorrVerifySync};Point.BASE._setWindowSize(8);const crypto={node:nodeCrypto,web:typeof self==="object"&&"crypto"in self?self.crypto:undefined};const TAGS={challenge:"BIP0340/challenge",aux:"BIP0340/aux",nonce:"BIP0340/nonce"};const TAGGED_HASH_PREFIXES={};const utils={bytesToHex:bytesToHex,hexToBytes:hexToBytes,concatBytes:concatBytes,mod:mod,invert:invert,isValidPrivateKey(privateKey){try{normalizePrivateKey(privateKey);return true}catch(error){return false}},_bigintTo32Bytes:numTo32b,_normalizePrivateKey:normalizePrivateKey,hashToPrivateKey:hash=>{hash=ensureBytes(hash);const minLen=groupLen+8;if(hash.length1024){throw new Error(`Expected valid bytes of private key as per FIPS 186`)}const num=mod(bytesToNumber(hash),CURVE.n-_1n)+_1n;return numTo32b(num)},randomBytes:(bytesLength=32)=>{if(crypto.web){return crypto.web.getRandomValues(new Uint8Array(bytesLength))}else if(crypto.node){const{randomBytes}=crypto.node;return Uint8Array.from(randomBytes(bytesLength))}else{throw new Error("The environment doesn't have randomBytes function")}},randomPrivateKey:()=>utils.hashToPrivateKey(utils.randomBytes(groupLen+8)),precompute(windowSize=8,point=Point.BASE){const cached=point===Point.BASE?point:new Point(point.x,point.y);cached._setWindowSize(windowSize);cached.multiply(_3n);return cached},sha256:async(...messages)=>{if(crypto.web){const buffer=await crypto.web.subtle.digest("SHA-256",concatBytes(...messages));return new Uint8Array(buffer)}else if(crypto.node){const{createHash}=crypto.node;const hash=createHash("sha256");messages.forEach(m=>hash.update(m));return Uint8Array.from(hash.digest())}else{throw new Error("The environment doesn't have sha256 function")}},hmacSha256:async(key,...messages)=>{if(crypto.web){const ckey=await crypto.web.subtle.importKey("raw",key,{name:"HMAC",hash:{name:"SHA-256"}},false,["sign"]);const message=concatBytes(...messages);const buffer=await crypto.web.subtle.sign("HMAC",ckey,message);return new Uint8Array(buffer)}else if(crypto.node){const{createHmac}=crypto.node;const hash=createHmac("sha256",key);messages.forEach(m=>hash.update(m));return Uint8Array.from(hash.digest())}else{throw new Error("The environment doesn't have hmac-sha256 function")}},sha256Sync:undefined,hmacSha256Sync:undefined,taggedHash:async(tag,...messages)=>{let tagP=TAGGED_HASH_PREFIXES[tag];if(tagP===undefined){const tagH=await utils.sha256(Uint8Array.from(tag,c=>c.charCodeAt(0)));tagP=concatBytes(tagH,tagH);TAGGED_HASH_PREFIXES[tag]=tagP}return utils.sha256(tagP,...messages)},taggedHashSync:(tag,...messages)=>{if(typeof _sha256Sync!=="function")throw new ShaError("sha256Sync is undefined, you need to set it");let tagP=TAGGED_HASH_PREFIXES[tag];if(tagP===undefined){const tagH=_sha256Sync(Uint8Array.from(tag,c=>c.charCodeAt(0)));tagP=concatBytes(tagH,tagH);TAGGED_HASH_PREFIXES[tag]=tagP}return _sha256Sync(tagP,...messages)},_JacobianPoint:JacobianPoint};Object.defineProperties(utils,{sha256Sync:{configurable:false,get(){return _sha256Sync},set(val){if(!_sha256Sync)_sha256Sync=val}},hmacSha256Sync:{configurable:false,get(){return _hmacSha256Sync},set(val){if(!_hmacSha256Sync)_hmacSha256Sync=val}}});const ZeroAddress="0x0000000000000000000000000000000000000000";const ZeroHash="0x0000000000000000000000000000000000000000000000000000000000000000";const N$1=BigInt("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141");const WeiPerEther=BigInt("1000000000000000000");const MaxUint256=BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");const MinInt256=BigInt("0x8000000000000000000000000000000000000000000000000000000000000000")*BigInt(-1);const MaxInt256=BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");const EtherSymbol="Ξ";const MessagePrefix="Ethereum Signed Message:\n";const BN_0$7=BigInt(0);const BN_1$3=BigInt(1);const BN_2$3=BigInt(2);const BN_27$1=BigInt(27);const BN_28$1=BigInt(28);const BN_35$1=BigInt(35);const _guard$3={};function toUint256(value){return zeroPadValue(toBeArray(value),32)}class Signature{#r;#s;#v;#networkV;get r(){return this.#r}set r(value){assertArgument(dataLength(value)===32,"invalid r","value",value);this.#r=hexlify(value)}get s(){return this.#s}set s(_value){assertArgument(dataLength(_value)===32,"invalid s","value",_value);const value=hexlify(_value);assertArgument(parseInt(value.substring(0,3))<8,"non-canonical s","value",value);this.#s=value}get v(){return this.#v}set v(value){const v=getNumber(value,"value");assertArgument(v===27||v===28,"invalid v","v",value);this.#v=v}get networkV(){return this.#networkV}get legacyChainId(){const v=this.networkV;if(v==null){return null}return Signature.getChainId(v)}get yParity(){return this.v===27?0:1}get yParityAndS(){const yParityAndS=getBytes(this.s);if(this.yParity){yParityAndS[0]|=128}return hexlify(yParityAndS)}get compactSerialized(){return concat([this.r,this.yParityAndS])}get serialized(){return concat([this.r,this.s,this.yParity?"0x1c":"0x1b"])}constructor(guard,r,s,v){assertPrivate(guard,_guard$3,"Signature");this.#r=r;this.#s=s;this.#v=v;this.#networkV=null}[Symbol.for("nodejs.util.inspect.custom")](){return`Signature { r: "${this.r}", s: "${this.s}", yParity: ${this.yParity}, networkV: ${this.networkV} }`}clone(){const clone=new Signature(_guard$3,this.r,this.s,this.v);if(this.networkV){clone.#networkV=this.networkV}return clone}toJSON(){const networkV=this.networkV;return{_type:"signature",networkV:networkV!=null?networkV.toString():null,r:this.r,s:this.s,v:this.v}}static getChainId(v){const bv=getBigInt(v,"v");if(bv==BN_27$1||bv==BN_28$1){return BN_0$7}assertArgument(bv>=BN_35$1,"invalid EIP-155 v","v",v);return(bv-BN_35$1)/BN_2$3}static getChainIdV(chainId,v){return getBigInt(chainId)*BN_2$3+BigInt(35+v-27)}static getNormalizedV(v){const bv=getBigInt(v);if(bv===BN_0$7||bv===BN_27$1){return 27}if(bv===BN_1$3||bv===BN_28$1){return 28}assertArgument(bv>=BN_35$1,"invalid v","v",v);return bv&BN_1$3?27:28}static from(sig){function assertError(check,message){assertArgument(check,message,"signature",sig)}if(sig==null){return new Signature(_guard$3,ZeroHash,ZeroHash,27)}if(typeof sig==="string"){const bytes=getBytes(sig,"signature");if(bytes.length===64){const r=hexlify(bytes.slice(0,32));const s=bytes.slice(32,64);const v=s[0]&128?28:27;s[0]&=127;return new Signature(_guard$3,r,hexlify(s),v)}if(bytes.length===65){const r=hexlify(bytes.slice(0,32));const s=bytes.slice(32,64);assertError((s[0]&128)===0,"non-canonical s");const v=Signature.getNormalizedV(bytes[64]);return new Signature(_guard$3,r,hexlify(s),v)}assertError(false,"invalid raw signature length")}if(sig instanceof Signature){return sig.clone()}const _r=sig.r;assertError(_r!=null,"missing r");const r=toUint256(_r);const s=function(s,yParityAndS){if(s!=null){return toUint256(s)}if(yParityAndS!=null){assertError(isHexString(yParityAndS,32),"invalid yParityAndS");const bytes=getBytes(yParityAndS);bytes[0]&=127;return hexlify(bytes)}assertError(false,"missing s")}(sig.s,sig.yParityAndS);assertError((getBytes(s)[0]&128)==0,"non-canonical s");const{networkV,v}=function(_v,yParityAndS,yParity){if(_v!=null){const v=getBigInt(_v);return{networkV:v>=BN_35$1?v:undefined,v:Signature.getNormalizedV(v)}}if(yParityAndS!=null){assertError(isHexString(yParityAndS,32),"invalid yParityAndS");return{v:getBytes(yParityAndS)[0]&128?28:27}}if(yParity!=null){switch(yParity){case 0:return{v:27};case 1:return{v:28}}assertError(false,"invalid yParity")}assertError(false,"missing v")}(sig.v,sig.yParityAndS,sig.yParity);const result=new Signature(_guard$3,r,s,v);if(networkV){result.#networkV=networkV}assertError(!("yParity"in sig&&sig.yParity!==result.yParity),"yParity mismatch");assertError(!("yParityAndS"in sig&&sig.yParityAndS!==result.yParityAndS),"yParityAndS mismatch");return result}}utils.hmacSha256Sync=function(key,...messages){return getBytes(computeHmac("sha256",key,concat(messages)))};class SigningKey{#privateKey;constructor(privateKey){assertArgument(dataLength(privateKey)===32,"invalid private key","privateKey","[REDACTED]");this.#privateKey=hexlify(privateKey)}get privateKey(){return this.#privateKey}get publicKey(){return SigningKey.computePublicKey(this.#privateKey)}get compressedPublicKey(){return SigningKey.computePublicKey(this.#privateKey,true)}sign(digest){assertArgument(dataLength(digest)===32,"invalid digest length","digest",digest);const[sigDer,recid]=signSync(getBytesCopy(digest),getBytesCopy(this.#privateKey),{recovered:true,canonical:true});const sig=Signature$1.fromHex(sigDer);return Signature.from({r:toBeHex("0x"+sig.r.toString(16),32),s:toBeHex("0x"+sig.s.toString(16),32),v:recid?28:27})}computeSharedSecret(other){const pubKey=SigningKey.computePublicKey(other);console.log(pubKey);return hexlify(getSharedSecret(getBytesCopy(this.#privateKey),getBytes(pubKey)))}static computePublicKey(key,compressed){let bytes=getBytes(key,"key");if(bytes.length===32){const pubKey=getPublicKey(bytes,!!compressed);return hexlify(pubKey)}if(bytes.length===64){const pub=new Uint8Array(65);pub[0]=4;pub.set(bytes,1);bytes=pub}const point=Point.fromHex(bytes);return hexlify(point.toRawBytes(compressed))}static recoverPublicKey(digest,signature){assertArgument(dataLength(digest)===32,"invalid digest length","digest",digest);const sig=Signature.from(signature);const der=Signature$1.fromCompact(getBytesCopy(concat([sig.r,sig.s]))).toDERRawBytes();const pubKey=recoverPublicKey(getBytesCopy(digest),der,sig.yParity);assertArgument(pubKey!=null,"invalid signautre for digest","signature",signature);return hexlify(pubKey)}static addPoints(p0,p1,compressed){const pub0=Point.fromHex(SigningKey.computePublicKey(p0).substring(2));const pub1=Point.fromHex(SigningKey.computePublicKey(p1).substring(2));return"0x"+pub0.add(pub1).toHex(!!compressed)}}null;function lock(){computeHmac.lock();keccak256.lock();pbkdf2.lock();randomBytes.lock();ripemd160.lock();scrypt.lock();scryptSync.lock();sha256.lock();sha512.lock();randomBytes.lock()}const BN_0$6=BigInt(0);const BN_36=BigInt(36);function getChecksumAddress(address){address=address.toLowerCase();const chars=address.substring(2).split("");const expanded=new Uint8Array(40);for(let i=0;i<40;i++){expanded[i]=chars[i].charCodeAt(0)}const hashed=getBytes(keccak256(expanded));for(let i=0;i<40;i+=2){if(hashed[i>>1]>>4>=8){chars[i]=chars[i].toUpperCase()}if((hashed[i>>1]&15)>=8){chars[i+1]=chars[i+1].toUpperCase()}}return"0x"+chars.join("")}const ibanLookup={};for(let i=0;i<10;i++){ibanLookup[String(i)]=String(i)}for(let i=0;i<26;i++){ibanLookup[String.fromCharCode(65+i)]=String(10+i)}const safeDigits=15;function ibanChecksum(address){address=address.toUpperCase();address=address.substring(4)+address.substring(0,2)+"00";let expanded=address.split("").map(c=>{return ibanLookup[c]}).join("");while(expanded.length>=safeDigits){let block=expanded.substring(0,safeDigits);expanded=parseInt(block,10)%97+expanded.substring(block.length)}let checksum=String(98-parseInt(expanded,10)%97);while(checksum.length<2){checksum="0"+checksum}return checksum}const Base36=function(){const result={};for(let i=0;i<36;i++){const key="0123456789abcdefghijklmnopqrstuvwxyz"[i];result[key]=BigInt(i)}return result}();function fromBase36(value){value=value.toLowerCase();let result=BN_0$6;for(let i=0;iv.format()).join(",")})`}return this.type}defaultValue(){return 0}minValue(){return 0}maxValue(){return 0}isBigInt(){return!!this.type.match(/^u?int[0-9]+$/)}isData(){return this.type.startsWith("bytes")}isString(){return this.type==="string"}get tupleName(){if(this.type!=="tuple"){throw TypeError("not a tuple")}return this.#options}get arrayLength(){if(this.type!=="array"){throw TypeError("not an array")}if(this.#options===true){return-1}if(this.#options===false){return this.value.length}return null}static from(type,value){return new Typed(_gaurd,type,value)}static uint8(v){return n(v,8)}static uint16(v){return n(v,16)}static uint24(v){return n(v,24)}static uint32(v){return n(v,32)}static uint40(v){return n(v,40)}static uint48(v){return n(v,48)}static uint56(v){return n(v,56)}static uint64(v){return n(v,64)}static uint72(v){return n(v,72)}static uint80(v){return n(v,80)}static uint88(v){return n(v,88)}static uint96(v){return n(v,96)}static uint104(v){return n(v,104)}static uint112(v){return n(v,112)}static uint120(v){return n(v,120)}static uint128(v){return n(v,128)}static uint136(v){return n(v,136)}static uint144(v){return n(v,144)}static uint152(v){return n(v,152)}static uint160(v){return n(v,160)}static uint168(v){return n(v,168)}static uint176(v){return n(v,176)}static uint184(v){return n(v,184)}static uint192(v){return n(v,192)}static uint200(v){return n(v,200)}static uint208(v){return n(v,208)}static uint216(v){return n(v,216)}static uint224(v){return n(v,224)}static uint232(v){return n(v,232)}static uint240(v){return n(v,240)}static uint248(v){return n(v,248)}static uint256(v){return n(v,256)}static uint(v){return n(v,256)}static int8(v){return n(v,-8)}static int16(v){return n(v,-16)}static int24(v){return n(v,-24)}static int32(v){return n(v,-32)}static int40(v){return n(v,-40)}static int48(v){return n(v,-48)}static int56(v){return n(v,-56)}static int64(v){return n(v,-64)}static int72(v){return n(v,-72)}static int80(v){return n(v,-80)}static int88(v){return n(v,-88)}static int96(v){return n(v,-96)}static int104(v){return n(v,-104)}static int112(v){return n(v,-112)}static int120(v){return n(v,-120)}static int128(v){return n(v,-128)}static int136(v){return n(v,-136)}static int144(v){return n(v,-144)}static int152(v){return n(v,-152)}static int160(v){return n(v,-160)}static int168(v){return n(v,-168)}static int176(v){return n(v,-176)}static int184(v){return n(v,-184)}static int192(v){return n(v,-192)}static int200(v){return n(v,-200)}static int208(v){return n(v,-208)}static int216(v){return n(v,-216)}static int224(v){return n(v,-224)}static int232(v){return n(v,-232)}static int240(v){return n(v,-240)}static int248(v){return n(v,-248)}static int256(v){return n(v,-256)}static int(v){return n(v,-256)}static bytes1(v){return b(v,1)}static bytes2(v){return b(v,2)}static bytes3(v){return b(v,3)}static bytes4(v){return b(v,4)}static bytes5(v){return b(v,5)}static bytes6(v){return b(v,6)}static bytes7(v){return b(v,7)}static bytes8(v){return b(v,8)}static bytes9(v){return b(v,9)}static bytes10(v){return b(v,10)}static bytes11(v){return b(v,11)}static bytes12(v){return b(v,12)}static bytes13(v){return b(v,13)}static bytes14(v){return b(v,14)}static bytes15(v){return b(v,15)}static bytes16(v){return b(v,16)}static bytes17(v){return b(v,17)}static bytes18(v){return b(v,18)}static bytes19(v){return b(v,19)}static bytes20(v){return b(v,20)}static bytes21(v){return b(v,21)}static bytes22(v){return b(v,22)}static bytes23(v){return b(v,23)}static bytes24(v){return b(v,24)}static bytes25(v){return b(v,25)}static bytes26(v){return b(v,26)}static bytes27(v){return b(v,27)}static bytes28(v){return b(v,28)}static bytes29(v){return b(v,29)}static bytes30(v){return b(v,30)}static bytes31(v){return b(v,31)}static bytes32(v){return b(v,32)}static address(v){return new Typed(_gaurd,"address",v)}static bool(v){return new Typed(_gaurd,"bool",!!v)}static bytes(v){return new Typed(_gaurd,"bytes",v)}static string(v){return new Typed(_gaurd,"string",v)}static array(v,dynamic){throw new Error("not implemented yet");return new Typed(_gaurd,"array",v,dynamic)}static tuple(v,name){throw new Error("not implemented yet");return new Typed(_gaurd,"tuple",v,name)}static overrides(v){return new Typed(_gaurd,"overrides",Object.assign({},v))}static isTyped(value){return value&&value._typedSymbol===_typedSymbol}static dereference(value,type){if(Typed.isTyped(value)){if(value.type!==type){throw new Error(`invalid type: expecetd ${type}, got ${value.type}`)}return value.value}return value}}class AddressCoder extends Coder{constructor(localName){super("address","address",localName,false)}defaultValue(){return"0x0000000000000000000000000000000000000000"}encode(writer,_value){let value=Typed.dereference(_value,"string");try{value=getAddress(value)}catch(error){return this._throwError(error.message,_value)}return writer.writeValue(value)}decode(reader){return getAddress(toBeHex(reader.readValue(),20))}}class AnonymousCoder extends Coder{coder;constructor(coder){super(coder.name,coder.type,"_",coder.dynamic);this.coder=coder}defaultValue(){return this.coder.defaultValue()}encode(writer,value){return this.coder.encode(writer,value)}decode(reader){return this.coder.decode(reader)}}function pack(writer,coders,values){let arrayValues=[];if(Array.isArray(values)){arrayValues=values}else if(values&&typeof values==="object"){let unique={};arrayValues=coders.map(coder=>{const name=coder.localName;assert$1(name,"cannot encode object for signature with missing names","INVALID_ARGUMENT",{argument:"values",info:{coder:coder},value:values});assert$1(!unique[name],"cannot encode object for signature with duplicate names","INVALID_ARGUMENT",{argument:"values",info:{coder:coder},value:values});unique[name]=true;return values[name]})}else{assertArgument(false,"invalid tuple value","tuple",values)}assertArgument(coders.length===arrayValues.length,"types/value length mismatch","tuple",values);let staticWriter=new Writer;let dynamicWriter=new Writer;let updateFuncs=[];coders.forEach((coder,index)=>{let value=arrayValues[index];if(coder.dynamic){let dynamicOffset=dynamicWriter.length;coder.encode(dynamicWriter,value);let updateFunc=staticWriter.writeUpdatableValue();updateFuncs.push(baseOffset=>{updateFunc(baseOffset+dynamicOffset)})}else{coder.encode(staticWriter,value)}});updateFuncs.forEach(func=>{func(staticWriter.length)});let length=writer.appendWriter(staticWriter);length+=writer.appendWriter(dynamicWriter);return length}function unpack(reader,coders){let values=[];let keys=[];let baseReader=reader.subReader(0);coders.forEach(coder=>{let value=null;if(coder.dynamic){let offset=reader.readIndex();let offsetReader=baseReader.subReader(offset);try{value=coder.decode(offsetReader)}catch(error){if(isError(error,"BUFFER_OVERRUN")){throw error}value=error;value.baseType=coder.name;value.name=coder.localName;value.type=coder.type}}else{try{value=coder.decode(reader)}catch(error){if(isError(error,"BUFFER_OVERRUN")){throw error}value=error;value.baseType=coder.name;value.name=coder.localName;value.type=coder.type}}if(value==undefined){throw new Error("investigate")}values.push(value);keys.push(coder.localName||null)});return Result.fromItems(values,keys)}class ArrayCoder extends Coder{coder;length;constructor(coder,length,localName){const type=coder.type+"["+(length>=0?length:"")+"]";const dynamic=length===-1||coder.dynamic;super("array",type,localName,dynamic);defineProperties(this,{coder:coder,length:length})}defaultValue(){const defaultChild=this.coder.defaultValue();const result=[];for(let i=0;ibounds||value<-(bounds+BN_1$2)){this._throwError("value out-of-bounds",_value)}value=toTwos(value,8*WordSize)}else if(valuemask(maxUintValue,this.size*8)){this._throwError("value out-of-bounds",_value)}return writer.writeValue(value)}decode(reader){let value=mask(reader.readValue(),this.size*8);if(this.signed){value=fromTwos(value,this.size*8)}return value}}class StringCoder extends DynamicBytesCoder{constructor(localName){super("string",localName)}defaultValue(){return""}encode(writer,_value){return super.encode(writer,toUtf8Bytes(Typed.dereference(_value,"string")))}decode(reader){return toUtf8String(super.decode(reader))}}class TupleCoder extends Coder{coders;constructor(coders,localName){let dynamic=false;const types=[];coders.forEach(coder=>{if(coder.dynamic){dynamic=true}types.push(coder.type)});const type="tuple("+types.join(",")+")";super("tuple",type,localName,dynamic);defineProperties(this,{coders:Object.freeze(coders.slice())})}defaultValue(){const values=[];this.coders.forEach(coder=>{values.push(coder.defaultValue())});const uniqueNames=this.coders.reduce((accum,coder)=>{const name=coder.localName;if(name){if(!accum[name]){accum[name]=0}accum[name]++}return accum},{});this.coders.forEach((coder,index)=>{let name=coder.localName;if(!name||uniqueNames[name]!==1){return}if(name==="length"){name="_length"}if(values[name]!=null){return}values[name]=values[index]});return Object.freeze(values)}encode(writer,_value){const value=Typed.dereference(_value,"tuple");return pack(writer,this.coders,value)}decode(reader){return unpack(reader,this.coders)}}function id(value){return keccak256(toUtf8Bytes(value))}function decode_arithmetic(bytes){let pos=0;function u16(){return bytes[pos++]<<8|bytes[pos++]}let symbol_count=u16();let total=1;let acc=[0,1];for(let i=1;i>--read_width&1}const N=31;const FULL=2**N;const HALF=FULL>>>1;const QRTR=HALF>>1;const MASK=FULL-1;let register=0;for(let i=0;i1){let mid=start+end>>>1;if(value>>1|read_bit();a=a<<1^HALF;b=(b^HALF)<<1|HALF|1}low=a;range=1+b-a}let offset=symbol_count-4;return symbols.map(x=>{switch(x-offset){case 3:return offset+65792+(bytes[pos_payload++]<<16|bytes[pos_payload++]<<8|bytes[pos_payload++]);case 2:return offset+256+(bytes[pos_payload++]<<8|bytes[pos_payload++]);case 1:return offset+bytes[pos_payload++];default:return x-1}})}function read_payload(v){let pos=0;return()=>v[pos++]}function read_compressed_payload(s){return read_payload(decode_arithmetic(unsafe_atob(s)))}function unsafe_atob(s){let lookup=[];[..."ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"].forEach((c,i)=>lookup[c.charCodeAt(0)]=i);let n=s.length;let ret=new Uint8Array(6*n>>3);for(let i=0,pos=0,width=0,carry=0;i=8){ret[pos++]=carry>>(width-=8)}}return ret}function signed(i){return i&1?~i>>1:i>>1}function read_deltas(n,next){let v=Array(n);for(let i=0,x=0;i{let v=read_sorted(next);if(v.length)return v})}function read_mapped(next){let ret=[];while(true){let w=next();if(w==0)break;ret.push(read_linear_table(w,next))}while(true){let w=next()-1;if(w<0)break;ret.push(read_replacement_table(w,next))}return ret.flat()}function read_array_while(next){let v=[];while(true){let x=next(v.length);if(!x)break;v.push(x)}return v}function read_transposed(n,w,next){let m=Array(n).fill().map(()=>[]);for(let i=0;im[j].push(x))}return m}function read_linear_table(w,next){let dx=1+next();let dy=next();let vN=read_array_while(next);let m=read_transposed(vN.length,1+w,next);return m.flatMap((v,i)=>{let[x,...ys]=v;return Array(vN[i]).fill().map((_,j)=>{let j_dy=j*dy;return[x+j*dx,ys.map(y=>y+j_dy)]})})}function read_replacement_table(w,next){let n=1+next();let m=read_transposed(n,1+w,next);return m.map(v=>[v[0],v.slice(1)])}var r$1=read_compressed_payload("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");const FENCED=new Map([[8217,"apostrophe"],[8260,"fraction slash"],[12539,"middle dot"]]);const NSM_MAX=4;function hex_cp(cp){return cp.toString(16).toUpperCase().padStart(2,"0")}function quote_cp(cp){return`{${hex_cp(cp)}}`}function explode_cp(s){let cps=[];for(let pos=0,len=s.length;pos>24&255}function unpack_cp(packed){return packed&16777215}const SHIFTED_RANK=new Map(read_sorted_arrays(r).flatMap((v,i)=>v.map(x=>[x,i+1<<24])));const EXCLUSIONS=new Set(read_sorted(r));const DECOMP=new Map;const RECOMP=new Map;for(let[cp,cps]of read_mapped(r)){if(!EXCLUSIONS.has(cp)&&cps.length==2){let[a,b]=cps;let bucket=RECOMP.get(a);if(!bucket){bucket=new Map;RECOMP.set(a,bucket)}bucket.set(b,cp)}DECOMP.set(cp,cps.reverse())}const S0=44032;const L0=4352;const V0=4449;const T0=4519;const L_COUNT=19;const V_COUNT=21;const T_COUNT=28;const N_COUNT=V_COUNT*T_COUNT;const S_COUNT=L_COUNT*N_COUNT;const S1=S0+S_COUNT;const L1=L0+L_COUNT;const V1=V0+V_COUNT;const T1$1=T0+T_COUNT;function is_hangul(cp){return cp>=S0&&cp=L0&&a=V0&&bT0&&b0)add(T0+t_index)}else{let mapped=DECOMP.get(cp);if(mapped){buf.push(...mapped)}else{add(cp)}}if(!buf.length)break;cp=buf.pop()}}if(check_order&&ret.length>1){let prev_cc=unpack_cc(ret[0]);for(let i=1;i0&&prev_cc>=cc){if(cc==0){ret.push(prev_cp,...stack);stack.length=0;prev_cp=cp}else{stack.push(cp)}prev_cc=cc}else{let composed=compose_pair(prev_cp,cp);if(composed>=0){prev_cp=composed}else if(prev_cc==0&&cc==0){ret.push(prev_cp);prev_cp=cp}else{stack.push(cp);prev_cc=cc}}}if(prev_cp>=0){ret.push(prev_cp,...stack)}return ret}function nfd(cps){return decomposed(cps).map(unpack_cp)}function nfc(cps){return composed_from_decomposed(decomposed(cps))}const STOP=46;const FE0F=65039;const STOP_CH=".";const UNIQUE_PH=1;const HYPHEN=45;function read_set(){return new Set(read_sorted(r$1))}const MAPPED=new Map(read_mapped(r$1));const IGNORED=read_set();const CM=read_set();const NSM=new Set(read_sorted(r$1).map(function(i){return this[i]},[...CM]));const ESCAPE=read_set();const NFC_CHECK=read_set();const CHUNKS=read_sorted_arrays(r$1);function read_chunked(){return new Set([read_sorted(r$1).map(i=>CHUNKS[i]),read_sorted(r$1)].flat(2))}const UNRESTRICTED=r$1();const GROUPS=read_array_while(i=>{let N=read_array_while(r$1).map(x=>x+96);if(N.length){let R=i>=UNRESTRICTED;N[0]-=32;N=str_from_cps(N);if(R)N=`Restricted[${N}]`;let P=read_chunked();let Q=read_chunked();let V=[...P,...Q].sort((a,b)=>a-b);let M=!r$1();return{N:N,P:P,M:M,R:R,V:new Set(V)}}});const WHOLE_VALID=read_set();const WHOLE_MAP=new Map;[...WHOLE_VALID,...read_set()].sort((a,b)=>a-b).map((cp,i,v)=>{let d=r$1();let w=v[i]=d?v[i-d]:{V:[],M:new Map};w.V.push(cp);if(!WHOLE_VALID.has(cp)){WHOLE_MAP.set(cp,w)}});for(let{V,M}of new Set(WHOLE_MAP.values())){let recs=[];for(let cp of V){let gs=GROUPS.filter(g=>g.V.has(cp));let rec=recs.find(({G})=>gs.some(g=>G.has(g)));if(!rec){rec={G:new Set,V:[]};recs.push(rec)}rec.V.push(cp);gs.forEach(g=>rec.G.add(g))}let union=recs.flatMap(({G})=>[...G]);for(let{G,V}of recs){let complement=new Set(union.filter(g=>!G.has(g)));for(let cp of V){M.set(cp,complement)}}}let union=new Set;let multi=new Set;for(let g of GROUPS){for(let cp of g.V){(union.has(cp)?multi:union).add(cp)}}for(let cp of union){if(!WHOLE_MAP.has(cp)&&!multi.has(cp)){WHOLE_MAP.set(cp,UNIQUE_PH)}}const VALID=new Set([...union,...nfd(union)]);const EMOJI_SORTED=read_sorted(r$1);const EMOJI_ROOT=read_emoji_trie([]);function read_emoji_trie(cps){let B=read_array_while(()=>{let keys=read_sorted(r$1).map(i=>EMOJI_SORTED[i]);if(keys.length)return read_emoji_trie(keys)}).sort((a,b)=>b.Q.size-a.Q.size);let temp=r$1();let V=temp%3;temp=temp/3|0;let F=temp&1;temp>>=1;let S=temp&1;let C=temp&2;return{B:B,V:V,F:F,S:S,C:C,Q:new Set(cps)}}class Emoji extends Array{get is_emoji(){return true}}function safe_str_from_cps(cps,quoter=quote_cp){let buf=[];if(is_combining_mark(cps[0]))buf.push("◌");let prev=0;let n=cps.length;for(let i=0;i=4&&cps[2]==HYPHEN&&cps[3]==HYPHEN){throw new Error("invalid label extension")}}function check_leading_underscore(cps){const UNDERSCORE=95;for(let i=cps.lastIndexOf(UNDERSCORE);i>0;){if(cps[--i]!==UNDERSCORE){throw new Error("underscore allowed only at start")}}}function check_fenced(cps){let cp=cps[0];let prev=FENCED.get(cp);if(prev)throw error_placement(`leading ${prev}`);let n=cps.length;let last=-1;for(let i=1;istr_from_cps(process(explode_cp(label),nf).flatMap(x=>x.is_emoji?filter_fe0f(x):x))).join(STOP_CH)}function ens_normalize(name){return flatten(ens_split(name))}function ens_beautify(name){let split=ens_split(name,true);for(let{type,output,error}of split){if(error)continue;if(type!=="Greek"){let prev=0;while(true){let next=output.indexOf(958,prev);if(next<0)break;output[next]=926;prev=next+1}}}return flatten(split)}function ens_split(name,preserve_emoji){let offset=0;return name.split(STOP_CH).map(label=>{let input=explode_cp(label);let info={input:input,offset:offset};offset+=input.length+1;let norm;try{let tokens=info.tokens=process(input,nfc);let token_count=tokens.length;let type;if(!token_count){throw new Error(`empty label`)}else{let chars=tokens[0];let emoji=token_count>1||chars.is_emoji;if(!emoji&&chars.every(cp=>cp<128)){norm=chars;check_leading_underscore(norm);check_label_extension(norm);type="ASCII"}else{if(emoji){info.emoji=true;chars=tokens.flatMap(x=>x.is_emoji?[]:x)}norm=tokens.flatMap(x=>!preserve_emoji&&x.is_emoji?filter_fe0f(x):x);check_leading_underscore(norm);if(!chars.length){type="Emoji"}else{if(CM.has(norm[0]))throw error_placement("leading combining mark");for(let i=1;iset.has(g)):[...set];if(!maker.length)return}else{shared.push(cp)}}if(maker){for(let g of maker){if(shared.every(cp=>g.V.has(cp))){throw new Error(`whole-script confusable: ${group.N}/${g.N}`)}}}}function determine_group(unique){let groups=GROUPS;for(let cp of unique){let gs=groups.filter(g=>g.V.has(cp));if(!gs.length){if(groups===GROUPS){throw error_disallowed(cp)}else{throw error_group_member(groups[0],cp)}}groups=gs;if(gs.length==1)break}return groups}function flatten(split){return split.map(({input,error,output})=>{if(error){let msg=error.message;throw new Error(split.length==1?msg:`Invalid label ${bidi_qq(safe_str_from_cps(input))}: ${msg}`)}return str_from_cps(output)}).join(STOP_CH)}function error_disallowed(cp){return new Error(`disallowed character: ${quoted_cp(cp)}`)}function error_group_member(g,cp){let quoted=quoted_cp(cp);let gg=GROUPS.find(g=>g.P.has(cp));if(gg){quoted=`${gg.N} ${quoted}`}return new Error(`illegal mixture: ${g.N} + ${quoted}`)}function error_placement(where){return new Error(`illegal placement: ${where}`)}function check_group(g,cps){let{V,M}=g;for(let cp of cps){if(!V.has(cp)){throw error_group_member(g,cp)}}if(M){let decomposed=nfd(cps);for(let i=1,e=decomposed.length;iNSM_MAX){throw new Error(`non-spacing marks: too many ${bidi_qq(safe_str_from_cps(decomposed.slice(i-1,j)))} (${j-i}/${NSM_MAX})`)}i=j}}}}function process(input,nf){let ret=[];let chars=[];input=input.slice().reverse();while(input.length){let emoji=consume_emoji_reversed(input);if(emoji){if(chars.length){ret.push(nf(chars));chars=[]}ret.push(emoji)}else{let cp=input.pop();if(VALID.has(cp)){chars.push(cp)}else{let cps=MAPPED.get(cp);if(cps){chars.push(...cps)}else if(!IGNORED.has(cp)){throw error_disallowed(cp)}}}}if(chars.length){ret.push(nf(chars))}return ret}function filter_fe0f(cps){return cps.filter(cp=>cp!=FE0F)}function consume_emoji_reversed(cps,eaten){let node=EMOJI_ROOT;let emoji;let saved;let stack=[];let pos=cps.length;if(eaten)eaten.length=0;while(pos){let cp=cps[--pos];node=node.B.find(x=>x.Q.has(cp));if(!node)break;if(node.S){saved=cp}else if(node.C){if(cp===saved)break}stack.push(cp);if(node.F){stack.push(FE0F);if(pos>0&&cps[pos-1]==FE0F)pos--}if(node.V){emoji=conform_emoji_copy(stack,node);if(eaten)eaten.push(...cps.slice(pos).reverse());cps.length=pos}}return emoji}function conform_emoji_copy(cps,node){let copy=Emoji.from(cps);if(node.V==2)copy.splice(1,1);return copy}function ens_emoji(){let ret=[];build(EMOJI_ROOT,[]);return ret.sort(compare_arrays);function build(node,cps,saved){if(node.S){saved=cps[cps.length-1]}else if(node.C){if(saved===cps[cps.length-1])return}if(node.F)cps.push(FE0F);if(node.V)ret.push(conform_emoji_copy(cps,node));for(let br of node.B){for(let cp of br.Q){build(br,[...cps,cp],saved)}}}}const TY_VALID="valid";const TY_MAPPED="mapped";const TY_IGNORED="ignored";const TY_DISALLOWED="disallowed";const TY_EMOJI="emoji";const TY_NFC="nfc";const TY_STOP="stop";function ens_tokenize(name,{nf=true}={}){let input=explode_cp(name).reverse();let eaten=[];let tokens=[];while(input.length){let emoji=consume_emoji_reversed(input,eaten);if(emoji){tokens.push({type:TY_EMOJI,emoji:emoji,input:eaten.slice(),cps:filter_fe0f(emoji)})}else{let cp=input.pop();if(cp==STOP){tokens.push({type:TY_STOP,cp:cp})}else if(VALID.has(cp)){tokens.push({type:TY_VALID,cps:[cp]})}else if(IGNORED.has(cp)){tokens.push({type:TY_IGNORED,cp:cp})}else{let cps=MAPPED.get(cp);if(cps){tokens.push({type:TY_MAPPED,cp:cp,cps:cps.slice()})}else{tokens.push({type:TY_DISALLOWED,cp:cp})}}}}if(nf){for(let i=0,start=-1;iis_valid_or_mapped(x.type)?x.cps:[]);let cps=nfc(cps0);if(compare_arrays(cps,cps0)){tokens.splice(start,end-start,{type:TY_NFC,input:cps0,cps:cps,tokens0:collapse_valid_tokens(slice),tokens:ens_tokenize(str_from_cps(cps),{nf:false})});i=start}else{i=end-1}start=-1}else{start=i}}else if(token.type!==TY_IGNORED){start=-1}}}return collapse_valid_tokens(tokens)}function is_valid_or_mapped(type){return type==TY_VALID||type==TY_MAPPED}function requires_check(cps){return cps.some(cp=>NFC_CHECK.has(cp))}function collapse_valid_tokens(tokens){for(let i=0;ix.cps)})}}return tokens}const Zeros=new Uint8Array(32);Zeros.fill(0);function checkComponent(comp){assertArgument(comp.length!==0,"invalid ENS name; empty component","comp",comp);return comp}function ensNameSplit(name){const bytes=toUtf8Bytes(ensNormalize(name));const comps=[];if(name.length===0){return comps}let last=0;for(let i=0;i{if(comp.length>63){throw new Error("invalid DNS encoded entry; length exceeds 63 bytes")}const bytes=new Uint8Array(comp.length+1);bytes.set(comp,1);bytes[0]=bytes.length-1;return bytes})))+"00"}function accessSetify(addr,storageKeys){return{address:getAddress(addr),storageKeys:storageKeys.map((storageKey,index)=>{assertArgument(isHexString(storageKey,32),"invalid slot",`storageKeys[${index}]`,storageKey);return storageKey.toLowerCase()})}}function accessListify(value){if(Array.isArray(value)){return value.map((set,index)=>{if(Array.isArray(set)){assertArgument(set.length===2,"invalid slot set",`value[${index}]`,set);return accessSetify(set[0],set[1])}assertArgument(set!=null&&typeof set==="object","invalid address-slot set","value",value);return accessSetify(set.address,set.storageKeys)})}assertArgument(value!=null&&typeof value==="object","invalid access list","value",value);const result=Object.keys(value).map(addr=>{const storageKeys=value[addr].reduce((accum,storageKey)=>{accum[storageKey]=true;return accum},{});return accessSetify(addr,Object.keys(storageKeys).sort())});result.sort((a,b)=>a.address.localeCompare(b.address));return result}function computeAddress(key){let pubkey;if(typeof key==="string"){pubkey=SigningKey.computePublicKey(key,false)}else{pubkey=key.publicKey}return getAddress(keccak256("0x"+pubkey.substring(4)).substring(26))}function recoverAddress(digest,signature){return computeAddress(SigningKey.recoverPublicKey(digest,signature))}const BN_0$4=BigInt(0);const BN_2$2=BigInt(2);const BN_27=BigInt(27);const BN_28=BigInt(28);const BN_35=BigInt(35);const BN_MAX_UINT=BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");function handleAddress(value){if(value==="0x"){return null}return getAddress(value)}function handleAccessList(value,param){try{return accessListify(value)}catch(error){assertArgument(false,error.message,param,value)}}function handleNumber(_value,param){if(_value==="0x"){return 0}return getNumber(_value,param)}function handleUint(_value,param){if(_value==="0x"){return BN_0$4}const value=getBigInt(_value,param);assertArgument(value<=BN_MAX_UINT,"value exceeds uint size",param,value);return value}function formatNumber(_value,name){const value=getBigInt(_value,"value");const result=toBeArray(value);assertArgument(result.length<=32,`value too large`,`tx.${name}`,value);return result}function formatAccessList(value){return accessListify(value).map(set=>[set.address,set.storageKeys])}function _parseLegacy(data){const fields=decodeRlp(data);assertArgument(Array.isArray(fields)&&(fields.length===9||fields.length===6),"invalid field count for legacy transaction","data",data);const tx={type:0,nonce:handleNumber(fields[0],"nonce"),gasPrice:handleUint(fields[1],"gasPrice"),gasLimit:handleUint(fields[2],"gasLimit"),to:handleAddress(fields[3]),value:handleUint(fields[4],"value"),data:hexlify(fields[5]),chainId:BN_0$4};if(fields.length===6){return tx}const v=handleUint(fields[6],"v");const r=handleUint(fields[7],"r");const s=handleUint(fields[8],"s");if(r===BN_0$4&&s===BN_0$4){tx.chainId=v}else{let chainId=(v-BN_35)/BN_2$2;if(chainId=this.maxPriorityFeePerGas,"priorityFee cannot be more than maxFee","BAD_DATA",{value:this})}assert$1(!hasFee||this.type!==0&&this.type!==1,"transaction type cannot have maxFeePerGas or maxPriorityFeePerGas","BAD_DATA",{value:this});assert$1(this.type!==0||!hasAccessList,"legacy transaction cannot have accessList","BAD_DATA",{value:this});const types=[];if(this.type!=null){types.push(this.type)}else{if(hasFee){types.push(2)}else if(hasGasPrice){types.push(1);if(!hasAccessList){types.push(0)}}else if(hasAccessList){types.push(1);types.push(2)}else{types.push(0);types.push(1);types.push(2)}}types.sort();return types}isLegacy(){return this.type===0}isBerlin(){return this.type===1}isLondon(){return this.type===2}clone(){return Transaction.from(this)}toJSON(){const s=v=>{if(v==null){return null}return v.toString()};return{type:this.type,to:this.to,data:this.data,nonce:this.nonce,gasLimit:s(this.gasLimit),gasPrice:s(this.gasPrice),maxPriorityFeePerGas:s(this.maxPriorityFeePerGas),maxFeePerGas:s(this.maxFeePerGas),value:s(this.value),chainId:s(this.chainId),sig:this.signature?this.signature.toJSON():null,accessList:this.accessList}}static from(tx){if(tx==null){return new Transaction}if(typeof tx==="string"){const payload=getBytes(tx);if(payload[0]>=127){return Transaction.from(_parseLegacy(payload))}switch(payload[0]){case 1:return Transaction.from(_parseEip2930(payload));case 2:return Transaction.from(_parseEip1559(payload))}assert$1(false,"unsupported transaction type","UNSUPPORTED_OPERATION",{operation:"from"})}const result=new Transaction;if(tx.type!=null){result.type=tx.type}if(tx.to!=null){result.to=tx.to}if(tx.nonce!=null){result.nonce=tx.nonce}if(tx.gasLimit!=null){result.gasLimit=tx.gasLimit}if(tx.gasPrice!=null){result.gasPrice=tx.gasPrice}if(tx.maxPriorityFeePerGas!=null){result.maxPriorityFeePerGas=tx.maxPriorityFeePerGas}if(tx.maxFeePerGas!=null){result.maxFeePerGas=tx.maxFeePerGas}if(tx.data!=null){result.data=tx.data}if(tx.value!=null){result.value=tx.value}if(tx.chainId!=null){result.chainId=tx.chainId}if(tx.signature!=null){result.signature=Signature.from(tx.signature)}if(tx.accessList!=null){result.accessList=tx.accessList}if(tx.hash!=null){assertArgument(result.isSigned(),"unsigned transaction cannot define hash","tx",tx);assertArgument(result.hash===tx.hash,"hash mismatch","tx",tx)}if(tx.from!=null){assertArgument(result.isSigned(),"unsigned transaction cannot define from","tx",tx);assertArgument(result.from.toLowerCase()===(tx.from||"").toLowerCase(),"from mismatch","tx",tx)}return result}}null;function hashMessage(message){if(typeof message==="string"){message=toUtf8Bytes(message)}return keccak256(concat([toUtf8Bytes(MessagePrefix),toUtf8Bytes(String(message.length)),message]))}function verifyMessage(message,sig){const digest=hashMessage(message);return recoverAddress(digest,sig)}const regexBytes=new RegExp("^bytes([0-9]+)$");const regexNumber=new RegExp("^(u?int)([0-9]*)$");const regexArray=new RegExp("^(.*)\\[([0-9]*)\\]$");function _pack(type,value,isArray){switch(type){case"address":if(isArray){return getBytes(zeroPadValue(value,32))}return getBytes(getAddress(value));case"string":return toUtf8Bytes(value);case"bytes":return getBytes(value);case"bool":value=!!value?"0x01":"0x00";if(isArray){return getBytes(zeroPadValue(value,32))}return getBytes(value)}let match=type.match(regexNumber);if(match){let signed=match[1]==="int";let size=parseInt(match[2]||"256");assertArgument((!match[2]||match[2]===String(size))&&size%8===0&&size!==0&&size<=256,"invalid number type","type",type);if(isArray){size=256}if(signed){value=toTwos(value,size)}return getBytes(zeroPadValue(toBeArray(value),size/8))}match=type.match(regexBytes);if(match){const size=parseInt(match[1]);assertArgument(String(size)===match[1]&&size!==0&&size<=32,"invalid bytes type","type",type);assertArgument(dataLength(value)===size,`invalid value for ${type}`,"value",value);if(isArray){return getBytes(zeroPadBytes(value,32))}return value}match=type.match(regexArray);if(match&&Array.isArray(value)){const baseType=match[1];const count=parseInt(match[2]||String(value.length));assertArgument(count===value.length,`invalid array length for ${type}`,"value",value);const result=[];value.forEach(function(value){result.push(_pack(baseType,value,true))});return getBytes(concat(result))}assertArgument(false,"invalid type","type",type)}function solidityPacked(types,values){assertArgument(types.length===values.length,"wrong number of values; expected ${ types.length }","values",values);const tight=[];types.forEach(function(type,index){tight.push(_pack(type,values[index]))});return hexlify(concat(tight))}function solidityPackedKeccak256(types,values){return keccak256(solidityPacked(types,values))}function solidityPackedSha256(types,values){return sha256(solidityPacked(types,values))}const padding=new Uint8Array(32);padding.fill(0);const BN__1=BigInt(-1);const BN_0$3=BigInt(0);const BN_1$1=BigInt(1);const BN_MAX_UINT256=BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");function hexPadRight(value){const bytes=getBytes(value);const padOffset=bytes.length%32;if(padOffset){return concat([bytes,padding.slice(padOffset)])}return hexlify(bytes)}const hexTrue=toBeHex(BN_1$1,32);const hexFalse=toBeHex(BN_0$3,32);const domainFieldTypes={name:"string",version:"string",chainId:"uint256",verifyingContract:"address",salt:"bytes32"};const domainFieldNames=["name","version","chainId","verifyingContract","salt"];function checkString(key){return function(value){assertArgument(typeof value==="string",`invalid domain value for ${JSON.stringify(key)}`,`domain.${key}`,value);return value}}const domainChecks={name:checkString("name"),version:checkString("version"),chainId:function(_value){const value=getBigInt(_value,"domain.chainId");assertArgument(value>=0,"invalid chain ID","domain.chainId",_value);if(Number.isSafeInteger(value)){return Number(value)}return toQuantity(value)},verifyingContract:function(value){try{return getAddress(value).toLowerCase()}catch(error){}assertArgument(false,`invalid domain value "verifyingContract"`,"domain.verifyingContract",value)},salt:function(value){const bytes=getBytes(value,"domain.salt");assertArgument(bytes.length===32,`invalid domain value "salt"`,"domain.salt",value);return hexlify(bytes)}};function getBaseEncoder(type){{const match=type.match(/^(u?)int(\d*)$/);if(match){const signed=match[1]==="";const width=parseInt(match[2]||"256");assertArgument(width%8===0&&width!==0&&width<=256&&(match[2]==null||match[2]===String(width)),"invalid numeric width","type",type);const boundsUpper=mask(BN_MAX_UINT256,signed?width-1:width);const boundsLower=signed?(boundsUpper+BN_1$1)*BN__1:BN_0$3;return function(_value){const value=getBigInt(_value,"value");assertArgument(value>=boundsLower&&value<=boundsUpper,`value out-of-bounds for ${type}`,"value",value);return toBeHex(signed?toTwos(value,256):value,32)}}}{const match=type.match(/^bytes(\d+)$/);if(match){const width=parseInt(match[1]);assertArgument(width!==0&&width<=32&&match[1]===String(width),"invalid bytes width","type",type);return function(value){const bytes=getBytes(value);assertArgument(bytes.length===width,`invalid length for ${type}`,"value",value);return hexPadRight(value)}}}switch(type){case"address":return function(value){return zeroPadValue(getAddress(value),32)};case"bool":return function(value){return!value?hexFalse:hexTrue};case"bytes":return function(value){return keccak256(value)};case"string":return function(value){return id(value)}}return null}function encodeType(name,fields){return`${name}(${fields.map(({name,type})=>type+" "+name).join(",")})`}class TypedDataEncoder{primaryType;#types;get types(){return JSON.parse(this.#types)}#fullTypes;#encoderCache;constructor(types){this.#types=JSON.stringify(types);this.#fullTypes=new Map;this.#encoderCache=new Map;const links=new Map;const parents=new Map;const subtypes=new Map;Object.keys(types).forEach(type=>{links.set(type,new Set);parents.set(type,[]);subtypes.set(type,new Set)});for(const name in types){const uniqueNames=new Set;for(const field of types[name]){assertArgument(!uniqueNames.has(field.name),`duplicate variable name ${JSON.stringify(field.name)} in ${JSON.stringify(name)}`,"types",types);uniqueNames.add(field.name);const baseType=field.type.match(/^([^\x5b]*)(\x5b|$)/)[1]||null;assertArgument(baseType!==name,`circular type reference to ${JSON.stringify(baseType)}`,"types",types);const encoder=getBaseEncoder(baseType);if(encoder){continue}assertArgument(parents.has(baseType),`unknown type ${JSON.stringify(baseType)}`,"types",types);parents.get(baseType).push(name);links.get(name).add(baseType)}}const primaryTypes=Array.from(parents.keys()).filter(n=>parents.get(n).length===0);assertArgument(primaryTypes.length!==0,"missing primary type","types",types);assertArgument(primaryTypes.length===1,`ambiguous primary types or unused types: ${primaryTypes.map(t=>JSON.stringify(t)).join(", ")}`,"types",types);defineProperties(this,{primaryType:primaryTypes[0]});function checkCircular(type,found){assertArgument(!found.has(type),`circular type reference to ${JSON.stringify(type)}`,"types",types);found.add(type);for(const child of links.get(type)){if(!parents.has(child)){continue}checkCircular(child,found);for(const subtype of found){subtypes.get(subtype).add(child)}}found.delete(type)}checkCircular(this.primaryType,new Set);for(const[name,set]of subtypes){const st=Array.from(set);st.sort();this.#fullTypes.set(name,encodeType(name,types[name])+st.map(t=>encodeType(t,types[t])).join(""))}}getEncoder(type){let encoder=this.#encoderCache.get(type);if(!encoder){encoder=this.#getEncoder(type);this.#encoderCache.set(type,encoder)}return encoder}#getEncoder(type){{const encoder=getBaseEncoder(type);if(encoder){return encoder}}const match=type.match(/^(.*)(\x5b(\d*)\x5d)$/);if(match){const subtype=match[1];const subEncoder=this.getEncoder(subtype);return value=>{assertArgument(!match[3]||parseInt(match[3])===value.length,`array length mismatch; expected length ${parseInt(match[3])}`,"value",value);let result=value.map(subEncoder);if(this.#fullTypes.has(subtype)){result=result.map(keccak256)}return keccak256(concat(result))}}const fields=this.types[type];if(fields){const encodedType=id(this.#fullTypes.get(type));return value=>{const values=fields.map(({name,type})=>{const result=this.getEncoder(type)(value[name]);if(this.#fullTypes.has(type)){return keccak256(result)}return result});values.unshift(encodedType);return concat(values)}}assertArgument(false,`unknown type: ${type}`,"type",type)}encodeType(name){const result=this.#fullTypes.get(name);assertArgument(result,`unknown type: ${JSON.stringify(name)}`,"name",name);return result}encodeData(type,value){return this.getEncoder(type)(value)}hashStruct(name,value){return keccak256(this.encodeData(name,value))}encode(value){return this.encodeData(this.primaryType,value)}hash(value){return this.hashStruct(this.primaryType,value)}_visit(type,value,callback){{const encoder=getBaseEncoder(type);if(encoder){return callback(type,value)}}const match=type.match(/^(.*)(\x5b(\d*)\x5d)$/);if(match){assertArgument(!match[3]||parseInt(match[3])===value.length,`array length mismatch; expected length ${parseInt(match[3])}`,"value",value);return value.map(v=>this._visit(match[1],v,callback))}const fields=this.types[type];if(fields){return fields.reduce((accum,{name,type})=>{accum[name]=this._visit(type,value[name],callback);return accum},{})}assertArgument(false,`unknown type: ${type}`,"type",type)}visit(value,callback){return this._visit(this.primaryType,value,callback)}static from(types){return new TypedDataEncoder(types)}static getPrimaryType(types){return TypedDataEncoder.from(types).primaryType}static hashStruct(name,types,value){return TypedDataEncoder.from(types).hashStruct(name,value)}static hashDomain(domain){const domainFields=[];for(const name in domain){if(domain[name]==null){continue}const type=domainFieldTypes[name];assertArgument(type,`invalid typed-data domain key: ${JSON.stringify(name)}`,"domain",domain);domainFields.push({name:name,type:type})}domainFields.sort((a,b)=>{return domainFieldNames.indexOf(a.name)-domainFieldNames.indexOf(b.name)});return TypedDataEncoder.hashStruct("EIP712Domain",{EIP712Domain:domainFields},domain)}static encode(domain,types,value){return concat(["0x1901",TypedDataEncoder.hashDomain(domain),TypedDataEncoder.from(types).hash(value)])}static hash(domain,types,value){return keccak256(TypedDataEncoder.encode(domain,types,value))}static async resolveNames(domain,types,value,resolveName){domain=Object.assign({},domain);for(const key in domain){if(domain[key]==null){delete domain[key]}}const ensCache={};if(domain.verifyingContract&&!isHexString(domain.verifyingContract,20)){ensCache[domain.verifyingContract]="0x"}const encoder=TypedDataEncoder.from(types);encoder.visit(value,(type,value)=>{if(type==="address"&&!isHexString(value,20)){ensCache[value]="0x"}return value});for(const name in ensCache){ensCache[name]=await resolveName(name)}if(domain.verifyingContract&&ensCache[domain.verifyingContract]){domain.verifyingContract=ensCache[domain.verifyingContract]}value=encoder.visit(value,(type,value)=>{if(type==="address"&&ensCache[value]){return ensCache[value]}return value});return{domain:domain,value:value}}static getPayload(domain,types,value){TypedDataEncoder.hashDomain(domain);const domainValues={};const domainTypes=[];domainFieldNames.forEach(name=>{const value=domain[name];if(value==null){return}domainValues[name]=domainChecks[name](value);domainTypes.push({name:name,type:domainFieldTypes[name]})});const encoder=TypedDataEncoder.from(types);const typesWithDomain=Object.assign({},types);assertArgument(typesWithDomain.EIP712Domain==null,"types must not contain EIP712Domain type","types.EIP712Domain",types);typesWithDomain.EIP712Domain=domainTypes;encoder.encode(value);return{types:typesWithDomain,domain:domainValues,primaryType:encoder.primaryType,message:encoder.visit(value,(type,value)=>{if(type.match(/^bytes(\d*)/)){return hexlify(getBytes(value))}if(type.match(/^u?int/)){return getBigInt(value).toString()}switch(type){case"address":return value.toLowerCase();case"bool":return!!value;case"string":assertArgument(typeof value==="string","invalid string","value",value);return value}assertArgument(false,"unsupported type","type",type)})}}}function verifyTypedData(domain,types,value,signature){return recoverAddress(TypedDataEncoder.hash(domain,types,value),signature)}function setify(items){const result=new Set;items.forEach(k=>result.add(k));return Object.freeze(result)}const _kwVisib="constant external internal payable private public pure view";const KwVisib=setify(_kwVisib.split(" "));const _kwTypes="constructor error event fallback function receive struct";const KwTypes=setify(_kwTypes.split(" "));const _kwModifiers="calldata memory storage payable indexed";const KwModifiers=setify(_kwModifiers.split(" "));const _kwOther="tuple returns";const _keywords=[_kwTypes,_kwModifiers,_kwOther,_kwVisib].join(" ");const Keywords=setify(_keywords.split(" "));const SimpleTokens={"(":"OPEN_PAREN",")":"CLOSE_PAREN","[":"OPEN_BRACKET","]":"CLOSE_BRACKET",",":"COMMA","@":"AT"};const regexWhitespacePrefix=new RegExp("^(\\s*)");const regexNumberPrefix=new RegExp("^([0-9]+)");const regexIdPrefix=new RegExp("^([a-zA-Z$_][a-zA-Z0-9$_]*)");const regexId=new RegExp("^([a-zA-Z$_][a-zA-Z0-9$_]*)$");const regexType=new RegExp("^(address|bool|bytes([0-9]*)|string|u?int([0-9]*))$");class TokenString{#offset;#tokens;get offset(){return this.#offset}get length(){return this.#tokens.length-this.#offset}constructor(tokens){this.#offset=0;this.#tokens=tokens.slice()}clone(){return new TokenString(this.#tokens)}reset(){this.#offset=0}#subTokenString(from=0,to=0){return new TokenString(this.#tokens.slice(from,to).map(t=>{return Object.freeze(Object.assign({},t,{match:t.match-from,linkBack:t.linkBack-from,linkNext:t.linkNext-from}))}))}popKeyword(allowed){const top=this.peek();if(top.type!=="KEYWORD"||!allowed.has(top.text)){throw new Error(`expected keyword ${top.text}`)}return this.pop().text}popType(type){if(this.peek().type!==type){throw new Error(`expected ${type}; got ${JSON.stringify(this.peek())}`)}return this.pop().text}popParen(){const top=this.peek();if(top.type!=="OPEN_PAREN"){throw new Error("bad start")}const result=this.#subTokenString(this.#offset+1,top.match+1);this.#offset=top.match+1;return result}popParams(){const top=this.peek();if(top.type!=="OPEN_PAREN"){throw new Error("bad start")}const result=[];while(this.#offset=this.#tokens.length){throw new Error("out-of-bounds")}return this.#tokens[this.#offset]}peekKeyword(allowed){const top=this.peekType("KEYWORD");return top!=null&&allowed.has(top)?top:null}peekType(type){if(this.length===0){return null}const top=this.peek();return top.type===type?top.text:null}pop(){const result=this.peek();this.#offset++;return result}toString(){const tokens=[];for(let i=this.#offset;i`}}function lex(text){const tokens=[];const throwError=message=>{const token=offset0&&tokens[tokens.length-1].type==="NUMBER"){const value=tokens.pop().text;suffix=value+suffix;tokens[tokens.length-1].value=getNumber(value)}if(tokens.length===0||tokens[tokens.length-1].type!=="BRACKET"){throw new Error("missing opening bracket")}tokens[tokens.length-1].text+=suffix}continue}match=cur.match(regexIdPrefix);if(match){token.text=match[1];offset+=token.text.length;if(Keywords.has(token.text)){token.type="KEYWORD";continue}if(token.text.match(regexType)){token.type="TYPE";continue}token.type="ID";continue}match=cur.match(regexNumberPrefix);if(match){token.text=match[1];token.type="NUMBER";offset+=token.text.length;continue}throw new Error(`unexpected token ${JSON.stringify(cur[0])} at position ${offset}`)}return new TokenString(tokens.map(t=>Object.freeze(t)))}function allowSingle(set,allowed){let included=[];for(const key in allowed.keys()){if(set.has(key)){included.push(key)}}if(included.length>1){throw new Error(`conflicting types: ${included.join(", ")}`)}}function consumeName(type,tokens){if(tokens.peekKeyword(KwTypes)){const keyword=tokens.pop().text;if(keyword!==type){throw new Error(`expected ${type}, got ${keyword}`)}}return tokens.popType("ID")}function consumeKeywords(tokens,allowed){const keywords=new Set;while(true){const keyword=tokens.peekType("KEYWORD");if(keyword==null||allowed&&!allowed.has(keyword)){break}tokens.pop();if(keywords.has(keyword)){throw new Error(`duplicate keywords: ${JSON.stringify(keyword)}`)}keywords.add(keyword)}return Object.freeze(keywords)}function consumeMutability(tokens){let modifiers=consumeKeywords(tokens,KwVisib);allowSingle(modifiers,setify("constant payable nonpayable".split(" ")));allowSingle(modifiers,setify("pure view payable nonpayable".split(" ")));if(modifiers.has("view")){return"view"}if(modifiers.has("pure")){return"pure"}if(modifiers.has("payable")){return"payable"}if(modifiers.has("nonpayable")){return"nonpayable"}if(modifiers.has("constant")){return"view"}return"nonpayable"}function consumeParams(tokens,allowIndexed){return tokens.popParams().map(t=>ParamType.from(t,allowIndexed))}function consumeGas(tokens){if(tokens.peekType("AT")){tokens.pop();if(tokens.peekType("NUMBER")){return getBigInt(tokens.pop().text)}throw new Error("invalid gas")}return null}function consumeEoi(tokens){if(tokens.length){throw new Error(`unexpected tokens: ${tokens.toString()}`)}}const regexArrayType=new RegExp(/^(.*)\[([0-9]*)\]$/);function verifyBasicType(type){const match=type.match(regexType);assertArgument(match,"invalid type","type",type);if(type==="uint"){return"uint256"}if(type==="int"){return"int256"}if(match[2]){const length=parseInt(match[2]);assertArgument(length!==0&&length<=32,"invalid bytes length","type",type)}else if(match[3]){const size=parseInt(match[3]);assertArgument(size!==0&&size<=256&&size%8===0,"invalid numeric width","type",type)}return type}const _guard$2={};const internal$1=Symbol.for("_ethers_internal");const ParamTypeInternal="_ParamTypeInternal";const ErrorFragmentInternal="_ErrorInternal";const EventFragmentInternal="_EventInternal";const ConstructorFragmentInternal="_ConstructorInternal";const FallbackFragmentInternal="_FallbackInternal";const FunctionFragmentInternal="_FunctionInternal";const StructFragmentInternal="_StructInternal";class ParamType{name;type;baseType;indexed;components;arrayLength;arrayChildren;constructor(guard,name,type,baseType,indexed,components,arrayLength,arrayChildren){assertPrivate(guard,_guard$2,"ParamType");Object.defineProperty(this,internal$1,{value:ParamTypeInternal});if(components){components=Object.freeze(components.slice())}if(baseType==="array"){if(arrayLength==null||arrayChildren==null){throw new Error("")}}else if(arrayLength!=null||arrayChildren!=null){throw new Error("")}if(baseType==="tuple"){if(components==null){throw new Error("")}}else if(components!=null){throw new Error("")}defineProperties(this,{name:name,type:type,baseType:baseType,indexed:indexed,components:components,arrayLength:arrayLength,arrayChildren:arrayChildren})}format(format){if(format==null){format="sighash"}if(format==="json"){let result={type:this.baseType==="tuple"?"tuple":this.type,name:this.name||undefined};if(typeof this.indexed==="boolean"){result.indexed=this.indexed}if(this.isTuple()){result.components=this.components.map(c=>JSON.parse(c.format(format)))}return JSON.stringify(result)}let result="";if(this.isArray()){result+=this.arrayChildren.format(format);result+=`[${this.arrayLength<0?"":String(this.arrayLength)}]`}else{if(this.isTuple()){if(format!=="sighash"){result+=this.type}result+="("+this.components.map(comp=>comp.format(format)).join(format==="full"?", ":",")+")"}else{result+=this.type}}if(format!=="sighash"){if(this.indexed===true){result+=" indexed"}if(format==="full"&&this.name){result+=" "+this.name}}return result}isArray(){return this.baseType==="array"}isTuple(){return this.baseType==="tuple"}isIndexable(){return this.indexed!=null}walk(value,process){if(this.isArray()){if(!Array.isArray(value)){throw new Error("invalid array value")}if(this.arrayLength!==-1&&value.length!==this.arrayLength){throw new Error("array is wrong length")}const _this=this;return value.map(v=>_this.arrayChildren.walk(v,process))}if(this.isTuple()){if(!Array.isArray(value)){throw new Error("invalid tuple value")}if(value.length!==this.components.length){throw new Error("array is wrong length")}const _this=this;return value.map((v,i)=>_this.components[i].walk(v,process))}return process(this.type,value)}#walkAsync(promises,value,process,setValue){if(this.isArray()){if(!Array.isArray(value)){throw new Error("invalid array value")}if(this.arrayLength!==-1&&value.length!==this.arrayLength){throw new Error("array is wrong length")}const childType=this.arrayChildren;const result=value.slice();result.forEach((value,index)=>{childType.#walkAsync(promises,value,process,value=>{result[index]=value})});setValue(result);return}if(this.isTuple()){const components=this.components;let result;if(Array.isArray(value)){result=value.slice()}else{if(value==null||typeof value!=="object"){throw new Error("invalid tuple value")}result=components.map(param=>{if(!param.name){throw new Error("cannot use object value with unnamed components")}if(!(param.name in value)){throw new Error(`missing value for component ${param.name}`)}return value[param.name]})}if(result.length!==this.components.length){throw new Error("array is wrong length")}result.forEach((value,index)=>{components[index].#walkAsync(promises,value,process,value=>{result[index]=value})});setValue(result);return}const result=process(this.type,value);if(result.then){promises.push(async function(){setValue(await result)}())}else{setValue(result)}}async walkAsync(value,process){const promises=[];const result=[value];this.#walkAsync(promises,value,process,value=>{result[0]=value});if(promises.length){await Promise.all(promises)}return result[0]}static from(obj,allowIndexed){if(ParamType.isParamType(obj)){return obj}if(typeof obj==="string"){return ParamType.from(lex(obj),allowIndexed)}else if(obj instanceof TokenString){let type="",baseType="";let comps=null;if(consumeKeywords(obj,setify(["tuple"])).has("tuple")||obj.peekType("OPEN_PAREN")){baseType="tuple";comps=obj.popParams().map(t=>ParamType.from(t));type=`tuple(${comps.map(c=>c.format()).join(",")})`}else{type=verifyBasicType(obj.popType("TYPE"));baseType=type}let arrayChildren=null;let arrayLength=null;while(obj.length&&obj.peekType("BRACKET")){const bracket=obj.pop();arrayChildren=new ParamType(_guard$2,"",type,baseType,null,comps,arrayLength,arrayChildren);arrayLength=bracket.value;type+=bracket.text;baseType="array";comps=null}let indexed=null;const keywords=consumeKeywords(obj,KwModifiers);if(keywords.has("indexed")){if(!allowIndexed){throw new Error("")}indexed=true}const name=obj.peekType("ID")?obj.pop().text:"";if(obj.length){throw new Error("leftover tokens")}return new ParamType(_guard$2,name,type,baseType,indexed,comps,arrayLength,arrayChildren)}const name=obj.name;assertArgument(!name||typeof name==="string"&&name.match(regexId),"invalid name","obj.name",name);let indexed=obj.indexed;if(indexed!=null){assertArgument(allowIndexed,"parameter cannot be indexed","obj.indexed",obj.indexed);indexed=!!indexed}let type=obj.type;let arrayMatch=type.match(regexArrayType);if(arrayMatch){const arrayLength=parseInt(arrayMatch[2]||"-1");const arrayChildren=ParamType.from({type:arrayMatch[1],components:obj.components});return new ParamType(_guard$2,name||"",type,"array",indexed,null,arrayLength,arrayChildren)}if(type==="tuple"||type.startsWith("tuple(")||type.startsWith("(")){const comps=obj.components!=null?obj.components.map(c=>ParamType.from(c)):null;const tuple=new ParamType(_guard$2,name||"",type,"tuple",indexed,comps,null,null);return tuple}type=verifyBasicType(obj.type);return new ParamType(_guard$2,name||"",type,type,indexed,null,null,null)}static isParamType(value){return value&&value[internal$1]===ParamTypeInternal}}class Fragment{type;inputs;constructor(guard,type,inputs){assertPrivate(guard,_guard$2,"Fragment");inputs=Object.freeze(inputs.slice());defineProperties(this,{type:type,inputs:inputs})}static from(obj){if(typeof obj==="string"){try{Fragment.from(JSON.parse(obj))}catch(e){}return Fragment.from(lex(obj))}if(obj instanceof TokenString){const type=obj.peekKeyword(KwTypes);switch(type){case"constructor":return ConstructorFragment.from(obj);case"error":return ErrorFragment.from(obj);case"event":return EventFragment.from(obj);case"fallback":case"receive":return FallbackFragment.from(obj);case"function":return FunctionFragment.from(obj);case"struct":return StructFragment.from(obj)}}else if(typeof obj==="object"){switch(obj.type){case"constructor":return ConstructorFragment.from(obj);case"error":return ErrorFragment.from(obj);case"event":return EventFragment.from(obj);case"fallback":case"receive":return FallbackFragment.from(obj);case"function":return FunctionFragment.from(obj);case"struct":return StructFragment.from(obj)}assert$1(false,`unsupported type: ${obj.type}`,"UNSUPPORTED_OPERATION",{operation:"Fragment.from"})}assertArgument(false,"unsupported frgament object","obj",obj)}static isConstructor(value){return ConstructorFragment.isFragment(value)}static isError(value){return ErrorFragment.isFragment(value)}static isEvent(value){return EventFragment.isFragment(value)}static isFunction(value){return FunctionFragment.isFragment(value)}static isStruct(value){return StructFragment.isFragment(value)}}class NamedFragment extends Fragment{name;constructor(guard,type,name,inputs){super(guard,type,inputs);assertArgument(typeof name==="string"&&name.match(regexId),"invalid identifier","name",name);inputs=Object.freeze(inputs.slice());defineProperties(this,{name:name})}}function joinParams(format,params){return"("+params.map(p=>p.format(format)).join(format==="full"?", ":",")+")"}class ErrorFragment extends NamedFragment{constructor(guard,name,inputs){super(guard,"error",name,inputs);Object.defineProperty(this,internal$1,{value:ErrorFragmentInternal})}get selector(){return id(this.format("sighash")).substring(0,10)}format(format){if(format==null){format="sighash"}if(format==="json"){return JSON.stringify({type:"error",name:this.name,inputs:this.inputs.map(input=>JSON.parse(input.format(format)))})}const result=[];if(format!=="sighash"){result.push("error")}result.push(this.name+joinParams(format,this.inputs));return result.join(" ")}static from(obj){if(ErrorFragment.isFragment(obj)){return obj}if(typeof obj==="string"){return ErrorFragment.from(lex(obj))}else if(obj instanceof TokenString){const name=consumeName("error",obj);const inputs=consumeParams(obj);consumeEoi(obj);return new ErrorFragment(_guard$2,name,inputs)}return new ErrorFragment(_guard$2,obj.name,obj.inputs?obj.inputs.map(ParamType.from):[])}static isFragment(value){return value&&value[internal$1]===ErrorFragmentInternal}}class EventFragment extends NamedFragment{anonymous;constructor(guard,name,inputs,anonymous){super(guard,"event",name,inputs);Object.defineProperty(this,internal$1,{value:EventFragmentInternal});defineProperties(this,{anonymous:anonymous})}get topicHash(){return id(this.format("sighash"))}format(format){if(format==null){format="sighash"}if(format==="json"){return JSON.stringify({type:"event",anonymous:this.anonymous,name:this.name,inputs:this.inputs.map(i=>JSON.parse(i.format(format)))})}const result=[];if(format!=="sighash"){result.push("event")}result.push(this.name+joinParams(format,this.inputs));if(format!=="sighash"&&this.anonymous){result.push("anonymous")}return result.join(" ")}static getTopicHash(name,params){params=(params||[]).map(p=>ParamType.from(p));const fragment=new EventFragment(_guard$2,name,params,false);return fragment.topicHash}static from(obj){if(EventFragment.isFragment(obj)){return obj}if(typeof obj==="string"){return EventFragment.from(lex(obj))}else if(obj instanceof TokenString){const name=consumeName("event",obj);const inputs=consumeParams(obj,true);const anonymous=!!consumeKeywords(obj,setify(["anonymous"])).has("anonymous");consumeEoi(obj);return new EventFragment(_guard$2,name,inputs,anonymous)}return new EventFragment(_guard$2,obj.name,obj.inputs?obj.inputs.map(p=>ParamType.from(p,true)):[],!!obj.anonymous)}static isFragment(value){return value&&value[internal$1]===EventFragmentInternal}}class ConstructorFragment extends Fragment{payable;gas;constructor(guard,type,inputs,payable,gas){super(guard,type,inputs);Object.defineProperty(this,internal$1,{value:ConstructorFragmentInternal});defineProperties(this,{payable:payable,gas:gas})}format(format){assert$1(format!=null&&format!=="sighash","cannot format a constructor for sighash","UNSUPPORTED_OPERATION",{operation:"format(sighash)"});if(format==="json"){return JSON.stringify({type:"constructor",stateMutability:this.payable?"payable":"undefined",payable:this.payable,gas:this.gas!=null?this.gas:undefined,inputs:this.inputs.map(i=>JSON.parse(i.format(format)))})}const result=[`constructor${joinParams(format,this.inputs)}`];result.push(this.payable?"payable":"nonpayable");if(this.gas!=null){result.push(`@${this.gas.toString()}`)}return result.join(" ")}static from(obj){if(ConstructorFragment.isFragment(obj)){return obj}if(typeof obj==="string"){return ConstructorFragment.from(lex(obj))}else if(obj instanceof TokenString){consumeKeywords(obj,setify(["constructor"]));const inputs=consumeParams(obj);const payable=!!consumeKeywords(obj,setify(["payable"])).has("payable");const gas=consumeGas(obj);consumeEoi(obj);return new ConstructorFragment(_guard$2,"constructor",inputs,payable,gas)}return new ConstructorFragment(_guard$2,"constructor",obj.inputs?obj.inputs.map(ParamType.from):[],!!obj.payable,obj.gas!=null?obj.gas:null)}static isFragment(value){return value&&value[internal$1]===ConstructorFragmentInternal}}class FallbackFragment extends Fragment{payable;constructor(guard,inputs,payable){super(guard,"fallback",inputs);Object.defineProperty(this,internal$1,{value:FallbackFragmentInternal});defineProperties(this,{payable:payable})}format(format){const type=this.inputs.length===0?"receive":"fallback";if(format==="json"){const stateMutability=this.payable?"payable":"nonpayable";return JSON.stringify({type:type,stateMutability:stateMutability})}return`${type}()${this.payable?" payable":""}`}static from(obj){if(FallbackFragment.isFragment(obj)){return obj}if(typeof obj==="string"){return FallbackFragment.from(lex(obj))}else if(obj instanceof TokenString){const errorObj=obj.toString();const topIsValid=obj.peekKeyword(setify(["fallback","receive"]));assertArgument(topIsValid,"type must be fallback or receive","obj",errorObj);const type=obj.popKeyword(setify(["fallback","receive"]));if(type==="receive"){const inputs=consumeParams(obj);assertArgument(inputs.length===0,`receive cannot have arguments`,"obj.inputs",inputs);consumeKeywords(obj,setify(["payable"]));consumeEoi(obj);return new FallbackFragment(_guard$2,[],true)}let inputs=consumeParams(obj);if(inputs.length){assertArgument(inputs.length===1&&inputs[0].type==="bytes","invalid fallback inputs","obj.inputs",inputs.map(i=>i.format("minimal")).join(", "))}else{inputs=[ParamType.from("bytes")]}const mutability=consumeMutability(obj);assertArgument(mutability==="nonpayable"||mutability==="payable","fallback cannot be constants","obj.stateMutability",mutability);if(consumeKeywords(obj,setify(["returns"])).has("returns")){const outputs=consumeParams(obj);assertArgument(outputs.length===1&&outputs[0].type==="bytes","invalid fallback outputs","obj.outputs",outputs.map(i=>i.format("minimal")).join(", "))}consumeEoi(obj);return new FallbackFragment(_guard$2,inputs,mutability==="payable")}if(obj.type==="receive"){return new FallbackFragment(_guard$2,[],true)}if(obj.type==="fallback"){const inputs=[ParamType.from("bytes")];const payable=obj.stateMutability==="payable";return new FallbackFragment(_guard$2,inputs,payable)}assertArgument(false,"invalid fallback description","obj",obj)}static isFragment(value){return value&&value[internal$1]===FallbackFragmentInternal}}class FunctionFragment extends NamedFragment{constant;outputs;stateMutability;payable;gas;constructor(guard,name,stateMutability,inputs,outputs,gas){super(guard,"function",name,inputs);Object.defineProperty(this,internal$1,{value:FunctionFragmentInternal});outputs=Object.freeze(outputs.slice());const constant=stateMutability==="view"||stateMutability==="pure";const payable=stateMutability==="payable";defineProperties(this,{constant:constant,gas:gas,outputs:outputs,payable:payable,stateMutability:stateMutability})}get selector(){return id(this.format("sighash")).substring(0,10)}format(format){if(format==null){format="sighash"}if(format==="json"){return JSON.stringify({type:"function",name:this.name,constant:this.constant,stateMutability:this.stateMutability!=="nonpayable"?this.stateMutability:undefined,payable:this.payable,gas:this.gas!=null?this.gas:undefined,inputs:this.inputs.map(i=>JSON.parse(i.format(format))),outputs:this.outputs.map(o=>JSON.parse(o.format(format)))})}const result=[];if(format!=="sighash"){result.push("function")}result.push(this.name+joinParams(format,this.inputs));if(format!=="sighash"){if(this.stateMutability!=="nonpayable"){result.push(this.stateMutability)}if(this.outputs&&this.outputs.length){result.push("returns");result.push(joinParams(format,this.outputs))}if(this.gas!=null){result.push(`@${this.gas.toString()}`)}}return result.join(" ")}static getSelector(name,params){params=(params||[]).map(p=>ParamType.from(p));const fragment=new FunctionFragment(_guard$2,name,"view",params,[],null);return fragment.selector}static from(obj){if(FunctionFragment.isFragment(obj)){return obj}if(typeof obj==="string"){return FunctionFragment.from(lex(obj))}else if(obj instanceof TokenString){const name=consumeName("function",obj);const inputs=consumeParams(obj);const mutability=consumeMutability(obj);let outputs=[];if(consumeKeywords(obj,setify(["returns"])).has("returns")){outputs=consumeParams(obj)}const gas=consumeGas(obj);consumeEoi(obj);return new FunctionFragment(_guard$2,name,mutability,inputs,outputs,gas)}let stateMutability=obj.stateMutability;if(stateMutability==null){stateMutability="payable";if(typeof obj.constant==="boolean"){stateMutability="view";if(!obj.constant){stateMutability="payable";if(typeof obj.payable==="boolean"&&!obj.payable){stateMutability="nonpayable"}}}else if(typeof obj.payable==="boolean"&&!obj.payable){stateMutability="nonpayable"}}return new FunctionFragment(_guard$2,obj.name,stateMutability,obj.inputs?obj.inputs.map(ParamType.from):[],obj.outputs?obj.outputs.map(ParamType.from):[],obj.gas!=null?obj.gas:null)}static isFragment(value){return value&&value[internal$1]===FunctionFragmentInternal}}class StructFragment extends NamedFragment{constructor(guard,name,inputs){super(guard,"struct",name,inputs);Object.defineProperty(this,internal$1,{value:StructFragmentInternal})}format(){throw new Error("@TODO")}static from(obj){if(typeof obj==="string"){return StructFragment.from(lex(obj))}else if(obj instanceof TokenString){const name=consumeName("struct",obj);const inputs=consumeParams(obj);consumeEoi(obj);return new StructFragment(_guard$2,name,inputs)}return new StructFragment(_guard$2,obj.name,obj.inputs?obj.inputs.map(ParamType.from):[])}static isFragment(value){return value&&value[internal$1]===StructFragmentInternal}}const PanicReasons$1=new Map;PanicReasons$1.set(0,"GENERIC_PANIC");PanicReasons$1.set(1,"ASSERT_FALSE");PanicReasons$1.set(17,"OVERFLOW");PanicReasons$1.set(18,"DIVIDE_BY_ZERO");PanicReasons$1.set(33,"ENUM_RANGE_ERROR");PanicReasons$1.set(34,"BAD_STORAGE_DATA");PanicReasons$1.set(49,"STACK_UNDERFLOW");PanicReasons$1.set(50,"ARRAY_RANGE_ERROR");PanicReasons$1.set(65,"OUT_OF_MEMORY");PanicReasons$1.set(81,"UNINITIALIZED_FUNCTION_CALL");const paramTypeBytes=new RegExp(/^bytes([0-9]*)$/);const paramTypeNumber=new RegExp(/^(u?int)([0-9]*)$/);let defaultCoder=null;function getBuiltinCallException(action,tx,data,abiCoder){let message="missing revert data";let reason=null;const invocation=null;let revert=null;if(data){message="execution reverted";const bytes=getBytes(data);data=hexlify(data);if(bytes.length===0){message+=" (no data present; likely require(false) occurred";reason="require(false)"}else if(bytes.length%32!==4){message+=" (could not decode reason; invalid data length)"}else if(hexlify(bytes.slice(0,4))==="0x08c379a0"){try{reason=abiCoder.decode(["string"],bytes.slice(4))[0];revert={signature:"Error(string)",name:"Error",args:[reason]};message+=`: ${JSON.stringify(reason)}`}catch(error){message+=" (could not decode reason; invalid string data)"}}else if(hexlify(bytes.slice(0,4))==="0x4e487b71"){try{const code=Number(abiCoder.decode(["uint256"],bytes.slice(4))[0]);revert={signature:"Panic(uint256)",name:"Panic",args:[code]};reason=`Panic due to ${PanicReasons$1.get(code)||"UNKNOWN"}(${code})`;message+=`: ${reason}`}catch(error){message+=" (could not decode panic code)"}}else{message+=" (unknown custom error)"}}const transaction={to:tx.to?getAddress(tx.to):null,data:tx.data||"0x"};if(tx.from){transaction.from=getAddress(tx.from)}return makeError(message,"CALL_EXCEPTION",{action:action,data:data,reason:reason,transaction:transaction,invocation:invocation,revert:revert})}class AbiCoder{#getCoder(param){if(param.isArray()){return new ArrayCoder(this.#getCoder(param.arrayChildren),param.arrayLength,param.name)}if(param.isTuple()){return new TupleCoder(param.components.map(c=>this.#getCoder(c)),param.name)}switch(param.baseType){case"address":return new AddressCoder(param.name);case"bool":return new BooleanCoder(param.name);case"string":return new StringCoder(param.name);case"bytes":return new BytesCoder(param.name);case"":return new NullCoder(param.name)}let match=param.type.match(paramTypeNumber);if(match){let size=parseInt(match[2]||"256");assertArgument(size!==0&&size<=256&&size%8===0,"invalid "+match[1]+" bit length","param",param);return new NumberCoder(size/8,match[1]==="int",param.name)}match=param.type.match(paramTypeBytes);if(match){let size=parseInt(match[1]);assertArgument(size!==0&&size<=32,"invalid bytes length","param",param);return new FixedBytesCoder(size,param.name)}assertArgument(false,"invalid type","type",param.type)}getDefaultValue(types){const coders=types.map(type=>this.#getCoder(ParamType.from(type)));const coder=new TupleCoder(coders,"_");return coder.defaultValue()}encode(types,values){assertArgumentCount(values.length,types.length,"types/values length mismatch");const coders=types.map(type=>this.#getCoder(ParamType.from(type)));const coder=new TupleCoder(coders,"_");const writer=new Writer;coder.encode(writer,values);return writer.data}decode(types,data,loose){const coders=types.map(type=>this.#getCoder(ParamType.from(type)));const coder=new TupleCoder(coders,"_");return coder.decode(new Reader(data,loose))}static defaultAbiCoder(){if(defaultCoder==null){defaultCoder=new AbiCoder}return defaultCoder}static getBuiltinCallException(action,tx,data){return getBuiltinCallException(action,tx,data,AbiCoder.defaultAbiCoder())}}function encodeBytes32String(text){const bytes=toUtf8Bytes(text);if(bytes.length>31){throw new Error("bytes32 string must be less than 32 bytes")}return zeroPadBytes(bytes,32)}function decodeBytes32String(_bytes){const data=getBytes(_bytes,"bytes");if(data.length!==32){throw new Error("invalid bytes32 - not 32 bytes long")}if(data[31]!==0){throw new Error("invalid bytes32 string - no null terminator")}let length=31;while(data[length-1]===0){length--}return toUtf8String(data.slice(0,length))}class LogDescription{fragment;name;signature;topic;args;constructor(fragment,topic,args){const name=fragment.name,signature=fragment.format();defineProperties(this,{fragment:fragment,name:name,signature:signature,topic:topic,args:args})}}class TransactionDescription{fragment;name;args;signature;selector;value;constructor(fragment,selector,args,value){const name=fragment.name,signature=fragment.format();defineProperties(this,{fragment:fragment,name:name,args:args,signature:signature,selector:selector,value:value})}}class ErrorDescription{fragment;name;args;signature;selector;constructor(fragment,selector,args){const name=fragment.name,signature=fragment.format();defineProperties(this,{fragment:fragment,name:name,args:args,signature:signature,selector:selector})}}class Indexed{hash;_isIndexed;static isIndexed(value){return!!(value&&value._isIndexed)}constructor(hash){defineProperties(this,{hash:hash,_isIndexed:true})}}const PanicReasons={0:"generic panic",1:"assert(false)",17:"arithmetic overflow",18:"division or modulo by zero",33:"enum overflow",34:"invalid encoded storage byte array accessed",49:"out-of-bounds array access; popping on an empty array",50:"out-of-bounds access of an array or bytesN",65:"out of memory",81:"uninitialized function"};const BuiltinErrors={"0x08c379a0":{signature:"Error(string)",name:"Error",inputs:["string"],reason:message=>{return`reverted with reason string ${JSON.stringify(message)}`}},"0x4e487b71":{signature:"Panic(uint256)",name:"Panic",inputs:["uint256"],reason:code=>{let reason="unknown panic code";if(code>=0&&code<=255&&PanicReasons[code.toString()]){reason=PanicReasons[code.toString()]}return`reverted with panic code 0x${code.toString(16)} (${reason})`}}};class Interface{fragments;deploy;fallback;receive;#errors;#events;#functions;#abiCoder;constructor(fragments){let abi=[];if(typeof fragments==="string"){abi=JSON.parse(fragments)}else{abi=fragments}this.#functions=new Map;this.#errors=new Map;this.#events=new Map;const frags=[];for(const a of abi){try{frags.push(Fragment.from(a))}catch(error){console.log("EE",error)}}defineProperties(this,{fragments:Object.freeze(frags)});let fallback=null;let receive=false;this.#abiCoder=this.getAbiCoder();this.fragments.forEach((fragment,index)=>{let bucket;switch(fragment.type){case"constructor":if(this.deploy){console.log("duplicate definition - constructor");return}defineProperties(this,{deploy:fragment});return;case"fallback":if(fragment.inputs.length===0){receive=true}else{assertArgument(!fallback||fragment.payable!==fallback.payable,"conflicting fallback fragments",`fragments[${index}]`,fragment);fallback=fragment;receive=fallback.payable}return;case"function":bucket=this.#functions;break;case"event":bucket=this.#events;break;case"error":bucket=this.#errors;break;default:return}const signature=fragment.format();if(bucket.has(signature)){return}bucket.set(signature,fragment)});if(!this.deploy){defineProperties(this,{deploy:ConstructorFragment.from("constructor()")})}defineProperties(this,{fallback:fallback,receive:receive})}format(minimal){const format=minimal?"minimal":"full";const abi=this.fragments.map(f=>f.format(format));return abi}formatJson(){const abi=this.fragments.map(f=>f.format("json"));return JSON.stringify(abi.map(j=>JSON.parse(j)))}getAbiCoder(){return AbiCoder.defaultAbiCoder()}#getFunction(key,values,forceUnique){if(isHexString(key)){const selector=key.toLowerCase();for(const fragment of this.#functions.values()){if(selector===fragment.selector){return fragment}}return null}if(key.indexOf("(")===-1){const matching=[];for(const[name,fragment]of this.#functions){if(name.split("(")[0]===key){matching.push(fragment)}}if(values){const lastValue=values.length>0?values[values.length-1]:null;let valueLength=values.length;let allowOptions=true;if(Typed.isTyped(lastValue)&&lastValue.type==="overrides"){allowOptions=false;valueLength--}for(let i=matching.length-1;i>=0;i--){const inputs=matching[i].inputs.length;if(inputs!==valueLength&&(!allowOptions||inputs!==valueLength-1)){matching.splice(i,1)}}for(let i=matching.length-1;i>=0;i--){const inputs=matching[i].inputs;for(let j=0;j=inputs.length){if(values[j].type==="overrides"){continue}matching.splice(i,1);break}if(values[j].type!==inputs[j].baseType){matching.splice(i,1);break}}}}if(matching.length===1&&values&&values.length!==matching[0].inputs.length){const lastArg=values[values.length-1];if(lastArg==null||Array.isArray(lastArg)||typeof lastArg!=="object"){matching.splice(0,1)}}if(matching.length===0){return null}if(matching.length>1&&forceUnique){const matchStr=matching.map(m=>JSON.stringify(m.format())).join(", ");assertArgument(false,`ambiguous function description (i.e. matches ${matchStr})`,"key",key)}return matching[0]}const result=this.#functions.get(FunctionFragment.from(key).format());if(result){return result}return null}getFunctionName(key){const fragment=this.#getFunction(key,null,false);assertArgument(fragment,"no matching function","key",key);return fragment.name}hasFunction(key){return!!this.#getFunction(key,null,false)}getFunction(key,values){return this.#getFunction(key,values||null,true)}forEachFunction(callback){const names=Array.from(this.#functions.keys());names.sort((a,b)=>a.localeCompare(b));for(let i=0;i=0;i--){if(matching[i].inputs.length=0;i--){const inputs=matching[i].inputs;for(let j=0;j1&&forceUnique){const matchStr=matching.map(m=>JSON.stringify(m.format())).join(", ");assertArgument(false,`ambiguous event description (i.e. matches ${matchStr})`,"key",key)}return matching[0]}const result=this.#events.get(EventFragment.from(key).format());if(result){return result}return null}getEventName(key){const fragment=this.#getEvent(key,null,false);assertArgument(fragment,"no matching event","key",key);return fragment.name}hasEvent(key){return!!this.#getEvent(key,null,false)}getEvent(key,values){return this.#getEvent(key,values||null,true)}forEachEvent(callback){const names=Array.from(this.#events.keys());names.sort((a,b)=>a.localeCompare(b));for(let i=0;i1){const matchStr=matching.map(m=>JSON.stringify(m.format())).join(", ");assertArgument(false,`ambiguous error description (i.e. ${matchStr})`,"name",key)}return matching[0]}key=ErrorFragment.from(key).format();if(key==="Error(string)"){return ErrorFragment.from("error Error(string)")}if(key==="Panic(uint256)"){return ErrorFragment.from("error Panic(uint256)")}const result=this.#errors.get(key);if(result){return result}return null}forEachError(callback){const names=Array.from(this.#errors.keys());names.sort((a,b)=>a.localeCompare(b));for(let i=0;i{if(param.type==="string"){return id(value)}else if(param.type==="bytes"){return keccak256(hexlify(value))}if(param.type==="bool"&&typeof value==="boolean"){value=value?"0x01":"0x00"}if(param.type.match(/^u?int/)){value=toBeHex(value)}if(param.type==="address"){this.#abiCoder.encode(["address"],[value])}return zeroPadValue(hexlify(value),32)};values.forEach((value,index)=>{const param=fragment.inputs[index];if(!param.indexed){assertArgument(value==null,"cannot filter non-indexed parameters; must be null","contract."+param.name,value);return}if(value==null){topics.push(null)}else if(param.baseType==="array"||param.baseType==="tuple"){assertArgument(false,"filtering with tuples or arrays not supported","contract."+param.name,value)}else if(Array.isArray(value)){topics.push(value.map(value=>encodeTopic(param,value)))}else{topics.push(encodeTopic(param,value))}});while(topics.length&&topics[topics.length-1]===null){topics.pop()}return topics}encodeEventLog(fragment,values){if(typeof fragment==="string"){const f=this.getEvent(fragment);assertArgument(f,"unknown event","eventFragment",fragment);fragment=f}const topics=[];const dataTypes=[];const dataValues=[];if(!fragment.anonymous){topics.push(fragment.topicHash)}assertArgument(values.length===fragment.inputs.length,"event arguments/values mismatch","values",values);fragment.inputs.forEach((param,index)=>{const value=values[index];if(param.indexed){if(param.type==="string"){topics.push(id(value))}else if(param.type==="bytes"){topics.push(keccak256(value))}else if(param.baseType==="tuple"||param.baseType==="array"){throw new Error("not implemented")}else{topics.push(this.#abiCoder.encode([param.type],[value]))}}else{dataTypes.push(param);dataValues.push(value)}});return{data:this.#abiCoder.encode(dataTypes,dataValues),topics:topics}}decodeEventLog(fragment,data,topics){if(typeof fragment==="string"){const f=this.getEvent(fragment);assertArgument(f,"unknown event","eventFragment",fragment);fragment=f}if(topics!=null&&!fragment.anonymous){const eventTopic=fragment.topicHash;assertArgument(isHexString(topics[0],32)&&topics[0].toLowerCase()===eventTopic,"fragment/topic mismatch","topics[0]",topics[0]);topics=topics.slice(1)}const indexed=[];const nonIndexed=[];const dynamic=[];fragment.inputs.forEach((param,index)=>{if(param.indexed){if(param.type==="string"||param.type==="bytes"||param.baseType==="tuple"||param.baseType==="array"){indexed.push(ParamType.from({type:"bytes32",name:param.name}));dynamic.push(true)}else{indexed.push(param);dynamic.push(false)}}else{nonIndexed.push(param);dynamic.push(false)}});const resultIndexed=topics!=null?this.#abiCoder.decode(indexed,concat(topics)):null;const resultNonIndexed=this.#abiCoder.decode(nonIndexed,data,true);const values=[];const keys=[];let nonIndexedIndex=0,indexedIndex=0;fragment.inputs.forEach((param,index)=>{let value=null;if(param.indexed){if(resultIndexed==null){value=new Indexed(null)}else if(dynamic[index]){value=new Indexed(resultIndexed[indexedIndex++])}else{try{value=resultIndexed[indexedIndex++]}catch(error){value=error}}}else{try{value=resultNonIndexed[nonIndexedIndex++]}catch(error){value=error}}values.push(value);keys.push(param.name||null)});return Result.fromItems(values,keys)}parseTransaction(tx){const data=getBytes(tx.data,"tx.data");const value=getBigInt(tx.value!=null?tx.value:0,"tx.value");const fragment=this.getFunction(hexlify(data.slice(0,4)));if(!fragment){return null}const args=this.#abiCoder.decode(fragment.inputs,data.slice(4));return new TransactionDescription(fragment,fragment.selector,args,value)}parseCallResult(data){throw new Error("@TODO")}parseLog(log){const fragment=this.getEvent(log.topics[0]);if(!fragment||fragment.anonymous){return null}return new LogDescription(fragment,fragment.topicHash,this.decodeEventLog(fragment,log.data,log.topics))}parseError(data){const hexData=hexlify(data);const fragment=this.getError(dataSlice(hexData,0,4));if(!fragment){return null}const args=this.#abiCoder.decode(fragment.inputs,dataSlice(hexData,4));return new ErrorDescription(fragment,fragment.selector,args)}static from(value){if(value instanceof Interface){return value}if(typeof value==="string"){return new Interface(JSON.parse(value))}if(typeof value.format==="function"){return new Interface(value.format("json"))}return new Interface(value)}}const BN_0$2=BigInt(0);function getValue(value){if(value==null){return null}return value}function toJson(value){if(value==null){return null}return value.toString()}class FeeData{gasPrice;maxFeePerGas;maxPriorityFeePerGas;constructor(gasPrice,maxFeePerGas,maxPriorityFeePerGas){defineProperties(this,{gasPrice:getValue(gasPrice),maxFeePerGas:getValue(maxFeePerGas),maxPriorityFeePerGas:getValue(maxPriorityFeePerGas)})}toJSON(){const{gasPrice,maxFeePerGas,maxPriorityFeePerGas}=this;return{_type:"FeeData",gasPrice:toJson(gasPrice),maxFeePerGas:toJson(maxFeePerGas),maxPriorityFeePerGas:toJson(maxPriorityFeePerGas)}}}function copyRequest(req){const result={};if(req.to){result.to=req.to}if(req.from){result.from=req.from}if(req.data){result.data=hexlify(req.data)}const bigIntKeys="chainId,gasLimit,gasPrice,maxFeePerGas,maxPriorityFeePerGas,value".split(/,/);for(const key of bigIntKeys){if(!(key in req)||req[key]==null){continue}result[key]=getBigInt(req[key],`request.${key}`)}const numberKeys="type,nonce".split(/,/);for(const key of numberKeys){if(!(key in req)||req[key]==null){continue}result[key]=getNumber(req[key],`request.${key}`)}if(req.accessList){result.accessList=accessListify(req.accessList)}if("blockTag"in req){result.blockTag=req.blockTag}if("enableCcipRead"in req){result.enableCcipReadEnabled=!!req.enableCcipRead}if("customData"in req){result.customData=req.customData}return result}class Block{provider;number;hash;timestamp;parentHash;nonce;difficulty;gasLimit;gasUsed;miner;extraData;baseFeePerGas;#transactions;constructor(block,provider){this.#transactions=block.transactions.map(tx=>{if(typeof tx!=="string"){return new TransactionResponse(tx,provider)}return tx});defineProperties(this,{provider:provider,hash:getValue(block.hash),number:block.number,timestamp:block.timestamp,parentHash:block.parentHash,nonce:block.nonce,difficulty:block.difficulty,gasLimit:block.gasLimit,gasUsed:block.gasUsed,miner:block.miner,extraData:block.extraData,baseFeePerGas:getValue(block.baseFeePerGas)})}get transactions(){return this.#transactions.map(tx=>{if(typeof tx==="string"){return tx}return tx.hash})}get prefetchedTransactions(){const txs=this.#transactions.slice();if(txs.length===0){return[]}assert$1(typeof txs[0]==="object","transactions were not prefetched with block request","UNSUPPORTED_OPERATION",{operation:"transactionResponses()"});return txs}toJSON(){const{baseFeePerGas,difficulty,extraData,gasLimit,gasUsed,hash,miner,nonce,number,parentHash,timestamp,transactions}=this;return{_type:"Block",baseFeePerGas:toJson(baseFeePerGas),difficulty:toJson(difficulty),extraData:extraData,gasLimit:toJson(gasLimit),gasUsed:toJson(gasUsed),hash:hash,miner:miner,nonce:nonce,number:number,parentHash:parentHash,timestamp:timestamp,transactions:transactions}}[Symbol.iterator](){let index=0;const txs=this.transactions;return{next:()=>{if(index{return new Log(log,provider)}));defineProperties(this,{provider:provider,to:tx.to,from:tx.from,contractAddress:tx.contractAddress,hash:tx.hash,index:tx.index,blockHash:tx.blockHash,blockNumber:tx.blockNumber,logsBloom:tx.logsBloom,gasUsed:tx.gasUsed,cumulativeGasUsed:tx.cumulativeGasUsed,gasPrice:tx.effectiveGasPrice||tx.gasPrice,type:tx.type,status:tx.status,root:tx.root})}get logs(){return this.#logs}toJSON(){const{to,from,contractAddress,hash,index,blockHash,blockNumber,logsBloom,logs,status,root}=this;return{_type:"TransactionReceipt",blockHash:blockHash,blockNumber:blockNumber,contractAddress:contractAddress,cumulativeGasUsed:toJson(this.cumulativeGasUsed),from:from,gasPrice:toJson(this.gasPrice),gasUsed:toJson(this.gasUsed),hash:hash,index:index,logs:logs,logsBloom:logsBloom,root:root,status:status,to:to}}get length(){return this.logs.length}[Symbol.iterator](){let index=0;return{next:()=>{if(index{if(stopScanning){return null}const{blockNumber,nonce}=await resolveProperties({blockNumber:this.provider.getBlockNumber(),nonce:this.provider.getTransactionCount(this.from)});if(nonce=confirms){return receipt}}else{await checkReplacement();if(confirms===0){return null}}const waiter=new Promise((resolve,reject)=>{const cancellers=[];const cancel=()=>{cancellers.forEach(c=>c())};cancellers.push(()=>{stopScanning=true});if(timeout>0){const timer=setTimeout(()=>{cancel();reject(makeError("wait for transaction timeout","TIMEOUT"))},timeout);cancellers.push(()=>{clearTimeout(timer)})}const txListener=async receipt=>{if(await receipt.confirmations()>=confirms){cancel();resolve(receipt)}};cancellers.push(()=>{this.provider.off(this.hash,txListener)});this.provider.on(this.hash,txListener);if(startBlock>=0){const replaceListener=async()=>{try{await checkReplacement()}catch(error){if(isError(error,"TRANSACTION_REPLACED")){cancel();reject(error);return}}if(!stopScanning){this.provider.once("block",replaceListener)}};cancellers.push(()=>{this.provider.off("block",replaceListener)});this.provider.once("block",replaceListener)}});return await waiter}isMined(){return this.blockHash!=null}isLegacy(){return this.type===0}isBerlin(){return this.type===1}isLondon(){return this.type===2}removedEvent(){assert$1(this.isMined(),"unmined transaction canot be orphaned","UNSUPPORTED_OPERATION",{operation:"removeEvent()"});return createRemovedTransactionFilter(this)}reorderedEvent(other){assert$1(this.isMined(),"unmined transaction canot be orphaned","UNSUPPORTED_OPERATION",{operation:"removeEvent()"});assert$1(!other||other.isMined(),"unmined 'other' transaction canot be orphaned","UNSUPPORTED_OPERATION",{operation:"removeEvent()"});return createReorderedTransactionFilter(this,other)}replaceableTransaction(startBlock){assertArgument(Number.isInteger(startBlock)&&startBlock>=0,"invalid startBlock","startBlock",startBlock);const tx=new TransactionResponse(this,this.provider);tx.#startBlock=startBlock;return tx}}function createOrphanedBlockFilter(block){return{orphan:"drop-block",hash:block.hash,number:block.number}}function createReorderedTransactionFilter(tx,other){return{orphan:"reorder-transaction",tx:tx,other:other}}function createRemovedTransactionFilter(tx){return{orphan:"drop-transaction",tx:tx}}function createRemovedLogFilter(log){return{orphan:"drop-log",log:{transactionHash:log.transactionHash,blockHash:log.blockHash,blockNumber:log.blockNumber,address:log.address,data:log.data,topics:Object.freeze(log.topics.slice()),index:log.index}}}class EventLog extends Log{interface;fragment;args;constructor(log,iface,fragment){super(log,log.provider);const args=iface.decodeEventLog(fragment,log.data,log.topics);defineProperties(this,{args:args,fragment:fragment,interface:iface})}get eventName(){return this.fragment.name}get eventSignature(){return this.fragment.format()}}class ContractTransactionReceipt extends TransactionReceipt{#iface;constructor(iface,provider,tx){super(tx,provider);this.#iface=iface}get logs(){return super.logs.map(log=>{const fragment=log.topics.length?this.#iface.getEvent(log.topics[0]):null;if(fragment){return new EventLog(log,this.#iface,fragment)}else{return log}})}}class ContractTransactionResponse extends TransactionResponse{#iface;constructor(iface,provider,tx){super(tx,provider);this.#iface=iface}async wait(confirms){const receipt=await super.wait();if(receipt==null){return null}return new ContractTransactionReceipt(this.#iface,this.provider,receipt)}}class ContractUnknownEventPayload extends EventPayload{log;constructor(contract,listener,filter,log){super(contract,listener,filter);defineProperties(this,{log:log})}async getBlock(){return await this.log.getBlock()}async getTransaction(){return await this.log.getTransaction()}async getTransactionReceipt(){return await this.log.getTransactionReceipt()}}class ContractEventPayload extends ContractUnknownEventPayload{constructor(contract,listener,filter,fragment,_log){super(contract,listener,filter,new EventLog(_log,contract.interface,fragment));const args=contract.interface.decodeEventLog(fragment,this.log.data,this.log.topics);defineProperties(this,{args:args,fragment:fragment})}get eventName(){return this.fragment.name}get eventSignature(){return this.fragment.format()}}const BN_0$1=BigInt(0);function canCall(value){return value&&typeof value.call==="function"}function canEstimate(value){return value&&typeof value.estimateGas==="function"}function canResolve(value){return value&&typeof value.resolveName==="function"}function canSend(value){return value&&typeof value.sendTransaction==="function"}class PreparedTopicFilter{#filter;fragment;constructor(contract,fragment,args){defineProperties(this,{fragment:fragment});if(fragment.inputs.length{const arg=args[index];if(arg==null){return null}return param.walkAsync(args[index],(type,value)=>{if(type==="address"){return resolveAddress(value,resolver)}return value})}));return contract.interface.encodeFilterTopics(fragment,resolvedArgs)}()}getTopicFilter(){return this.#filter}}function getRunner(value,feature){if(value==null){return null}if(typeof value[feature]==="function"){return value}if(value.provider&&typeof value.provider[feature]==="function"){return value.provider}return null}function getProvider(value){if(value==null){return null}return value.provider||null}async function copyOverrides(arg,allowed){const overrides=copyRequest(Typed.dereference(arg,"overrides"));assertArgument(overrides.to==null||(allowed||[]).indexOf("to")>=0,"cannot override to","overrides.to",overrides.to);assertArgument(overrides.data==null||(allowed||[]).indexOf("data")>=0,"cannot override data","overrides.data",overrides.data);if(overrides.from){overrides.from=await resolveAddress(overrides.from)}return overrides}async function resolveArgs(_runner,inputs,args){const runner=getRunner(_runner,"resolveName");const resolver=canResolve(runner)?runner:null;return await Promise.all(inputs.map((param,index)=>{return param.walkAsync(args[index],(type,value)=>{value=Typed.dereference(value,type);if(type==="address"){return resolveAddress(value,resolver)}return value})}))}function buildWrappedFallback(contract){const populateTransaction=async function(overrides){const tx=await copyOverrides(overrides,["data"]);tx.to=await contract.getAddress();const iface=contract.interface;const payable=iface.receive||iface.fallback&&iface.fallback.payable;assertArgument(payable||(tx.value||BN_0$1)===BN_0$1,"cannot send value to non-payable contract","overrides.value",tx.value);assertArgument(iface.fallback||(tx.data||"0x")==="0x","cannot send data to receive-only contract","overrides.data",tx.data);return tx};const staticCall=async function(overrides){const runner=getRunner(contract.runner,"call");assert$1(canCall(runner),"contract runner does not support calling","UNSUPPORTED_OPERATION",{operation:"call"});const tx=await populateTransaction(overrides);try{return await runner.call(tx)}catch(error){if(isCallException(error)&&error.data){throw contract.interface.makeError(error.data,tx)}throw error}};const send=async function(overrides){const runner=contract.runner;assert$1(canSend(runner),"contract runner does not support sending transactions","UNSUPPORTED_OPERATION",{operation:"sendTransaction"});const tx=await runner.sendTransaction(await populateTransaction(overrides));const provider=getProvider(contract.runner);return new ContractTransactionResponse(contract.interface,provider,tx)};const estimateGas=async function(overrides){const runner=getRunner(contract.runner,"estimateGas");assert$1(canEstimate(runner),"contract runner does not support gas estimation","UNSUPPORTED_OPERATION",{operation:"estimateGas"});return await runner.estimateGas(await populateTransaction(overrides))};const method=async overrides=>{return await send(overrides)};defineProperties(method,{_contract:contract,estimateGas:estimateGas,populateTransaction:populateTransaction,send:send,staticCall:staticCall});return method}function buildWrappedMethod(contract,key){const getFragment=function(...args){const fragment=contract.interface.getFunction(key,args);assert$1(fragment,"no matching fragment","UNSUPPORTED_OPERATION",{operation:"fragment"});return fragment};const populateTransaction=async function(...args){const fragment=getFragment(...args);let overrides={};if(fragment.inputs.length+1===args.length){overrides=await copyOverrides(args.pop())}if(fragment.inputs.length!==args.length){throw new Error("internal error: fragment inputs doesn't match arguments; should not happen")}const resolvedArgs=await resolveArgs(contract.runner,fragment.inputs,args);return Object.assign({},overrides,await resolveProperties({to:contract.getAddress(),data:contract.interface.encodeFunctionData(fragment,resolvedArgs)}))};const staticCall=async function(...args){const result=await staticCallResult(...args);if(result.length===1){return result[0]}return result};const send=async function(...args){const runner=contract.runner;assert$1(canSend(runner),"contract runner does not support sending transactions","UNSUPPORTED_OPERATION",{operation:"sendTransaction"});const tx=await runner.sendTransaction(await populateTransaction(...args));const provider=getProvider(contract.runner);return new ContractTransactionResponse(contract.interface,provider,tx)};const estimateGas=async function(...args){const runner=getRunner(contract.runner,"estimateGas");assert$1(canEstimate(runner),"contract runner does not support gas estimation","UNSUPPORTED_OPERATION",{operation:"estimateGas"});return await runner.estimateGas(await populateTransaction(...args))};const staticCallResult=async function(...args){const runner=getRunner(contract.runner,"call");assert$1(canCall(runner),"contract runner does not support calling","UNSUPPORTED_OPERATION",{operation:"call"});const tx=await populateTransaction(...args);let result="0x";try{result=await runner.call(tx)}catch(error){if(isCallException(error)&&error.data){throw contract.interface.makeError(error.data,tx)}throw error}const fragment=getFragment(...args);return contract.interface.decodeFunctionResult(fragment,result)};const method=async(...args)=>{const fragment=getFragment(...args);if(fragment.constant){return await staticCall(...args)}return await send(...args)};defineProperties(method,{name:contract.interface.getFunctionName(key),_contract:contract,_key:key,getFragment:getFragment,estimateGas:estimateGas,populateTransaction:populateTransaction,send:send,staticCall:staticCall,staticCallResult:staticCallResult});Object.defineProperty(method,"fragment",{configurable:false,enumerable:true,get:()=>{const fragment=contract.interface.getFunction(key);assert$1(fragment,"no matching fragment","UNSUPPORTED_OPERATION",{operation:"fragment"});return fragment}});return method}function buildWrappedEvent(contract,key){const getFragment=function(...args){const fragment=contract.interface.getEvent(key,args);assert$1(fragment,"no matching fragment","UNSUPPORTED_OPERATION",{operation:"fragment"});return fragment};const method=function(...args){return new PreparedTopicFilter(contract,getFragment(...args),args)};defineProperties(method,{name:contract.interface.getEventName(key),_contract:contract,_key:key,getFragment:getFragment});Object.defineProperty(method,"fragment",{configurable:false,enumerable:true,get:()=>{const fragment=contract.interface.getEvent(key);assert$1(fragment,"no matching fragment","UNSUPPORTED_OPERATION",{operation:"fragment"});return fragment}});return method}const internal=Symbol.for("_ethersInternal_contract");const internalValues=new WeakMap;function setInternal(contract,values){internalValues.set(contract[internal],values)}function getInternal(contract){return internalValues.get(contract[internal])}function isDeferred(value){return value&&typeof value==="object"&&"getTopicFilter"in value&&typeof value.getTopicFilter==="function"&&value.fragment}async function getSubInfo(contract,event){let topics;let fragment=null;if(Array.isArray(event)){const topicHashify=function(name){if(isHexString(name,32)){return name}const fragment=contract.interface.getEvent(name);assertArgument(fragment,"unknown fragment","name",name);return fragment.topicHash};topics=event.map(e=>{if(e==null){return null}if(Array.isArray(e)){return e.map(topicHashify)}return topicHashify(e)})}else if(event==="*"){topics=[null]}else if(typeof event==="string"){if(isHexString(event,32)){topics=[event]}else{fragment=contract.interface.getEvent(event);assertArgument(fragment,"unknown fragment","event",event);topics=[fragment.topicHash]}}else if(isDeferred(event)){topics=await event.getTopicFilter()}else if("fragment"in event){fragment=event.fragment;topics=[fragment.topicHash]}else{assertArgument(false,"unknown event name","event",event)}topics=topics.map(t=>{if(t==null){return null}if(Array.isArray(t)){const items=Array.from(new Set(t.map(t=>t.toLowerCase())).values());if(items.length===1){return items[0]}items.sort();return items}return t.toLowerCase()});const tag=topics.map(t=>{if(t==null){return"null"}if(Array.isArray(t)){return t.join("|")}return t}).join("&");return{fragment:fragment,tag:tag,topics:topics}}async function hasSub(contract,event){const{subs}=getInternal(contract);return subs.get((await getSubInfo(contract,event)).tag)||null}async function getSub(contract,operation,event){const provider=getProvider(contract.runner);assert$1(provider,"contract runner does not support subscribing","UNSUPPORTED_OPERATION",{operation:operation});const{fragment,tag,topics}=await getSubInfo(contract,event);const{addr,subs}=getInternal(contract);let sub=subs.get(tag);if(!sub){const address=addr?addr:contract;const filter={address:address,topics:topics};const listener=log=>{let foundFragment=fragment;if(foundFragment==null){try{foundFragment=contract.interface.getEvent(log.topics[0])}catch(error){}}if(foundFragment){const _foundFragment=foundFragment;const args=fragment?contract.interface.decodeEventLog(fragment,log.data,log.topics):[];emit(contract,event,args,listener=>{return new ContractEventPayload(contract,listener,event,_foundFragment,log)})}else{emit(contract,event,[],listener=>{return new ContractUnknownEventPayload(contract,listener,event,log)})}};let starting=[];const start=()=>{if(starting.length){return}starting.push(provider.on(filter,listener))};const stop=async()=>{if(starting.length==0){return}let started=starting;starting=[];await Promise.all(started);provider.off(filter,listener)};sub={tag:tag,listeners:[],start:start,stop:stop};subs.set(tag,sub)}return sub}let lastEmit=Promise.resolve();async function _emit(contract,event,args,payloadFunc){await lastEmit;const sub=await hasSub(contract,event);if(!sub){return false}const count=sub.listeners.length;sub.listeners=sub.listeners.filter(({listener,once})=>{const passArgs=Array.from(args);if(payloadFunc){passArgs.push(payloadFunc(once?null:listener))}try{listener.call(contract,...passArgs)}catch(error){}return!once});return count>0}async function emit(contract,event,args,payloadFunc){try{await lastEmit}catch(error){}const resultPromise=_emit(contract,event,args,payloadFunc);lastEmit=resultPromise;return await resultPromise}const passProperties=["then"];class BaseContract{target;interface;runner;filters;[internal];fallback;constructor(target,abi,runner,_deployTx){if(runner==null){runner=null}const iface=Interface.from(abi);defineProperties(this,{target:target,runner:runner,interface:iface});Object.defineProperty(this,internal,{value:{}});let addrPromise;let addr=null;let deployTx=null;if(_deployTx){const provider=getProvider(runner);deployTx=new ContractTransactionResponse(this.interface,provider,_deployTx)}let subs=new Map;if(typeof target==="string"){if(isHexString(target)){addr=target;addrPromise=Promise.resolve(target)}else{const resolver=getRunner(runner,"resolveName");if(!canResolve(resolver)){throw makeError("contract runner does not support name resolution","UNSUPPORTED_OPERATION",{operation:"resolveName"})}addrPromise=resolver.resolveName(target).then(addr=>{if(addr==null){throw new Error("TODO")}getInternal(this).addr=addr;return addr})}}else{addrPromise=target.getAddress().then(addr=>{if(addr==null){throw new Error("TODO")}getInternal(this).addr=addr;return addr})}setInternal(this,{addrPromise:addrPromise,addr:addr,deployTx:deployTx,subs:subs});const filters=new Proxy({},{get:(target,_prop,receiver)=>{if(passProperties.indexOf(_prop)>=0){return Reflect.get(target,_prop,receiver)}const prop=String(_prop);const result=this.getEvent(prop);if(result){return result}throw new Error(`unknown contract event: ${prop}`)},has:(target,prop)=>{if(passProperties.indexOf(prop)>=0){return Reflect.has(target,prop)}return Reflect.has(target,prop)||this.interface.hasEvent(String(prop))}});defineProperties(this,{filters:filters});defineProperties(this,{fallback:iface.receive||iface.fallback?buildWrappedFallback(this):null});return new Proxy(this,{get:(target,_prop,receiver)=>{if(_prop in target||passProperties.indexOf(_prop)>=0){return Reflect.get(target,_prop,receiver)}const prop=String(_prop);const result=target.getFunction(prop);if(result){return result}throw new Error(`unknown contract method: ${prop}`)},has:(target,prop)=>{if(prop in target||passProperties.indexOf(prop)>=0){return Reflect.has(target,prop)}return target.interface.hasFunction(String(prop))}})}connect(runner){return new BaseContract(this.target,this.interface,runner)}async getAddress(){return await getInternal(this).addrPromise}async getDeployedCode(){const provider=getProvider(this.runner);assert$1(provider,"runner does not support .provider","UNSUPPORTED_OPERATION",{operation:"getDeployedCode"});const code=await provider.getCode(await this.getAddress());if(code==="0x"){return null}return code}async waitForDeployment(){const deployTx=this.deploymentTransaction();if(deployTx){await deployTx.wait();return this}const code=await this.getDeployedCode();if(code!=null){return this}const provider=getProvider(this.runner);assert$1(provider!=null,"contract runner does not support .provider","UNSUPPORTED_OPERATION",{operation:"waitForDeployment"});return new Promise((resolve,reject)=>{const checkCode=async()=>{try{const code=await this.getDeployedCode();if(code!=null){return resolve(this)}provider.once("block",checkCode)}catch(error){reject(error)}};checkCode()})}deploymentTransaction(){return getInternal(this).deployTx}getFunction(key){if(typeof key!=="string"){key=key.format()}const func=buildWrappedMethod(this,key);return func}getEvent(key){if(typeof key!=="string"){key=key.format()}return buildWrappedEvent(this,key)}async queryTransaction(hash){throw new Error("@TODO")}async queryFilter(event,fromBlock,toBlock){if(fromBlock==null){fromBlock=0}if(toBlock==null){toBlock="latest"}const{addr,addrPromise}=getInternal(this);const address=addr?addr:await addrPromise;const{fragment,topics}=await getSubInfo(this,event);const filter={address:address,topics:topics,fromBlock:fromBlock,toBlock:toBlock};const provider=getProvider(this.runner);assert$1(provider,"contract runner does not have a provider","UNSUPPORTED_OPERATION",{operation:"queryFilter"});return(await provider.getLogs(filter)).map(log=>{let foundFragment=fragment;if(foundFragment==null){try{foundFragment=this.interface.getEvent(log.topics[0])}catch(error){}}if(foundFragment){return new EventLog(log,this.interface,foundFragment)}else{return new Log(log,provider)}})}async on(event,listener){const sub=await getSub(this,"on",event);sub.listeners.push({listener:listener,once:false});sub.start();return this}async once(event,listener){const sub=await getSub(this,"once",event);sub.listeners.push({listener:listener,once:true});sub.start();return this}async emit(event,...args){return await emit(this,event,args,null)}async listenerCount(event){if(event){const sub=await hasSub(this,event);if(!sub){return 0}return sub.listeners.length}const{subs}=getInternal(this);let total=0;for(const{listeners}of subs.values()){total+=listeners.length}return total}async listeners(event){if(event){const sub=await hasSub(this,event);if(!sub){return[]}return sub.listeners.map(({listener})=>listener)}const{subs}=getInternal(this);let result=[];for(const{listeners}of subs.values()){result=result.concat(listeners.map(({listener})=>listener))}return result}async off(event,listener){const sub=await hasSub(this,event);if(!sub){return this}if(listener){const index=sub.listeners.map(({listener})=>listener).indexOf(listener);if(index>=0){sub.listeners.splice(index,1)}}if(listener==null||sub.listeners.length===0){sub.stop();getInternal(this).subs.delete(sub.tag)}return this}async removeAllListeners(event){if(event){const sub=await hasSub(this,event);if(!sub){return this}sub.stop();getInternal(this).subs.delete(sub.tag)}else{const{subs}=getInternal(this);for(const{tag,stop}of subs.values()){stop();subs.delete(tag)}}return this}async addListener(event,listener){return await this.on(event,listener)}async removeListener(event,listener){return await this.off(event,listener)}static buildClass(abi){class CustomContract extends BaseContract{constructor(address,runner=null){super(address,abi,runner)}}return CustomContract}static from(target,abi,runner){if(runner==null){runner=null}const contract=new this(target,abi,runner);return contract}}function _ContractBase(){return BaseContract}class Contract extends _ContractBase(){}class ContractFactory{interface;bytecode;runner;constructor(abi,bytecode,runner){const iface=Interface.from(abi);if(bytecode instanceof Uint8Array){bytecode=hexlify(getBytes(bytecode))}else{if(typeof bytecode==="object"){bytecode=bytecode.object}if(!bytecode.startsWith("0x")){bytecode="0x"+bytecode}bytecode=hexlify(getBytes(bytecode))}defineProperties(this,{bytecode:bytecode,interface:iface,runner:runner||null})}async getDeployTransaction(...args){let overrides={};const fragment=this.interface.deploy;if(fragment.inputs.length+1===args.length){overrides=await copyOverrides(args.pop())}if(fragment.inputs.length!==args.length){throw new Error("incorrect number of arguments to constructor")}const resolvedArgs=await resolveArgs(this.runner,fragment.inputs,args);const data=concat([this.bytecode,this.interface.encodeDeploy(resolvedArgs)]);return Object.assign({},overrides,{data:data})}async deploy(...args){const tx=await this.getDeployTransaction(...args);assert$1(this.runner&&typeof this.runner.sendTransaction==="function","factory runner does not support sending transactions","UNSUPPORTED_OPERATION",{operation:"sendTransaction"});const sentTx=await this.runner.sendTransaction(tx);const address=getCreateAddress(sentTx);return new BaseContract(address,this.interface,this.runner,sentTx)}connect(runner){return new ContractFactory(this.interface,this.bytecode,runner)}static fromSolidity(output,runner){assertArgument(output!=null,"bad compiler output","output",output);if(typeof output==="string"){output=JSON.parse(output)}const abi=output.abi;let bytecode="";if(output.bytecode){bytecode=output.bytecode}else if(output.evm&&output.evm.bytecode){bytecode=output.evm.bytecode}return new this(abi,bytecode,runner)}}function getIpfsLink(link){if(link.match(/^ipfs:\/\/ipfs\//i)){link=link.substring(12)}else if(link.match(/^ipfs:\/\//i)){link=link.substring(7)}else{assertArgument(false,"unsupported IPFS format","link",link)}return`https:/\/gateway.ipfs.io/ipfs/${link}`}class MulticoinProviderPlugin{name;constructor(name){defineProperties(this,{name:name})}connect(proivder){return this}supportsCoinType(coinType){return false}async encodeAddress(coinType,address){throw new Error("unsupported coin")}async decodeAddress(coinType,data){throw new Error("unsupported coin")}}const BasicMulticoinPluginId="org.ethers.plugins.provider.BasicMulticoin";class BasicMulticoinProviderPlugin extends MulticoinProviderPlugin{constructor(){super(BasicMulticoinPluginId)}}const matcherIpfs=new RegExp("^(ipfs)://(.*)$","i");const matchers=[new RegExp("^(https)://(.*)$","i"),new RegExp("^(data):(.*)$","i"),matcherIpfs,new RegExp("^eip155:[0-9]+/(erc[0-9]+):(.*)$","i")];class EnsResolver{provider;address;name;#supports2544;#resolver;constructor(provider,address,name){defineProperties(this,{provider:provider,address:address,name:name});this.#supports2544=null;this.#resolver=new Contract(address,["function supportsInterface(bytes4) view returns (bool)","function resolve(bytes, bytes) view returns (bytes)","function addr(bytes32) view returns (address)","function addr(bytes32, uint) view returns (address)","function text(bytes32, string) view returns (string)","function contenthash(bytes32) view returns (bytes)"],provider)}async supportsWildcard(){if(this.#supports2544==null){this.#supports2544=(async()=>{try{return await this.#resolver.supportsInterface("0x9061b923")}catch(error){if(isError(error,"CALL_EXCEPTION")){return false}this.#supports2544=null;throw error}})()}return await this.#supports2544}async#fetch(funcName,params){params=(params||[]).slice();const iface=this.#resolver.interface;params.unshift(namehash(this.name));let fragment=null;if(await this.supportsWildcard()){fragment=iface.getFunction(funcName);assert$1(fragment,"missing fragment","UNKNOWN_ERROR",{info:{funcName:funcName}});params=[dnsEncode(this.name),iface.encodeFunctionData(fragment,params)];funcName="resolve(bytes,bytes)"}params.push({ccipReadEnable:true});try{const result=await this.#resolver[funcName](...params);if(fragment){return iface.decodeFunctionResult(fragment,result)[0]}return result}catch(error){if(!isError(error,"CALL_EXCEPTION")){throw error}}return null}async getAddress(coinType){if(coinType==null){coinType=60}if(coinType===60){try{const result=await this.#fetch("addr(bytes32)");if(result==null||result===ZeroAddress){return null}return result}catch(error){if(isError(error,"CALL_EXCEPTION")){return null}throw error}}let coinPlugin=null;for(const plugin of this.provider.plugins){if(!(plugin instanceof MulticoinProviderPlugin)){continue}if(plugin.supportsCoinType(coinType)){coinPlugin=plugin;break}}if(coinPlugin==null){return null}const data=await this.#fetch("addr(bytes32,uint)",[coinType]);if(data==null||data==="0x"){return null}const address=await coinPlugin.encodeAddress(coinType,data);if(address!=null){return address}assert$1(false,`invalid coin data`,"UNSUPPORTED_OPERATION",{operation:`getAddress(${coinType})`,info:{coinType:coinType,data:data}})}async getText(key){const data=await this.#fetch("text(bytes32,string)",[key]);if(data==null||data==="0x"){return null}return data}async getContentHash(){const data=await this.#fetch("contenthash(bytes32)");if(data==null||data==="0x"){return null}const ipfs=data.match(/^0x(e3010170|e5010172)(([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f]*))$/);if(ipfs){const scheme=ipfs[1]==="e3010170"?"ipfs":"ipns";const length=parseInt(ipfs[4],16);if(ipfs[5].length===length*2){return`${scheme}:/\/${encodeBase58("0x"+ipfs[2])}`}}const swarm=data.match(/^0xe40101fa011b20([0-9a-f]*)$/);if(swarm&&swarm[1].length===64){return`bzz:/\/${swarm[1]}`}assert$1(false,`invalid or unsupported content hash data`,"UNSUPPORTED_OPERATION",{operation:"getContentHash()",info:{data:data}})}async getAvatar(){const avatar=await this._getAvatar();return avatar.url}async _getAvatar(){const linkage=[{type:"name",value:this.name}];try{const avatar=await this.getText("avatar");if(avatar==null){linkage.push({type:"!avatar",value:""});return{url:null,linkage:linkage}}linkage.push({type:"avatar",value:avatar});for(let i=0;i{if(!Array.isArray(array)){throw new Error("not an array")}return array.map(i=>format(i))}}function object(format,altNames){return value=>{const result={};for(const key in format){let srcKey=key;if(altNames&&key in altNames&&!(srcKey in value)){for(const altKey of altNames[key]){if(altKey in value){srcKey=altKey;break}}}try{const nv=format[key](value[srcKey]);if(nv!==undefined){result[key]=nv}}catch(error){const message=error instanceof Error?error.message:"not-an-error";assert$1(false,`invalid value for value.${key} (${message})`,"BAD_DATA",{value:value})}}return result}}function formatBoolean(value){switch(value){case true:case"true":return true;case false:case"false":return false}assertArgument(false,`invalid boolean; ${JSON.stringify(value)}`,"value",value)}function formatData(value){assertArgument(isHexString(value,true),"invalid data","value",value);return value}function formatHash(value){assertArgument(isHexString(value,32),"invalid hash","value",value);return value}function formatUint256(value){if(!isHexString(value)){throw new Error("invalid uint256")}return zeroPadValue(value,32)}const _formatLog=object({address:getAddress,blockHash:formatHash,blockNumber:getNumber,data:formatData,index:getNumber,removed:formatBoolean,topics:arrayOf(formatHash),transactionHash:formatHash,transactionIndex:getNumber},{index:["logIndex"]});function formatLog(value){return _formatLog(value)}const _formatBlock=object({hash:allowNull(formatHash),parentHash:formatHash,number:getNumber,timestamp:getNumber,nonce:allowNull(formatData),difficulty:getBigInt,gasLimit:getBigInt,gasUsed:getBigInt,miner:allowNull(getAddress),extraData:formatData,baseFeePerGas:allowNull(getBigInt)});function formatBlock(value){const result=_formatBlock(value);result.transactions=value.transactions.map(tx=>{if(typeof tx==="string"){return tx}return formatTransactionResponse(tx)});return result}const _formatReceiptLog=object({transactionIndex:getNumber,blockNumber:getNumber,transactionHash:formatHash,address:getAddress,topics:arrayOf(formatHash),data:formatData,index:getNumber,blockHash:formatHash},{index:["logIndex"]});function formatReceiptLog(value){return _formatReceiptLog(value)}const _formatTransactionReceipt=object({to:allowNull(getAddress,null),from:allowNull(getAddress,null),contractAddress:allowNull(getAddress,null),index:getNumber,root:allowNull(hexlify),gasUsed:getBigInt,logsBloom:allowNull(formatData),blockHash:formatHash,hash:formatHash,logs:arrayOf(formatReceiptLog),blockNumber:getNumber,cumulativeGasUsed:getBigInt,effectiveGasPrice:allowNull(getBigInt),status:allowNull(getNumber),type:allowNull(getNumber,0)},{effectiveGasPrice:["gasPrice"],hash:["transactionHash"],index:["transactionIndex"]});function formatTransactionReceipt(value){return _formatTransactionReceipt(value)}function formatTransactionResponse(value){if(value.to&&getBigInt(value.to)===BN_0){value.to="0x0000000000000000000000000000000000000000"}const result=object({hash:formatHash,type:value=>{if(value==="0x"||value==null){return 0}return getNumber(value)},accessList:allowNull(accessListify,null),blockHash:allowNull(formatHash,null),blockNumber:allowNull(getNumber,null),transactionIndex:allowNull(getNumber,null),from:getAddress,gasPrice:allowNull(getBigInt),maxPriorityFeePerGas:allowNull(getBigInt),maxFeePerGas:allowNull(getBigInt),gasLimit:getBigInt,to:allowNull(getAddress,null),value:getBigInt,nonce:getNumber,data:formatData,creates:allowNull(getAddress,null),chainId:allowNull(getBigInt,null)},{data:["input"],gasLimit:["gas"]})(value);if(result.to==null&&result.creates==null){result.creates=getCreateAddress(result)}if((value.type===1||value.type===2)&&value.accessList==null){result.accessList=[]}if(value.signature){result.signature=Signature.from(value.signature)}else{result.signature=Signature.from(value)}if(result.chainId==null){const chainId=result.signature.legacyChainId;if(chainId!=null){result.chainId=chainId}}if(result.blockHash&&getBigInt(result.blockHash)===BN_0){result.blockHash=null}return result}const EnsAddress="0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e";class NetworkPlugin{name;constructor(name){defineProperties(this,{name:name})}clone(){return new NetworkPlugin(this.name)}}class GasCostPlugin extends NetworkPlugin{effectiveBlock;txBase;txCreate;txDataZero;txDataNonzero;txAccessListStorageKey;txAccessListAddress;constructor(effectiveBlock,costs){if(effectiveBlock==null){effectiveBlock=0}super(`org.ethers.network.plugins.GasCost#${effectiveBlock||0}`);const props={effectiveBlock:effectiveBlock};function set(name,nullish){let value=(costs||{})[name];if(value==null){value=nullish}assertArgument(typeof value==="number",`invalud value for ${name}`,"costs",costs);props[name]=value}set("txBase",21e3);set("txCreate",32e3);set("txDataZero",4);set("txDataNonzero",16);set("txAccessListStorageKey",1900);set("txAccessListAddress",2400);defineProperties(this,props)}clone(){return new GasCostPlugin(this.effectiveBlock,this)}}class EnsPlugin extends NetworkPlugin{address;targetNetwork;constructor(address,targetNetwork){super("org.ethers.plugins.network.Ens");defineProperties(this,{address:address||EnsAddress,targetNetwork:targetNetwork==null?1:targetNetwork})}clone(){return new EnsPlugin(this.address,this.targetNetwork)}}class FeeDataNetworkPlugin extends NetworkPlugin{#feeDataFunc;get feeDataFunc(){return this.#feeDataFunc}constructor(feeDataFunc){super("org.ethers.plugins.network.FeeData");this.#feeDataFunc=feeDataFunc}async getFeeData(provider){return await this.#feeDataFunc(provider)}clone(){return new FeeDataNetworkPlugin(this.#feeDataFunc)}}const Networks=new Map;class Network{#name;#chainId;#plugins;constructor(name,chainId){this.#name=name;this.#chainId=getBigInt(chainId);this.#plugins=new Map}toJSON(){return{name:this.name,chainId:this.chainId}}get name(){return this.#name}set name(value){this.#name=value}get chainId(){return this.#chainId}set chainId(value){this.#chainId=getBigInt(value,"chainId")}get plugins(){return Array.from(this.#plugins.values())}attachPlugin(plugin){if(this.#plugins.get(plugin.name)){throw new Error(`cannot replace existing plugin: ${plugin.name} `)}this.#plugins.set(plugin.name,plugin.clone());return this}getPlugin(name){return this.#plugins.get(name)||null}getPlugins(basename){return this.plugins.filter(p=>p.name.split("#")[0]===basename)}clone(){const clone=new Network(this.name,this.chainId);this.plugins.forEach(plugin=>{clone.attachPlugin(plugin.clone())});return clone}computeIntrinsicGas(tx){const costs=this.getPlugin("org.ethers.plugins.network.GasCost")||new GasCostPlugin;let gas=costs.txBase;if(tx.to==null){gas+=costs.txCreate}if(tx.data){for(let i=2;i{Network.register(name,func)})}}registerEth("mainnet",1,{ensNetwork:1,altNames:["homestead"]});registerEth("ropsten",3,{ensNetwork:3});registerEth("rinkeby",4,{ensNetwork:4});registerEth("goerli",5,{ensNetwork:5});registerEth("kovan",42,{ensNetwork:42});registerEth("sepolia",11155111,{});registerEth("classic",61,{});registerEth("classicKotti",6,{});registerEth("xdai",100,{ensNetwork:1});registerEth("optimism",10,{ensNetwork:1,etherscan:{url:"https://api-optimistic.etherscan.io/"}});registerEth("optimism-goerli",420,{etherscan:{url:"https://api-goerli-optimistic.etherscan.io/"}});registerEth("arbitrum",42161,{ensNetwork:1,etherscan:{url:"https://api.arbiscan.io/"}});registerEth("arbitrum-goerli",421613,{etherscan:{url:"https://api-goerli.arbiscan.io/"}});registerEth("matic",137,{ensNetwork:1,etherscan:{url:"https://api.polygonscan.com/"}});registerEth("matic-mumbai",80001,{altNames:["maticMumbai","maticmum"],etherscan:{url:"https://api-testnet.polygonscan.com/"}});registerEth("bnb",56,{ensNetwork:1,etherscan:{url:"http://api.bscscan.com"}});registerEth("bnbt",97,{etherscan:{url:"http://api-testnet.bscscan.com"}})}function copy$2(obj){return JSON.parse(JSON.stringify(obj))}function getPollingSubscriber(provider,event){if(event==="block"){return new PollingBlockSubscriber(provider)}if(isHexString(event,32)){return new PollingTransactionSubscriber(provider,event)}assert$1(false,"unsupported polling event","UNSUPPORTED_OPERATION",{operation:"getPollingSubscriber",info:{event:event}})}class PollingBlockSubscriber{#provider;#poller;#interval;#blockNumber;constructor(provider){this.#provider=provider;this.#poller=null;this.#interval=4e3;this.#blockNumber=-2}get pollingInterval(){return this.#interval}set pollingInterval(value){this.#interval=value}async#poll(){try{const blockNumber=await this.#provider.getBlockNumber();if(this.#blockNumber===-2){this.#blockNumber=blockNumber;return}if(blockNumber!==this.#blockNumber){for(let b=this.#blockNumber+1;b<=blockNumber;b++){if(this.#poller==null){return}await this.#provider.emit("block",b)}this.#blockNumber=blockNumber}}catch(error){}if(this.#poller==null){return}this.#poller=this.#provider._setTimeout(this.#poll.bind(this),this.#interval)}start(){if(this.#poller){return}this.#poller=this.#provider._setTimeout(this.#poll.bind(this),this.#interval);this.#poll()}stop(){if(!this.#poller){return}this.#provider._clearTimeout(this.#poller);this.#poller=null}pause(dropWhilePaused){this.stop();if(dropWhilePaused){this.#blockNumber=-2}}resume(){this.start()}}class OnBlockSubscriber{#provider;#poll;#running;constructor(provider){this.#provider=provider;this.#running=false;this.#poll=blockNumber=>{this._poll(blockNumber,this.#provider)}}async _poll(blockNumber,provider){throw new Error("sub-classes must override this")}start(){if(this.#running){return}this.#running=true;this.#poll(-2);this.#provider.on("block",this.#poll)}stop(){if(!this.#running){return}this.#running=false;this.#provider.off("block",this.#poll)}pause(dropWhilePaused){this.stop()}resume(){this.start()}}class PollingOrphanSubscriber extends OnBlockSubscriber{#filter;constructor(provider,filter){super(provider);this.#filter=copy$2(filter)}async _poll(blockNumber,provider){throw new Error("@TODO");console.log(this.#filter)}}class PollingTransactionSubscriber extends OnBlockSubscriber{#hash;constructor(provider,hash){super(provider);this.#hash=hash}async _poll(blockNumber,provider){const tx=await provider.getTransactionReceipt(this.#hash);if(tx){provider.emit(this.#hash,tx)}}}class PollingEventSubscriber{#provider;#filter;#poller;#running;#blockNumber;constructor(provider,filter){this.#provider=provider;this.#filter=copy$2(filter);this.#poller=this.#poll.bind(this);this.#running=false;this.#blockNumber=-2}async#poll(blockNumber){if(this.#blockNumber===-2){return}const filter=copy$2(this.#filter);filter.fromBlock=this.#blockNumber+1;filter.toBlock=blockNumber;const logs=await this.#provider.getLogs(filter);if(logs.length===0){if(this.#blockNumber{this.#blockNumber=blockNumber})}this.#provider.on("block",this.#poller)}stop(){if(!this.#running){return}this.#running=false;this.#provider.off("block",this.#poller)}pause(dropWhilePaused){this.stop();if(dropWhilePaused){this.#blockNumber=-2}}resume(){this.start()}}const BN_2$1=BigInt(2);const MAX_CCIP_REDIRECTS=10;function isPromise$1(value){return value&&typeof value.then==="function"}function getTag(prefix,value){return prefix+":"+JSON.stringify(value,(k,v)=>{if(v==null){return"null"}if(typeof v==="bigint"){return`bigint:${v.toString()}`}if(typeof v==="string"){return v.toLowerCase()}if(typeof v==="object"&&!Array.isArray(v)){const keys=Object.keys(v);keys.sort();return keys.reduce((accum,key)=>{accum[key]=v[key];return accum},{})}return v})}class UnmanagedSubscriber{name;constructor(name){defineProperties(this,{name:name})}start(){}stop(){}pause(dropWhilePaused){}resume(){}}function copy$1(value){return JSON.parse(JSON.stringify(value))}function concisify(items){items=Array.from(new Set(items).values());items.sort();return items}async function getSubscription(_event,provider){if(_event==null){throw new Error("invalid event")}if(Array.isArray(_event)){_event={topics:_event}}if(typeof _event==="string"){switch(_event){case"block":case"pending":case"debug":case"network":{return{type:_event,tag:_event}}}}if(isHexString(_event,32)){const hash=_event.toLowerCase();return{type:"transaction",tag:getTag("tx",{hash:hash}),hash:hash}}if(_event.orphan){const event=_event;return{type:"orphan",tag:getTag("orphan",event),filter:copy$1(event)}}if(_event.address||_event.topics){const event=_event;const filter={topics:(event.topics||[]).map(t=>{if(t==null){return null}if(Array.isArray(t)){return concisify(t.map(t=>t.toLowerCase()))}return t.toLowerCase()})};if(event.address){const addresses=[];const promises=[];const addAddress=addr=>{if(isHexString(addr)){addresses.push(addr)}else{promises.push((async()=>{addresses.push(await resolveAddress(addr,provider))})())}};if(Array.isArray(event.address)){event.address.forEach(addAddress)}else{addAddress(event.address)}if(promises.length){await Promise.all(promises)}filter.address=concisify(addresses.map(a=>a.toLowerCase()))}return{filter:filter,tag:getTag("event",filter),type:"event"}}assertArgument(false,"unknown ProviderEvent","event",_event)}function getTime$1(){return(new Date).getTime()}class AbstractProvider{#subs;#plugins;#pausedState;#networkPromise;#anyNetwork;#performCache;#lastBlockNumber;#nextTimer;#timers;#disableCcipRead;constructor(_network){if(_network==="any"){this.#anyNetwork=true;this.#networkPromise=null}else if(_network){const network=Network.from(_network);this.#anyNetwork=false;this.#networkPromise=Promise.resolve(network);setTimeout(()=>{this.emit("network",network,null)},0)}else{this.#anyNetwork=false;this.#networkPromise=null}this.#lastBlockNumber=-1;this.#performCache=new Map;this.#subs=new Map;this.#plugins=new Map;this.#pausedState=null;this.#nextTimer=1;this.#timers=new Map;this.#disableCcipRead=false}get provider(){return this}get plugins(){return Array.from(this.#plugins.values())}attachPlugin(plugin){if(this.#plugins.get(plugin.name)){throw new Error(`cannot replace existing plugin: ${plugin.name} `)}this.#plugins.set(plugin.name,plugin.connect(this));return this}getPlugin(name){return this.#plugins.get(name)||null}get disableCcipRead(){return this.#disableCcipRead}set disableCcipRead(value){this.#disableCcipRead=!!value}async#perform(req){const tag=getTag(req.method,req);let perform=this.#performCache.get(tag);if(!perform){perform=this._perform(req);this.#performCache.set(tag,perform);setTimeout(()=>{if(this.#performCache.get(tag)===perform){this.#performCache.delete(tag)}},250)}return await perform}async ccipReadFetch(tx,calldata,urls){if(this.disableCcipRead||urls.length===0||tx.to==null){return null}const sender=tx.to.toLowerCase();const data=calldata.toLowerCase();const errorMessages=[];for(let i=0;i=500,`response not found during CCIP fetch: ${errorMessage}`,"OFFCHAIN_FAULT",{reason:"404_MISSING_RESOURCE",transaction:tx,info:{url:url,errorMessage:errorMessage}});errorMessages.push(errorMessage)}assert$1(false,`error encountered during CCIP fetch: ${errorMessages.map(m=>JSON.stringify(m)).join(", ")}`,"OFFCHAIN_FAULT",{reason:"500_SERVER_ERROR",transaction:tx,info:{urls:urls,errorMessages:errorMessages}})}_wrapBlock(value,network){return new Block(formatBlock(value),this)}_wrapLog(value,network){return new Log(formatLog(value),this)}_wrapTransactionReceipt(value,network){return new TransactionReceipt(formatTransactionReceipt(value),this)}_wrapTransactionResponse(tx,network){return new TransactionResponse(formatTransactionResponse(tx),this)}_detectNetwork(){assert$1(false,"sub-classes must implement this","UNSUPPORTED_OPERATION",{operation:"_detectNetwork"})}async _perform(req){assert$1(false,`unsupported method: ${req.method}`,"UNSUPPORTED_OPERATION",{operation:req.method,info:req})}async getBlockNumber(){const blockNumber=getNumber(await this.#perform({method:"getBlockNumber"}),"%response");if(this.#lastBlockNumber>=0){this.#lastBlockNumber=blockNumber}return blockNumber}_getAddress(address){return resolveAddress(address,this)}_getBlockTag(blockTag){if(blockTag==null){return"latest"}switch(blockTag){case"earliest":return"0x0";case"latest":case"pending":case"safe":case"finalized":return blockTag}if(isHexString(blockTag)){if(isHexString(blockTag,32)){return blockTag}return toQuantity(blockTag)}if(typeof blockTag==="bigint"){blockTag=getNumber(blockTag,"blockTag")}if(typeof blockTag==="number"){if(blockTag>=0){return toQuantity(blockTag)}if(this.#lastBlockNumber>=0){return toQuantity(this.#lastBlockNumber+blockTag)}return this.getBlockNumber().then(b=>toQuantity(b+blockTag))}assertArgument(false,"invalid blockTag","blockTag",blockTag)}_getFilter(filter){const topics=(filter.topics||[]).map(t=>{if(t==null){return null}if(Array.isArray(t)){return concisify(t.map(t=>t.toLowerCase()))}return t.toLowerCase()});const blockHash="blockHash"in filter?filter.blockHash:undefined;const resolve=(_address,fromBlock,toBlock)=>{let address=undefined;switch(_address.length){case 0:break;case 1:address=_address[0];break;default:_address.sort();address=_address}if(blockHash){if(fromBlock!=null||toBlock!=null){throw new Error("invalid filter")}}const filter={};if(address){filter.address=address}if(topics.length){filter.topics=topics}if(fromBlock){filter.fromBlock=fromBlock}if(toBlock){filter.toBlock=toBlock}if(blockHash){filter.blockHash=blockHash}return filter};let address=[];if(filter.address){if(Array.isArray(filter.address)){for(const addr of filter.address){address.push(this._getAddress(addr))}}else{address.push(this._getAddress(filter.address))}}let fromBlock=undefined;if("fromBlock"in filter){fromBlock=this._getBlockTag(filter.fromBlock)}let toBlock=undefined;if("toBlock"in filter){toBlock=this._getBlockTag(filter.toBlock)}if(address.filter(a=>typeof a!=="string").length||fromBlock!=null&&typeof fromBlock!=="string"||toBlock!=null&&typeof toBlock!=="string"){return Promise.all([Promise.all(address),fromBlock,toBlock]).then(result=>{return resolve(result[0],result[1],result[2])})}return resolve(address,fromBlock,toBlock)}_getTransactionRequest(_request){const request=copyRequest(_request);const promises=[];["to","from"].forEach(key=>{if(request[key]==null){return}const addr=resolveAddress(request[key]);if(isPromise$1(addr)){promises.push(async function(){request[key]=await addr}())}else{request[key]=addr}});if(request.blockTag!=null){const blockTag=this._getBlockTag(request.blockTag);if(isPromise$1(blockTag)){promises.push(async function(){request.blockTag=await blockTag}())}else{request.blockTag=blockTag}}if(promises.length){return async function(){await Promise.all(promises);return request}()}return request}async getNetwork(){if(this.#networkPromise==null){const detectNetwork=this._detectNetwork().then(network=>{this.emit("network",network,null);return network},error=>{if(this.#networkPromise===detectNetwork){this.#networkPromise=null}throw error});this.#networkPromise=detectNetwork;return(await detectNetwork).clone()}const networkPromise=this.#networkPromise;const[expected,actual]=await Promise.all([networkPromise,this._detectNetwork()]);if(expected.chainId!==actual.chainId){if(this.#anyNetwork){this.emit("network",actual,expected);if(this.#networkPromise===networkPromise){this.#networkPromise=Promise.resolve(actual)}}else{assert$1(false,`network changed: ${expected.chainId} => ${actual.chainId} `,"NETWORK_ERROR",{event:"changed"})}}return expected.clone()}async getFeeData(){const{block,gasPrice}=await resolveProperties({block:this.getBlock("latest"),gasPrice:(async()=>{try{const gasPrice=await this.#perform({method:"getGasPrice"});return getBigInt(gasPrice,"%response")}catch(error){}return null})()});let maxFeePerGas=null,maxPriorityFeePerGas=null;if(block&&block.baseFeePerGas){maxPriorityFeePerGas=BigInt("1000000000");maxFeePerGas=block.baseFeePerGas*BN_2$1+maxPriorityFeePerGas}return new FeeData(gasPrice,maxFeePerGas,maxPriorityFeePerGas)}async estimateGas(_tx){let tx=this._getTransactionRequest(_tx);if(isPromise$1(tx)){tx=await tx}return getBigInt(await this.#perform({method:"estimateGas",transaction:tx}),"%response")}async#call(tx,blockTag,attempt){assert$1(attempt=0&&blockTag==="latest"&&transaction.to!=null&&dataSlice(error.data,0,4)==="0x556f1830"){const data=error.data;const txSender=await resolveAddress(transaction.to,this);let ccipArgs;try{ccipArgs=parseOffchainLookup(dataSlice(error.data,4))}catch(error){assert$1(false,error.message,"OFFCHAIN_FAULT",{reason:"BAD_DATA",transaction:transaction,info:{data:data}})}assert$1(ccipArgs.sender.toLowerCase()===txSender.toLowerCase(),"CCIP Read sender mismatch","CALL_EXCEPTION",{action:"call",data:data,reason:"OffchainLookup",transaction:transaction,invocation:null,revert:{signature:"OffchainLookup(address,string[],bytes,bytes4,bytes)",name:"OffchainLookup",args:ccipArgs.errorArgs}});const ccipResult=await this.ccipReadFetch(transaction,ccipArgs.calldata,ccipArgs.urls);assert$1(ccipResult!=null,"CCIP Read failed to fetch data","OFFCHAIN_FAULT",{reason:"FETCH_FAILED",transaction:transaction,info:{data:error.data,errorArgs:ccipArgs.errorArgs}});const tx={to:txSender,data:concat([ccipArgs.selector,encodeBytes([ccipResult,ccipArgs.extraData])])};this.emit("debug",{action:"sendCcipReadCall",transaction:tx});try{const result=await this.#call(tx,blockTag,attempt+1);this.emit("debug",{action:"receiveCcipReadCallResult",transaction:Object.assign({},tx),result:result});return result}catch(error){this.emit("debug",{action:"receiveCcipReadCallError",transaction:Object.assign({},tx),error:error});throw error}}throw error}}async#checkNetwork(promise){const{value}=await resolveProperties({network:this.getNetwork(),value:promise});return value}async call(_tx){const{tx,blockTag}=await resolveProperties({tx:this._getTransactionRequest(_tx),blockTag:this._getBlockTag(_tx.blockTag)});return await this.#checkNetwork(this.#call(tx,blockTag,_tx.enableCcipRead?0:-1))}async#getAccountValue(request,_address,_blockTag){let address=this._getAddress(_address);let blockTag=this._getBlockTag(_blockTag);if(typeof address!=="string"||typeof blockTag!=="string"){[address,blockTag]=await Promise.all([address,blockTag])}return await this.#checkNetwork(this.#perform(Object.assign(request,{address:address,blockTag:blockTag})))}async getBalance(address,blockTag){return getBigInt(await this.#getAccountValue({method:"getBalance"},address,blockTag),"%response")}async getTransactionCount(address,blockTag){return getNumber(await this.#getAccountValue({method:"getTransactionCount"},address,blockTag),"%response")}async getCode(address,blockTag){return hexlify(await this.#getAccountValue({method:"getCode"},address,blockTag))}async getStorage(address,_position,blockTag){const position=getBigInt(_position,"position");return hexlify(await this.#getAccountValue({method:"getStorage",position:position},address,blockTag))}async broadcastTransaction(signedTx){const{blockNumber,hash,network}=await resolveProperties({blockNumber:this.getBlockNumber(),hash:this._perform({method:"broadcastTransaction",signedTransaction:signedTx}),network:this.getNetwork()});const tx=Transaction.from(signedTx);if(tx.hash!==hash){throw new Error("@TODO: the returned hash did not match")}return this._wrapTransactionResponse(tx,network).replaceableTransaction(blockNumber)}async#getBlock(block,includeTransactions){if(isHexString(block,32)){return await this.#perform({method:"getBlock",blockHash:block,includeTransactions:includeTransactions})}let blockTag=this._getBlockTag(block);if(typeof blockTag!=="string"){blockTag=await blockTag}return await this.#perform({method:"getBlock",blockTag:blockTag,includeTransactions:includeTransactions})}async getBlock(block,prefetchTxs){const{network,params}=await resolveProperties({network:this.getNetwork(),params:this.#getBlock(block,!!prefetchTxs)});if(params==null){return null}return this._wrapBlock(params,network)}async getTransaction(hash){const{network,params}=await resolveProperties({network:this.getNetwork(),params:this.#perform({method:"getTransaction",hash:hash})});if(params==null){return null}return this._wrapTransactionResponse(params,network)}async getTransactionReceipt(hash){const{network,params}=await resolveProperties({network:this.getNetwork(),params:this.#perform({method:"getTransactionReceipt",hash:hash})});if(params==null){return null}if(params.gasPrice==null&¶ms.effectiveGasPrice==null){const tx=await this.#perform({method:"getTransaction",hash:hash});if(tx==null){throw new Error("report this; could not find tx or effectiveGasPrice")}params.effectiveGasPrice=tx.gasPrice}return this._wrapTransactionReceipt(params,network)}async getTransactionResult(hash){const{result}=await resolveProperties({network:this.getNetwork(),result:this.#perform({method:"getTransactionResult",hash:hash})});if(result==null){return null}return hexlify(result)}async getLogs(_filter){let filter=this._getFilter(_filter);if(isPromise$1(filter)){filter=await filter}const{network,params}=await resolveProperties({network:this.getNetwork(),params:this.#perform({method:"getLogs",filter:filter})});return params.map(p=>this._wrapLog(p,network))}_getProvider(chainId){assert$1(false,"provider cannot connect to target network","UNSUPPORTED_OPERATION",{operation:"_getProvider()"})}async getResolver(name){return await EnsResolver.fromName(this,name)}async getAvatar(name){const resolver=await this.getResolver(name);if(resolver){return await resolver.getAvatar()}return null}async resolveName(name){const resolver=await this.getResolver(name);if(resolver){return await resolver.getAddress()}return null}async lookupAddress(address){address=getAddress(address);const node=namehash(address.substring(2).toLowerCase()+".addr.reverse");try{const ensAddr=await EnsResolver.getEnsAddress(this);const ensContract=new Contract(ensAddr,["function resolver(bytes32) view returns (address)"],this);const resolver=await ensContract.resolver(node);if(resolver==null||resolver===ZeroHash){return null}const resolverContract=new Contract(resolver,["function name(bytes32) view returns (string)"],this);const name=await resolverContract.name(node);const check=await this.resolveName(name);if(check!==address){return null}return name}catch(error){if(isError(error,"BAD_DATA")&&error.value==="0x"){return null}if(isError(error,"CALL_EXCEPTION")){return null}throw error}return null}async waitForTransaction(hash,_confirms,timeout){const confirms=_confirms!=null?_confirms:1;if(confirms===0){return this.getTransactionReceipt(hash)}return new Promise(async(resolve,reject)=>{let timer=null;const listener=async blockNumber=>{try{const receipt=await this.getTransactionReceipt(hash);if(receipt!=null){if(blockNumber-receipt.blockNumber+1>=confirms){resolve(receipt);if(timer){clearTimeout(timer);timer=null}return}}}catch(error){console.log("EEE",error)}this.once("block",listener)};if(timeout!=null){timer=setTimeout(()=>{if(timer==null){return}timer=null;this.off("block",listener);reject(makeError("timeout","TIMEOUT",{reason:"timeout"}))},timeout)}listener(await this.getBlockNumber())})}async waitForBlock(blockTag){assert$1(false,"not implemented yet","NOT_IMPLEMENTED",{operation:"waitForBlock"})}_clearTimeout(timerId){const timer=this.#timers.get(timerId);if(!timer){return}if(timer.timer){clearTimeout(timer.timer)}this.#timers.delete(timerId)}_setTimeout(_func,timeout){if(timeout==null){timeout=0}const timerId=this.#nextTimer++;const func=()=>{this.#timers.delete(timerId);_func()};if(this.paused){this.#timers.set(timerId,{timer:null,func:func,time:timeout})}else{const timer=setTimeout(func,timeout);this.#timers.set(timerId,{timer:timer,func:func,time:getTime$1()})}return timerId}_forEachSubscriber(func){for(const sub of this.#subs.values()){func(sub.subscriber)}}_getSubscriber(sub){switch(sub.type){case"debug":case"network":return new UnmanagedSubscriber(sub.type);case"block":return new PollingBlockSubscriber(this);case"event":return new PollingEventSubscriber(this,sub.filter);case"transaction":return new PollingTransactionSubscriber(this,sub.hash);case"orphan":return new PollingOrphanSubscriber(this,sub.filter)}throw new Error(`unsupported event: ${sub.type}`)}_recoverSubscriber(oldSub,newSub){for(const sub of this.#subs.values()){if(sub.subscriber===oldSub){if(sub.started){sub.subscriber.stop()}sub.subscriber=newSub;if(sub.started){newSub.start()}if(this.#pausedState!=null){newSub.pause(this.#pausedState)}break}}}async#hasSub(event,emitArgs){let sub=await getSubscription(event,this);if(sub.type==="event"&&emitArgs&&emitArgs.length>0&&emitArgs[0].removed===true){sub=await getSubscription({orphan:"drop-log",log:emitArgs[0]},this)}return this.#subs.get(sub.tag)||null}async#getSub(event){const subscription=await getSubscription(event,this);const tag=subscription.tag;let sub=this.#subs.get(tag);if(!sub){const subscriber=this._getSubscriber(subscription);const addressableMap=new WeakMap;const nameMap=new Map;sub={subscriber:subscriber,tag:tag,addressableMap:addressableMap,nameMap:nameMap,started:false,listeners:[]};this.#subs.set(tag,sub)}return sub}async on(event,listener){const sub=await this.#getSub(event);sub.listeners.push({listener:listener,once:false});if(!sub.started){sub.subscriber.start();sub.started=true;if(this.#pausedState!=null){sub.subscriber.pause(this.#pausedState)}}return this}async once(event,listener){const sub=await this.#getSub(event);sub.listeners.push({listener:listener,once:true});if(!sub.started){sub.subscriber.start();sub.started=true;if(this.#pausedState!=null){sub.subscriber.pause(this.#pausedState)}}return this}async emit(event,...args){const sub=await this.#hasSub(event,args);if(!sub||sub.listeners.length===0){return false}const count=sub.listeners.length;sub.listeners=sub.listeners.filter(({listener,once})=>{const payload=new EventPayload(this,once?null:listener,event);try{listener.call(this,...args,payload)}catch(error){}return!once});if(sub.listeners.length===0){if(sub.started){sub.subscriber.stop()}this.#subs.delete(sub.tag)}return count>0}async listenerCount(event){if(event){const sub=await this.#hasSub(event);if(!sub){return 0}return sub.listeners.length}let total=0;for(const{listeners}of this.#subs.values()){total+=listeners.length}return total}async listeners(event){if(event){const sub=await this.#hasSub(event);if(!sub){return[]}return sub.listeners.map(({listener})=>listener)}let result=[];for(const{listeners}of this.#subs.values()){result=result.concat(listeners.map(({listener})=>listener))}return result}async off(event,listener){const sub=await this.#hasSub(event);if(!sub){return this}if(listener){const index=sub.listeners.map(({listener})=>listener).indexOf(listener);if(index>=0){sub.listeners.splice(index,1)}}if(!listener||sub.listeners.length===0){if(sub.started){sub.subscriber.stop()}this.#subs.delete(sub.tag)}return this}async removeAllListeners(event){if(event){const{tag,started,subscriber}=await this.#getSub(event);if(started){subscriber.stop()}this.#subs.delete(tag)}else{for(const[tag,{started,subscriber}]of this.#subs){if(started){subscriber.stop()}this.#subs.delete(tag)}}return this}async addListener(event,listener){return await this.on(event,listener)}async removeListener(event,listener){return this.off(event,listener)}destroy(){this.removeAllListeners();for(const timerId of this.#timers.keys()){this._clearTimeout(timerId)}}get paused(){return this.#pausedState!=null}set paused(pause){if(!!pause===this.paused){return}if(this.paused){this.resume()}else{this.pause(false)}}pause(dropWhilePaused){this.#lastBlockNumber=-1;if(this.#pausedState!=null){if(this.#pausedState==!!dropWhilePaused){return}assert$1(false,"cannot change pause type; resume first","UNSUPPORTED_OPERATION",{operation:"pause"})}this._forEachSubscriber(s=>s.pause(dropWhilePaused));this.#pausedState=!!dropWhilePaused;for(const timer of this.#timers.values()){if(timer.timer){clearTimeout(timer.timer)}timer.time=getTime$1()-timer.time}}resume(){if(this.#pausedState==null){return}this._forEachSubscriber(s=>s.resume());this.#pausedState=null;for(const timer of this.#timers.values()){let timeout=timer.time;if(timeout<0){timeout=0}timer.time=getTime$1();setTimeout(timer.func,timeout)}}}function _parseString(result,start){try{const bytes=_parseBytes(result,start);if(bytes){return toUtf8String(bytes)}}catch(error){}return null}function _parseBytes(result,start){if(result==="0x"){return null}try{const offset=getNumber(dataSlice(result,start,start+32));const length=getNumber(dataSlice(result,offset,offset+32));return dataSlice(result,offset+32,offset+32+length)}catch(error){}return null}function numPad(value){const result=toBeArray(value);if(result.length>32){throw new Error("internal; should not happen")}const padded=new Uint8Array(32);padded.set(result,32-result.length);return padded}function bytesPad(value){if(value.length%32===0){return value}const result=new Uint8Array(Math.ceil(value.length/32)*32);result.set(value);return result}const empty=new Uint8Array([]);function encodeBytes(datas){const result=[];let byteCount=0;for(let i=0;i=5*32,"insufficient OffchainLookup data","OFFCHAIN_FAULT",{reason:"insufficient OffchainLookup data"});const sender=dataSlice(data,0,32);assert$1(dataSlice(sender,0,12)===dataSlice(zeros,0,12),"corrupt OffchainLookup sender","OFFCHAIN_FAULT",{reason:"corrupt OffchainLookup sender"});result.sender=dataSlice(sender,12);try{const urls=[];const urlsOffset=getNumber(dataSlice(data,32,64));const urlsLength=getNumber(dataSlice(data,urlsOffset,urlsOffset+32));const urlsData=dataSlice(data,urlsOffset+32);for(let u=0;uresult[k]);return result}function checkProvider(signer,operation){if(signer.provider){return signer.provider}assert$1(false,"missing provider","UNSUPPORTED_OPERATION",{operation:operation})}async function populate(signer,tx){let pop=copyRequest(tx);if(pop.to!=null){pop.to=resolveAddress(pop.to,signer)}if(pop.from!=null){const from=pop.from;pop.from=Promise.all([signer.getAddress(),resolveAddress(from,signer)]).then(([address,from])=>{assertArgument(address.toLowerCase()===from.toLowerCase(),"transaction from mismatch","tx.from",from);return address})}else{pop.from=signer.getAddress()}return await resolveProperties(pop)}class AbstractSigner{provider;constructor(provider){defineProperties(this,{provider:provider||null})}async getNonce(blockTag){return checkProvider(this,"getTransactionCount").getTransactionCount(await this.getAddress(),blockTag)}async populateCall(tx){const pop=await populate(this,tx);return pop}async populateTransaction(tx){const provider=checkProvider(this,"populateTransaction");const pop=await populate(this,tx);if(pop.nonce==null){pop.nonce=await this.getNonce("pending")}if(pop.gasLimit==null){pop.gasLimit=await this.estimateGas(pop)}const network=await this.provider.getNetwork();if(pop.chainId!=null){const chainId=getBigInt(pop.chainId);assertArgument(chainId===network.chainId,"transaction chainId mismatch","tx.chainId",tx.chainId)}else{pop.chainId=network.chainId}const hasEip1559=pop.maxFeePerGas!=null||pop.maxPriorityFeePerGas!=null;if(pop.gasPrice!=null&&(pop.type===2||hasEip1559)){assertArgument(false,"eip-1559 transaction do not support gasPrice","tx",tx)}else if((pop.type===0||pop.type===1)&&hasEip1559){assertArgument(false,"pre-eip-1559 transaction do not support maxFeePerGas/maxPriorityFeePerGas","tx",tx)}if((pop.type===2||pop.type==null)&&(pop.maxFeePerGas!=null&&pop.maxPriorityFeePerGas!=null)){pop.type=2}else if(pop.type===0||pop.type===1){const feeData=await provider.getFeeData();assert$1(feeData.gasPrice!=null,"network does not support gasPrice","UNSUPPORTED_OPERATION",{operation:"getGasPrice"});if(pop.gasPrice==null){pop.gasPrice=feeData.gasPrice}}else{const feeData=await provider.getFeeData();if(pop.type==null){if(feeData.maxFeePerGas!=null&&feeData.maxPriorityFeePerGas!=null){pop.type=2;if(pop.gasPrice!=null){const gasPrice=pop.gasPrice;delete pop.gasPrice;pop.maxFeePerGas=gasPrice;pop.maxPriorityFeePerGas=gasPrice}else{if(pop.maxFeePerGas==null){pop.maxFeePerGas=feeData.maxFeePerGas}if(pop.maxPriorityFeePerGas==null){pop.maxPriorityFeePerGas=feeData.maxPriorityFeePerGas}}}else if(feeData.gasPrice!=null){assert$1(!hasEip1559,"network does not support EIP-1559","UNSUPPORTED_OPERATION",{operation:"populateTransaction"});if(pop.gasPrice==null){pop.gasPrice=feeData.gasPrice}pop.type=0}else{assert$1(false,"failed to get consistent fee data","UNSUPPORTED_OPERATION",{operation:"signer.getFeeData"})}}else if(pop.type===2){if(pop.maxFeePerGas==null){pop.maxFeePerGas=feeData.maxFeePerGas}if(pop.maxPriorityFeePerGas==null){pop.maxPriorityFeePerGas=feeData.maxPriorityFeePerGas}}}return await resolveProperties(pop)}async estimateGas(tx){return checkProvider(this,"estimateGas").estimateGas(await this.populateCall(tx))}async call(tx){return checkProvider(this,"call").call(await this.populateCall(tx))}async resolveName(name){const provider=checkProvider(this,"resolveName");return await provider.resolveName(name)}async sendTransaction(tx){const provider=checkProvider(this,"sendTransaction");const pop=await this.populateTransaction(tx);delete pop.from;const txObj=Transaction.from(pop);return await provider.broadcastTransaction(await this.signTransaction(txObj))}}class VoidSigner extends AbstractSigner{address;constructor(address,provider){super(provider);defineProperties(this,{address:address})}async getAddress(){return this.address}connect(provider){return new VoidSigner(this.address,provider)}#throwUnsupported(suffix,operation){assert$1(false,`VoidSigner cannot sign ${suffix}`,"UNSUPPORTED_OPERATION",{operation:operation})}async signTransaction(tx){this.#throwUnsupported("transactions","signTransaction")}async signMessage(message){this.#throwUnsupported("messages","signMessage")}async signTypedData(domain,types,value){this.#throwUnsupported("typed-data","signTypedData")}}const shown=new Set;function showThrottleMessage(service){if(shown.has(service)){return}shown.add(service);console.log("========= NOTICE =========");console.log(`Request-Rate Exceeded for ${service} (this message will not be repeated)`);console.log("");console.log("The default API keys for each service are provided as a highly-throttled,");console.log("community resource for low-traffic projects and early prototyping.");console.log("");console.log("While your application will continue to function, we highly recommended");console.log("signing up for your own API keys to improve performance, increase your");console.log("request rate/limit and enable other perks, such as metrics and advanced APIs.");console.log("");console.log("For more details: https://docs.ethers.org/api-keys/");console.log("==========================")}function copy(obj){return JSON.parse(JSON.stringify(obj))}class FilterIdSubscriber{#provider;#filterIdPromise;#poller;#running;#network;#hault;constructor(provider){this.#provider=provider;this.#filterIdPromise=null;this.#poller=this.#poll.bind(this);this.#running=false;this.#network=null;this.#hault=false}_subscribe(provider){throw new Error("subclasses must override this")}_emitResults(provider,result){throw new Error("subclasses must override this")}_recover(provider){throw new Error("subclasses must override this")}async#poll(blockNumber){try{if(this.#filterIdPromise==null){this.#filterIdPromise=this._subscribe(this.#provider)}let filterId=null;try{filterId=await this.#filterIdPromise}catch(error){if(!isError(error,"UNSUPPORTED_OPERATION")||error.operation!=="eth_newFilter"){throw error}}if(filterId==null){this.#filterIdPromise=null;this.#provider._recoverSubscriber(this,this._recover(this.#provider));return}const network=await this.#provider.getNetwork();if(!this.#network){this.#network=network}if(this.#network.chainId!==network.chainId){throw new Error("chaid changed")}if(this.#hault){return}const result=await this.#provider.send("eth_getFilterChanges",[filterId]);await this._emitResults(this.#provider,result)}catch(error){console.log("@TODO",error)}this.#provider.once("block",this.#poller)}#teardown(){const filterIdPromise=this.#filterIdPromise;if(filterIdPromise){this.#filterIdPromise=null;filterIdPromise.then(filterId=>{this.#provider.send("eth_uninstallFilter",[filterId])})}}start(){if(this.#running){return}this.#running=true;this.#poll(-2)}stop(){if(!this.#running){return}this.#running=false;this.#hault=true;this.#teardown();this.#provider.off("block",this.#poller)}pause(dropWhilePaused){if(dropWhilePaused){this.#teardown()}this.#provider.off("block",this.#poller)}resume(){this.start()}}class FilterIdEventSubscriber extends FilterIdSubscriber{#event;constructor(provider,filter){super(provider);this.#event=copy(filter)}_recover(provider){return new PollingEventSubscriber(provider,this.#event)}async _subscribe(provider){const filterId=await provider.send("eth_newFilter",[this.#event]);return filterId}async _emitResults(provider,results){for(const result of results){provider.emit(this.#event,provider._wrapLog(result,provider._network))}}}class FilterIdPendingSubscriber extends FilterIdSubscriber{async _subscribe(provider){return await provider.send("eth_newPendingTransactionFilter",[])}async _emitResults(provider,results){for(const result of results){provider.emit("pending",result)}}}const Primitive="bigint,boolean,function,number,string,symbol".split(/,/g);function deepCopy(value){if(value==null||Primitive.indexOf(typeof value)>=0){return value}if(typeof value.getAddress==="function"){return value}if(Array.isArray(value)){return value.map(deepCopy)}if(typeof value==="object"){return Object.keys(value).reduce((accum,key)=>{accum[key]=value[key];return accum},{})}throw new Error(`should not happen: ${value} (${typeof value})`)}function stall$3(duration){return new Promise(resolve=>{setTimeout(resolve,duration)})}function getLowerCase(value){if(value){return value.toLowerCase()}return value}function isPollable(value){return value&&typeof value.pollingInterval==="number"}const defaultOptions={polling:false,staticNetwork:null,batchStallTime:10,batchMaxSize:1<<20,batchMaxCount:100};class JsonRpcSigner extends AbstractSigner{address;constructor(provider,address){super(provider);address=getAddress(address);defineProperties(this,{address:address})}connect(provider){assert$1(false,"cannot reconnect JsonRpcSigner","UNSUPPORTED_OPERATION",{operation:"signer.connect"})}async getAddress(){return this.address}async populateTransaction(tx){return await this.populateCall(tx)}async sendUncheckedTransaction(_tx){const tx=deepCopy(_tx);const promises=[];if(tx.from){const _from=tx.from;promises.push((async()=>{const from=await resolveAddress(_from,this.provider);assertArgument(from!=null&&from.toLowerCase()===this.address.toLowerCase(),"from address mismatch","transaction",_tx);tx.from=from})())}else{tx.from=this.address}if(tx.gasLimit==null){promises.push((async()=>{tx.gasLimit=await this.provider.estimateGas({...tx,from:this.address})})())}if(tx.to!=null){const _to=tx.to;promises.push((async()=>{tx.to=await resolveAddress(_to,this.provider)})())}if(promises.length){await Promise.all(promises)}const hexTx=this.provider.getRpcTransaction(tx);return this.provider.send("eth_sendTransaction",[hexTx])}async sendTransaction(tx){const blockNumber=await this.provider.getBlockNumber();const hash=await this.sendUncheckedTransaction(tx);return await new Promise((resolve,reject)=>{const timeouts=[1e3,100];const checkTx=async()=>{const tx=await this.provider.getTransaction(hash);if(tx!=null){resolve(tx.replaceableTransaction(blockNumber));return}this.provider._setTimeout(()=>{checkTx()},timeouts.pop()||4e3)};checkTx()})}async signTransaction(_tx){const tx=deepCopy(_tx);if(tx.from){const from=await resolveAddress(tx.from,this.provider);assertArgument(from!=null&&from.toLowerCase()===this.address.toLowerCase(),"from address mismatch","transaction",_tx);tx.from=from}else{tx.from=this.address}const hexTx=this.provider.getRpcTransaction(tx);return await this.provider.send("eth_signTransaction",[hexTx])}async signMessage(_message){const message=typeof _message==="string"?toUtf8Bytes(_message):_message;return await this.provider.send("personal_sign",[hexlify(message),this.address.toLowerCase()])}async signTypedData(domain,types,_value){const value=deepCopy(_value);const populated=await TypedDataEncoder.resolveNames(domain,types,value,async value=>{const address=await resolveAddress(value);assertArgument(address!=null,"TypedData does not support null address","value",value);return address});return await this.provider.send("eth_signTypedData_v4",[this.address.toLowerCase(),JSON.stringify(TypedDataEncoder.getPayload(populated.domain,types,populated.value))])}async unlock(password){return this.provider.send("personal_unlockAccount",[this.address.toLowerCase(),password,null])}async _legacySignMessage(_message){const message=typeof _message==="string"?toUtf8Bytes(_message):_message;return await this.provider.send("eth_sign",[this.address.toLowerCase(),hexlify(message)])}}class JsonRpcApiProvider extends AbstractProvider{#options;#nextId;#payloads;#drainTimer;#notReady;#network;#scheduleDrain(){if(this.#drainTimer){return}const stallTime=this._getOption("batchMaxCount")===1?0:this._getOption("batchStallTime");this.#drainTimer=setTimeout(()=>{this.#drainTimer=null;const payloads=this.#payloads;this.#payloads=[];while(payloads.length){const batch=[payloads.shift()];while(payloads.length){if(batch.length===this.#options.batchMaxCount){break}batch.push(payloads.shift());const bytes=JSON.stringify(batch.map(p=>p.payload));if(bytes.length>this.#options.batchMaxSize){payloads.unshift(batch.pop());break}}(async()=>{const payload=batch.length===1?batch[0].payload:batch.map(p=>p.payload);this.emit("debug",{action:"sendRpcPayload",payload:payload});try{const result=await this._send(payload);this.emit("debug",{action:"receiveRpcResult",result:result});for(const{resolve,reject,payload}of batch){const resp=result.filter(r=>r.id===payload.id)[0];if(resp==null){return reject(makeError("no response from server","BAD_DATA",{value:result,info:{payload:payload}}))}if("error"in resp){return reject(this.getRpcError(payload,resp))}resolve(resp.result)}}catch(error){this.emit("debug",{action:"receiveRpcError",error:error});for(const{reject}of batch){reject(error)}}})()}},stallTime)}constructor(network,options){super(network);this.#nextId=1;this.#options=Object.assign({},defaultOptions,options||{});this.#payloads=[];this.#drainTimer=null;this.#network=null;{let resolve=null;const promise=new Promise(_resolve=>{resolve=_resolve});this.#notReady={promise:promise,resolve:resolve}}const staticNetwork=this._getOption("staticNetwork");if(staticNetwork){assertArgument(staticNetwork===network,"staticNetwork MUST match network object","options",options);this.#network=staticNetwork}}_getOption(key){return this.#options[key]}get _network(){assert$1(this.#network,"network is not available yet","NETWORK_ERROR");return this.#network}async _perform(req){if(req.method==="call"||req.method==="estimateGas"){let tx=req.transaction;if(tx&&tx.type!=null&&getBigInt(tx.type)){if(tx.maxFeePerGas==null&&tx.maxPriorityFeePerGas==null){const feeData=await this.getFeeData();if(feeData.maxFeePerGas==null&&feeData.maxPriorityFeePerGas==null){req=Object.assign({},req,{transaction:Object.assign({},tx,{type:undefined})})}}}}const request=this.getRpcRequest(req);if(request!=null){return await this.send(request.method,request.args)}return super._perform(req)}async _detectNetwork(){const network=this._getOption("staticNetwork");if(network){return network}if(this.ready){return Network.from(getBigInt(await this.send("eth_chainId",[])))}const payload={id:this.#nextId++,method:"eth_chainId",params:[],jsonrpc:"2.0"};this.emit("debug",{action:"sendRpcPayload",payload:payload});let result;try{result=(await this._send(payload))[0]}catch(error){this.emit("debug",{action:"receiveRpcError",error:error});throw error}this.emit("debug",{action:"receiveRpcResult",result:result});if("result"in result){return Network.from(getBigInt(result.result))}throw this.getRpcError(payload,result)}_start(){if(this.#notReady==null||this.#notReady.resolve==null){return}this.#notReady.resolve();this.#notReady=null;(async()=>{while(this.#network==null){try{this.#network=await this._detectNetwork()}catch(error){console.log("JsonRpcProvider failed to startup; retry in 1s");await stall$3(1e3)}}this.#scheduleDrain()})()}async _waitUntilReady(){if(this.#notReady==null){return}return await this.#notReady.promise}_getSubscriber(sub){if(sub.type==="pending"){return new FilterIdPendingSubscriber(this)}if(sub.type==="event"){if(this._getOption("polling")){return new PollingEventSubscriber(this,sub.filter)}return new FilterIdEventSubscriber(this,sub.filter)}if(sub.type==="orphan"&&sub.filter.orphan==="drop-log"){return new UnmanagedSubscriber("orphan")}return super._getSubscriber(sub)}get ready(){return this.#notReady==null}getRpcTransaction(tx){const result={};["chainId","gasLimit","gasPrice","type","maxFeePerGas","maxPriorityFeePerGas","nonce","value"].forEach(key=>{if(tx[key]==null){return}let dstKey=key;if(key==="gasLimit"){dstKey="gas"}result[dstKey]=toQuantity(getBigInt(tx[key],`tx.${key}`))});["from","to","data"].forEach(key=>{if(tx[key]==null){return}result[key]=hexlify(tx[key])});if(tx.accessList){result["accessList"]=accessListify(tx.accessList)}return result}getRpcRequest(req){switch(req.method){case"chainId":return{method:"eth_chainId",args:[]};case"getBlockNumber":return{method:"eth_blockNumber",args:[]};case"getGasPrice":return{method:"eth_gasPrice",args:[]};case"getBalance":return{method:"eth_getBalance",args:[getLowerCase(req.address),req.blockTag]};case"getTransactionCount":return{method:"eth_getTransactionCount",args:[getLowerCase(req.address),req.blockTag]};case"getCode":return{method:"eth_getCode",args:[getLowerCase(req.address),req.blockTag]};case"getStorage":return{method:"eth_getStorageAt",args:[getLowerCase(req.address),"0x"+req.position.toString(16),req.blockTag]};case"broadcastTransaction":return{method:"eth_sendRawTransaction",args:[req.signedTransaction]};case"getBlock":if("blockTag"in req){return{method:"eth_getBlockByNumber",args:[req.blockTag,!!req.includeTransactions]}}else if("blockHash"in req){return{method:"eth_getBlockByHash",args:[req.blockHash,!!req.includeTransactions]}}break;case"getTransaction":return{method:"eth_getTransactionByHash",args:[req.hash]};case"getTransactionReceipt":return{method:"eth_getTransactionReceipt",args:[req.hash]};case"call":return{method:"eth_call",args:[this.getRpcTransaction(req.transaction),req.blockTag]};case"estimateGas":{return{method:"eth_estimateGas",args:[this.getRpcTransaction(req.transaction)]}}case"getLogs":if(req.filter&&req.filter.address!=null){if(Array.isArray(req.filter.address)){req.filter.address=req.filter.address.map(getLowerCase)}else{req.filter.address=getLowerCase(req.filter.address)}}return{method:"eth_getLogs",args:[req.filter]}}return null}getRpcError(payload,_error){const{method}=payload;const{error}=_error;if(method==="eth_estimateGas"&&error.message){const msg=error.message;if(!msg.match(/revert/i)&&msg.match(/insufficient funds/i)){return makeError("insufficient funds","INSUFFICIENT_FUNDS",{transaction:payload.params[0],info:{payload:payload,error:error}})}}if(method==="eth_call"||method==="eth_estimateGas"){const result=spelunkData(error);const e=AbiCoder.getBuiltinCallException(method==="eth_call"?"call":"estimateGas",payload.params[0],result?result.data:null);e.info={error:error,payload:payload};return e}const message=JSON.stringify(spelunkMessage(error));if(typeof error.message==="string"&&error.message.match(/user denied|ethers-user-denied/i)){const actionMap={eth_sign:"signMessage",personal_sign:"signMessage",eth_signTypedData_v4:"signTypedData",eth_signTransaction:"signTransaction",eth_sendTransaction:"sendTransaction",eth_requestAccounts:"requestAccess",wallet_requestAccounts:"requestAccess"};return makeError(`user rejected action`,"ACTION_REJECTED",{action:actionMap[method]||"unknown",reason:"rejected",info:{payload:payload,error:error}})}if(method==="eth_sendRawTransaction"||method==="eth_sendTransaction"){const transaction=payload.params[0];if(message.match(/insufficient funds|base fee exceeds gas limit/i)){return makeError("insufficient funds for intrinsic transaction cost","INSUFFICIENT_FUNDS",{transaction:transaction,info:{error:error}})}if(message.match(/nonce/i)&&message.match(/too low/i)){return makeError("nonce has already been used","NONCE_EXPIRED",{transaction:transaction,info:{error:error}})}if(message.match(/replacement transaction/i)&&message.match(/underpriced/i)){return makeError("replacement fee too low","REPLACEMENT_UNDERPRICED",{transaction:transaction,info:{error:error}})}if(message.match(/only replay-protected/i)){return makeError("legacy pre-eip-155 transactions not supported","UNSUPPORTED_OPERATION",{operation:method,info:{transaction:transaction,info:{error:error}}})}}if(message.match(/the method .* does not exist/i)){return makeError("unsupported operation","UNSUPPORTED_OPERATION",{operation:payload.method,info:{error:error}})}return makeError("could not coalesce error","UNKNOWN_ERROR",{error:error})}send(method,params){const id=this.#nextId++;const promise=new Promise((resolve,reject)=>{this.#payloads.push({resolve:resolve,reject:reject,payload:{method:method,params:params,id:id,jsonrpc:"2.0"}})});this.#scheduleDrain();return promise}async getSigner(address){if(address==null){address=0}const accountsPromise=this.send("eth_accounts",[]);if(typeof address==="number"){const accounts=await accountsPromise;if(address>=accounts.length){throw new Error("no such account")}return new JsonRpcSigner(this,accounts[address])}const{accounts}=await resolveProperties({network:this.getNetwork(),accounts:accountsPromise});address=getAddress(address);for(const account of accounts){if(getAddress(account)===address){return new JsonRpcSigner(this,address)}}throw new Error("invalid account")}async listAccounts(){const accounts=await this.send("eth_accounts",[]);return accounts.map(a=>new JsonRpcSigner(this,a))}}class JsonRpcApiPollingProvider extends JsonRpcApiProvider{#pollingInterval;constructor(network,options){super(network,options);this.#pollingInterval=4e3}_getSubscriber(sub){const subscriber=super._getSubscriber(sub);if(isPollable(subscriber)){subscriber.pollingInterval=this.#pollingInterval}return subscriber}get pollingInterval(){return this.#pollingInterval}set pollingInterval(value){if(!Number.isInteger(value)||value<0){throw new Error("invalid interval")}this.#pollingInterval=value;this._forEachSubscriber(sub=>{if(isPollable(sub)){sub.pollingInterval=this.#pollingInterval}})}}class JsonRpcProvider extends JsonRpcApiPollingProvider{#connect;constructor(url,network,options){if(url==null){url="http://localhost:8545"}super(network,options);if(typeof url==="string"){this.#connect=new FetchRequest(url)}else{this.#connect=url.clone()}}_getConnection(){return this.#connect.clone()}async send(method,params){await this._start();return await super.send(method,params)}async _send(payload){const request=this._getConnection();request.body=JSON.stringify(payload);request.setHeader("content-type","application/json");const response=await request.send();response.assertOk();let resp=response.bodyJson;if(!Array.isArray(resp)){resp=[resp]}return resp}}function spelunkData(value){if(value==null){return null}if(typeof value.message==="string"&&value.message.match("reverted")&&isHexString(value.data)){return{message:value.message,data:value.data}}if(typeof value==="object"){for(const key in value){const result=spelunkData(value[key]);if(result){return result}}return null}if(typeof value==="string"){try{return spelunkData(JSON.parse(value))}catch(error){}}return null}function _spelunkMessage(value,result){if(value==null){return}if(typeof value.message==="string"){result.push(value.message)}if(typeof value==="object"){for(const key in value){_spelunkMessage(value[key],result)}}if(typeof value==="string"){try{return _spelunkMessage(JSON.parse(value),result)}catch(error){}}}function spelunkMessage(value){const result=[];_spelunkMessage(value,result);return result}const defaultApiKey$1="9f7d929b018cdffb338517efa06f58359e86ff1ffd350bc889738523659e7972";function getHost$4(name){switch(name){case"mainnet":return"rpc.ankr.com/eth";case"goerli":return"rpc.ankr.com/eth_goerli";case"matic":return"rpc.ankr.com/polygon";case"arbitrum":return"rpc.ankr.com/arbitrum"}assertArgument(false,"unsupported network","network",name)}class AnkrProvider extends JsonRpcProvider{apiKey;constructor(_network,apiKey){if(_network==null){_network="mainnet"}const network=Network.from(_network);if(apiKey==null){apiKey=defaultApiKey$1}const options={polling:true,staticNetwork:network};const request=AnkrProvider.getRequest(network,apiKey);super(request,network,options);defineProperties(this,{apiKey:apiKey})}_getProvider(chainId){try{return new AnkrProvider(chainId,this.apiKey)}catch(error){}return super._getProvider(chainId)}static getRequest(network,apiKey){if(apiKey==null){apiKey=defaultApiKey$1}const request=new FetchRequest(`https:/\/${getHost$4(network.name)}/${apiKey}`);request.allowGzip=true;if(apiKey===defaultApiKey$1){request.retryFunc=async(request,response,attempt)=>{showThrottleMessage("AnkrProvider");return true}}return request}getRpcError(payload,error){if(payload.method==="eth_sendRawTransaction"){if(error&&error.error&&error.error.message==="INTERNAL_ERROR: could not replace existing tx"){error.error.message="replacement transaction underpriced"}}return super.getRpcError(payload,error)}isCommunityResource(){return this.apiKey===defaultApiKey$1}}const defaultApiKey="_gg7wSSi0KMBsdKnGVfHDueq6xMB9EkC";function getHost$3(name){switch(name){case"mainnet":return"eth-mainnet.alchemyapi.io";case"goerli":return"eth-goerli.g.alchemy.com";case"sepolia":return"eth-sepolia.g.alchemy.com";case"arbitrum":return"arb-mainnet.g.alchemy.com";case"arbitrum-goerli":return"arb-goerli.g.alchemy.com";case"matic":return"polygon-mainnet.g.alchemy.com";case"matic-mumbai":return"polygon-mumbai.g.alchemy.com";case"optimism":return"opt-mainnet.g.alchemy.com";case"optimism-goerli":return"opt-goerli.g.alchemy.com"}assertArgument(false,"unsupported network","network",name)}class AlchemyProvider extends JsonRpcProvider{apiKey;constructor(_network,apiKey){if(_network==null){_network="mainnet"}const network=Network.from(_network);if(apiKey==null){apiKey=defaultApiKey}const request=AlchemyProvider.getRequest(network,apiKey);super(request,network,{staticNetwork:network});defineProperties(this,{apiKey:apiKey})}_getProvider(chainId){try{return new AlchemyProvider(chainId,this.apiKey)}catch(error){}return super._getProvider(chainId)}async _perform(req){if(req.method==="getTransactionResult"){const{trace,tx}=await resolveProperties({trace:this.send("trace_transaction",[req.hash]),tx:this.getTransaction(req.hash)});if(trace==null||tx==null){return null}let data;let error=false;try{data=trace[0].result.output;error=trace[0].error==="Reverted"}catch(error){}if(data){assert$1(!error,"an error occurred during transaction executions","CALL_EXCEPTION",{action:"getTransactionResult",data:data,reason:null,transaction:tx,invocation:null,revert:null});return data}assert$1(false,"could not parse trace result","BAD_DATA",{value:trace})}return await super._perform(req)}isCommunityResource(){return this.apiKey===defaultApiKey}static getRequest(network,apiKey){if(apiKey==null){apiKey=defaultApiKey}const request=new FetchRequest(`https:/\/${getHost$3(network.name)}/v2/${apiKey}`);request.allowGzip=true;if(apiKey===defaultApiKey){request.retryFunc=async(request,response,attempt)=>{showThrottleMessage("alchemy");return true}}return request}}class CloudflareProvider extends JsonRpcProvider{constructor(_network){if(_network==null){_network="mainnet"}const network=Network.from(_network);assertArgument(network.name==="mainnet","unsupported network","network",_network);super("https://cloudflare-eth.com/",network,{staticNetwork:network})}}const THROTTLE=2e3;function isPromise(value){return value&&typeof value.then==="function"}const EtherscanPluginId="org.ethers.plugins.provider.Etherscan";class EtherscanPlugin extends NetworkPlugin{baseUrl;constructor(baseUrl){super(EtherscanPluginId);defineProperties(this,{baseUrl:baseUrl})}clone(){return new EtherscanPlugin(this.baseUrl)}}let nextId=1;class EtherscanProvider extends AbstractProvider{network;apiKey;#plugin;constructor(_network,_apiKey){const apiKey=_apiKey!=null?_apiKey:null;super();const network=Network.from(_network);this.#plugin=network.getPlugin(EtherscanPluginId);defineProperties(this,{apiKey:apiKey,network:network});this.getBaseUrl()}getBaseUrl(){if(this.#plugin){return this.#plugin.baseUrl}switch(this.network.name){case"mainnet":return"https://api.etherscan.io";case"goerli":return"https://api-goerli.etherscan.io";case"sepolia":return"https://api-sepolia.etherscan.io";case"arbitrum":return"https://api.arbiscan.io";case"arbitrum-goerli":return"https://api-goerli.arbiscan.io";case"matic":return"https://api.polygonscan.com";case"matic-mumbai":return"https://api-testnet.polygonscan.com";case"optimism":return"https://api-optimistic.etherscan.io";case"optimism-goerli":return"https://api-goerli-optimistic.etherscan.io";default:}assertArgument(false,"unsupported network","network",this.network)}getUrl(module,params){const query=Object.keys(params).reduce((accum,key)=>{const value=params[key];if(value!=null){accum+=`&${key}=${value}`}return accum},"");const apiKey=this.apiKey?`&apikey=${this.apiKey}`:"";return`${this.getBaseUrl()}/api?module=${module}${query}${apiKey}`}getPostUrl(){return`${this.getBaseUrl()}/api`}getPostData(module,params){params.module=module;params.apikey=this.apiKey;return params}async detectNetwork(){return this.network}async fetch(module,params,post){const id=nextId++;const url=post?this.getPostUrl():this.getUrl(module,params);const payload=post?this.getPostData(module,params):null;this.emit("debug",{action:"sendRequest",id:id,url:url,payload:payload});const request=new FetchRequest(url);request.setThrottleParams({slotInterval:1e3});request.retryFunc=(req,resp,attempt)=>{if(this.isCommunityResource()){showThrottleMessage("Etherscan")}return Promise.resolve(true)};request.processFunc=async(request,response)=>{const result=response.hasBody()?JSON.parse(toUtf8String(response.body)):{};const throttle=(typeof result.result==="string"?result.result:"").toLowerCase().indexOf("rate limit")>=0;if(module==="proxy"){if(result&&result.status==0&&result.message=="NOTOK"&&throttle){this.emit("debug",{action:"receiveError",id:id,reason:"proxy-NOTOK",error:result});response.throwThrottleError(result.result,THROTTLE)}}else{if(throttle){this.emit("debug",{action:"receiveError",id:id,reason:"null result",error:result.result});response.throwThrottleError(result.result,THROTTLE)}}return response};if(payload){request.setHeader("content-type","application/x-www-form-urlencoded; charset=UTF-8");request.body=Object.keys(payload).map(k=>`${k}=${payload[k]}`).join("&")}const response=await request.send();try{response.assertOk()}catch(error){this.emit("debug",{action:"receiveError",id:id,error:error,reason:"assertOk"});assert$1(false,"response error","SERVER_ERROR",{request:request,response:response})}if(!response.hasBody()){this.emit("debug",{action:"receiveError",id:id,error:"missing body",reason:"null body"});assert$1(false,"missing response","SERVER_ERROR",{request:request,response:response})}const result=JSON.parse(toUtf8String(response.body));if(module==="proxy"){if(result.jsonrpc!="2.0"){this.emit("debug",{action:"receiveError",id:id,result:result,reason:"invalid JSON-RPC"});assert$1(false,"invalid JSON-RPC response (missing jsonrpc='2.0')","SERVER_ERROR",{request:request,response:response,info:{result:result}})}if(result.error){this.emit("debug",{action:"receiveError",id:id,result:result,reason:"JSON-RPC error"});assert$1(false,"error response","SERVER_ERROR",{request:request,response:response,info:{result:result}})}this.emit("debug",{action:"receiveRequest",id:id,result:result});return result.result}else{if(result.status==0&&(result.message==="No records found"||result.message==="No transactions found")){this.emit("debug",{action:"receiveRequest",id:id,result:result});return result.result}if(result.status!=1||typeof result.message==="string"&&!result.message.match(/^OK/)){this.emit("debug",{action:"receiveError",id:id,result:result});assert$1(false,"error response","SERVER_ERROR",{request:request,response:response,info:{result:result}})}this.emit("debug",{action:"receiveRequest",id:id,result:result});return result.result}}_getTransactionPostData(transaction){const result={};for(let key in transaction){if(transaction[key]==null){continue}let value=transaction[key];if(key==="type"&&value===0){continue}if({type:true,gasLimit:true,gasPrice:true,maxFeePerGs:true,maxPriorityFeePerGas:true,nonce:true,value:true}[key]){value=toQuantity(value)}else if(key==="accessList"){value="["+accessListify(value).map(set=>{return`{address:"${set.address}",storageKeys:["${set.storageKeys.join('","')}"]}`}).join(",")+"]"}else{value=hexlify(value)}result[key]=value}return result}_checkError(req,error,transaction){let message="";if(isError(error,"SERVER_ERROR")){try{message=error.info.result.error.message}catch(e){}if(!message){try{message=error.info.message}catch(e){}}}if(req.method==="estimateGas"){if(!message.match(/revert/i)&&message.match(/insufficient funds/i)){assert$1(false,"insufficient funds","INSUFFICIENT_FUNDS",{transaction:req.transaction})}}if(req.method==="call"||req.method==="estimateGas"){if(message.match(/execution reverted/i)){let data="";try{data=error.info.result.error.data}catch(error){}const e=AbiCoder.getBuiltinCallException(req.method,req.transaction,data);e.info={request:req,error:error};throw e}}if(message){if(req.method==="broadcastTransaction"){const transaction=Transaction.from(req.signedTransaction);if(message.match(/replacement/i)&&message.match(/underpriced/i)){assert$1(false,"replacement fee too low","REPLACEMENT_UNDERPRICED",{transaction:transaction})}if(message.match(/insufficient funds/)){assert$1(false,"insufficient funds for intrinsic transaction cost","INSUFFICIENT_FUNDS",{transaction:transaction})}if(message.match(/same hash was already imported|transaction nonce is too low|nonce too low/)){assert$1(false,"nonce has already been used","NONCE_EXPIRED",{transaction:transaction})}}}throw error}async _detectNetwork(){return this.network}async _perform(req){switch(req.method){case"chainId":return this.network.chainId;case"getBlockNumber":return this.fetch("proxy",{action:"eth_blockNumber"});case"getGasPrice":return this.fetch("proxy",{action:"eth_gasPrice"});case"getBalance":return this.fetch("account",{action:"balance",address:req.address,tag:req.blockTag});case"getTransactionCount":return this.fetch("proxy",{action:"eth_getTransactionCount",address:req.address,tag:req.blockTag});case"getCode":return this.fetch("proxy",{action:"eth_getCode",address:req.address,tag:req.blockTag});case"getStorage":return this.fetch("proxy",{action:"eth_getStorageAt",address:req.address,position:req.position,tag:req.blockTag});case"broadcastTransaction":return this.fetch("proxy",{action:"eth_sendRawTransaction",hex:req.signedTransaction},true).catch(error=>{return this._checkError(req,error,req.signedTransaction)});case"getBlock":if("blockTag"in req){return this.fetch("proxy",{action:"eth_getBlockByNumber",tag:req.blockTag,boolean:req.includeTransactions?"true":"false"})}assert$1(false,"getBlock by blockHash not supported by Etherscan","UNSUPPORTED_OPERATION",{operation:"getBlock(blockHash)"});case"getTransaction":return this.fetch("proxy",{action:"eth_getTransactionByHash",txhash:req.hash});case"getTransactionReceipt":return this.fetch("proxy",{action:"eth_getTransactionReceipt",txhash:req.hash});case"call":{if(req.blockTag!=="latest"){throw new Error("EtherscanProvider does not support blockTag for call")}const postData=this._getTransactionPostData(req.transaction);postData.module="proxy";postData.action="eth_call";try{return await this.fetch("proxy",postData,true)}catch(error){return this._checkError(req,error,req.transaction)}}case"estimateGas":{const postData=this._getTransactionPostData(req.transaction);postData.module="proxy";postData.action="eth_estimateGas";try{return await this.fetch("proxy",postData,true)}catch(error){return this._checkError(req,error,req.transaction)}}default:break}return super._perform(req)}async getNetwork(){return this.network}async getEtherPrice(){if(this.network.name!=="mainnet"){return 0}return parseFloat((await this.fetch("stats",{action:"ethprice"})).ethusd)}async getContract(_address){let address=this._getAddress(_address);if(isPromise(address)){address=await address}try{const resp=await this.fetch("contract",{action:"getabi",address:address});const abi=JSON.parse(resp);return new Contract(address,abi,this)}catch(error){return null}}isCommunityResource(){return this.apiKey==null}}function getGlobal(){if(typeof self!=="undefined"){return self}if(typeof window!=="undefined"){return window}if(typeof global!=="undefined"){return global}throw new Error("unable to locate global object")}const _WebSocket=getGlobal().WebSocket;class SocketSubscriber{#provider;#filter;get filter(){return JSON.parse(this.#filter)}#filterId;#paused;#emitPromise;constructor(provider,filter){this.#provider=provider;this.#filter=JSON.stringify(filter);this.#filterId=null;this.#paused=null;this.#emitPromise=null}start(){this.#filterId=this.#provider.send("eth_subscribe",this.filter).then(filterId=>{this.#provider._register(filterId,this);return filterId})}stop(){this.#filterId.then(filterId=>{this.#provider.send("eth_unsubscribe",[filterId])});this.#filterId=null}pause(dropWhilePaused){assert$1(dropWhilePaused,"preserve logs while paused not supported by SocketSubscriber yet","UNSUPPORTED_OPERATION",{operation:"pause(false)"});this.#paused=!!dropWhilePaused}resume(){this.#paused=null}_handleMessage(message){if(this.#filterId==null){return}if(this.#paused===null){let emitPromise=this.#emitPromise;if(emitPromise==null){emitPromise=this._emit(this.#provider,message)}else{emitPromise=emitPromise.then(async()=>{await this._emit(this.#provider,message)})}this.#emitPromise=emitPromise.then(()=>{if(this.#emitPromise===emitPromise){this.#emitPromise=null}})}}async _emit(provider,message){throw new Error("sub-classes must implemente this; _emit")}}class SocketBlockSubscriber extends SocketSubscriber{constructor(provider){super(provider,["newHeads"])}async _emit(provider,message){provider.emit("block",parseInt(message.number))}}class SocketPendingSubscriber extends SocketSubscriber{constructor(provider){super(provider,["newPendingTransactions"])}async _emit(provider,message){provider.emit("pending",message)}}class SocketEventSubscriber extends SocketSubscriber{#logFilter;get logFilter(){return JSON.parse(this.#logFilter)}constructor(provider,filter){super(provider,["logs",filter]);this.#logFilter=JSON.stringify(filter)}async _emit(provider,message){provider.emit(this.logFilter,provider._wrapLog(message,provider._network))}}class SocketProvider extends JsonRpcApiProvider{#callbacks;#subs;#pending;constructor(network){super(network,{batchMaxCount:1});this.#callbacks=new Map;this.#subs=new Map;this.#pending=new Map}_getSubscriber(sub){switch(sub.type){case"close":return new UnmanagedSubscriber("close");case"block":return new SocketBlockSubscriber(this);case"pending":return new SocketPendingSubscriber(this);case"event":return new SocketEventSubscriber(this,sub.filter);case"orphan":if(sub.filter.orphan==="drop-log"){return new UnmanagedSubscriber("drop-log")}}return super._getSubscriber(sub)}_register(filterId,subscriber){this.#subs.set(filterId,subscriber);const pending=this.#pending.get(filterId);if(pending){for(const message of pending){subscriber._handleMessage(message)}this.#pending.delete(filterId)}}async _send(payload){assertArgument(!Array.isArray(payload),"WebSocket does not support batch send","payload",payload);const promise=new Promise((resolve,reject)=>{this.#callbacks.set(payload.id,{payload:payload,resolve:resolve,reject:reject})});await this._waitUntilReady();await this._write(JSON.stringify(payload));return[await promise]}async _processMessage(message){const result=JSON.parse(message);if("id"in result){const callback=this.#callbacks.get(result.id);if(callback==null){console.log("Weird... Response for not a thing we sent");return}this.#callbacks.delete(result.id);callback.resolve(result)}else if(result.method==="eth_subscription"){const filterId=result.params.subscription;const subscriber=this.#subs.get(filterId);if(subscriber){subscriber._handleMessage(result.params.result)}else{let pending=this.#pending.get(filterId);if(pending==null){pending=[];this.#pending.set(filterId,pending)}pending.push(result.params.result)}}}async _write(message){throw new Error("sub-classes must override this")}}class WebSocketProvider extends SocketProvider{#connect;#websocket;get websocket(){if(this.#websocket==null){throw new Error("websocket closed")}return this.#websocket}constructor(url,network){super(network);if(typeof url==="string"){this.#connect=()=>{return new _WebSocket(url)};this.#websocket=this.#connect()}else if(typeof url==="function"){this.#connect=url;this.#websocket=url()}else{this.#connect=null;this.#websocket=url}this.websocket.onopen=async()=>{try{await this._start();this.resume()}catch(error){console.log("failed to start WebsocketProvider",error)}};this.websocket.onmessage=message=>{this._processMessage(message.data)}}async _write(message){this.websocket.send(message)}async destroy(){if(this.#websocket!=null){this.#websocket.close();this.#websocket=null}super.destroy()}}const defaultProjectId="84842078b09946638c03157f83405213";function getHost$2(name){switch(name){case"mainnet":return"mainnet.infura.io";case"goerli":return"goerli.infura.io";case"sepolia":return"sepolia.infura.io";case"arbitrum":return"arbitrum-mainnet.infura.io";case"arbitrum-goerli":return"arbitrum-goerli.infura.io";case"matic":return"polygon-mainnet.infura.io";case"matic-mumbai":return"polygon-mumbai.infura.io";case"optimism":return"optimism-mainnet.infura.io";case"optimism-goerli":return"optimism-goerli.infura.io"}assertArgument(false,"unsupported network","network",name)}class InfuraWebSocketProvider extends WebSocketProvider{projectId;projectSecret;constructor(network,projectId){const provider=new InfuraProvider(network,projectId);const req=provider._getConnection();assert$1(!req.credentials,"INFURA WebSocket project secrets unsupported","UNSUPPORTED_OPERATION",{operation:"InfuraProvider.getWebSocketProvider()"});const url=req.url.replace(/^http/i,"ws").replace("/v3/","/ws/v3/");super(url,network);defineProperties(this,{projectId:provider.projectId,projectSecret:provider.projectSecret})}isCommunityResource(){return this.projectId===defaultProjectId}}class InfuraProvider extends JsonRpcProvider{projectId;projectSecret;constructor(_network,projectId,projectSecret){if(_network==null){_network="mainnet"}const network=Network.from(_network);if(projectId==null){projectId=defaultProjectId}if(projectSecret==null){projectSecret=null}const request=InfuraProvider.getRequest(network,projectId,projectSecret);super(request,network,{staticNetwork:network});defineProperties(this,{projectId:projectId,projectSecret:projectSecret})}_getProvider(chainId){try{return new InfuraProvider(chainId,this.projectId,this.projectSecret)}catch(error){}return super._getProvider(chainId)}isCommunityResource(){return this.projectId===defaultProjectId}static getWebSocketProvider(network,projectId){return new InfuraWebSocketProvider(network,projectId)}static getRequest(network,projectId,projectSecret){if(projectId==null){projectId=defaultProjectId}if(projectSecret==null){projectSecret=null}const request=new FetchRequest(`https:/\/${getHost$2(network.name)}/v3/${projectId}`);request.allowGzip=true;if(projectSecret){request.setCredentials("",projectSecret)}if(projectId===defaultProjectId){request.retryFunc=async(request,response,attempt)=>{showThrottleMessage("InfuraProvider");return true}}return request}}const defaultToken="919b412a057b5e9c9b6dce193c5a60242d6efadb";function getHost$1(name){switch(name){case"mainnet":return"ethers.quiknode.pro";case"goerli":return"ethers.ethereum-goerli.quiknode.pro";case"arbitrum":return"ethers.arbitrum-mainnet.quiknode.pro";case"arbitrum-goerli":return"ethers.arbitrum-goerli.quiknode.pro";case"matic":return"ethers.matic.quiknode.pro";case"matic-mumbai":return"ethers.matic-testnet.quiknode.pro";case"optimism":return"ethers.optimism.quiknode.pro";case"optimism-goerli":return"ethers.optimism-goerli.quiknode.pro"}assertArgument(false,"unsupported network","network",name)}class QuickNodeProvider extends JsonRpcProvider{token;constructor(_network,token){if(_network==null){_network="mainnet"}const network=Network.from(_network);if(token==null){token=defaultToken}const request=QuickNodeProvider.getRequest(network,token);super(request,network,{staticNetwork:network});defineProperties(this,{token:token})}_getProvider(chainId){try{return new QuickNodeProvider(chainId,this.token)}catch(error){}return super._getProvider(chainId)}isCommunityResource(){return this.token===defaultToken}static getRequest(network,token){if(token==null){token=defaultToken}const request=new FetchRequest(`https:/\/${getHost$1(network.name)}/${token}`);request.allowGzip=true;if(token===defaultToken){request.retryFunc=async(request,response,attempt)=>{showThrottleMessage("QuickNodeProvider");return true}}return request}}const BN_1=BigInt("1");const BN_2=BigInt("2");function shuffle(array){for(let i=array.length-1;i>0;i--){const j=Math.floor(Math.random()*(i+1));const tmp=array[i];array[i]=array[j];array[j]=tmp}}function stall$2(duration){return new Promise(resolve=>{setTimeout(resolve,duration)})}function getTime(){return(new Date).getTime()}function stringify(value){return JSON.stringify(value,(key,value)=>{if(typeof value==="bigint"){return{type:"bigint",value:value.toString()}}return value})}const defaultConfig={stallTimeout:400,priority:1,weight:1};const defaultState={blockNumber:-2,requests:0,lateResponses:0,errorResponses:0,outOfSync:-1,unsupportedEvents:0,rollingDuration:0,score:0,_network:null,_updateNumber:null,_totalTime:0};async function waitForSync(config,blockNumber){while(config.blockNumber<0||config.blockNumber{const blockNumber=await config.provider.getBlockNumber();if(blockNumber>config.blockNumber){config.blockNumber=blockNumber}config._updateNumber=null})()}await config._updateNumber;config.outOfSync++}}function _normalize(value){if(value==null){return"null"}if(Array.isArray(value)){return"["+value.map(_normalize).join(",")+"]"}if(typeof value==="object"&&typeof value.toJSON==="function"){return _normalize(value.toJSON())}switch(typeof value){case"boolean":case"symbol":return value.toString();case"bigint":case"number":return BigInt(value).toString();case"string":return JSON.stringify(value);case"object":{const keys=Object.keys(value);keys.sort();return"{"+keys.map(k=>`${JSON.stringify(k)}:${_normalize(value[k])}`).join(",")+"}"}}console.log("Could not serialize",value);throw new Error("Hmm...")}function normalizeResult(value){if("error"in value){const error=value.error;return{tag:_normalize(error),value:error}}const result=value.result;return{tag:_normalize(result),value:result}}function checkQuorum(quorum,results){const tally=new Map;for(const{value,tag,weight}of results){const t=tally.get(tag)||{value:value,weight:0};t.weight+=weight;tally.set(tag,t)}let best=null;for(const r of tally.values()){if(r.weight>=quorum&&(!best||r.weight>best.weight)){best=r}}if(best){return best.value}return undefined}function getMedian(quorum,results){let resultWeight=0;const errorMap=new Map;let bestError=null;const values=[];for(const{value,tag,weight}of results){if(value instanceof Error){const e=errorMap.get(tag)||{value:value,weight:0};e.weight+=weight;errorMap.set(tag,e);if(bestError==null||e.weight>bestError.weight){bestError=e}}else{values.push(BigInt(value));resultWeight+=weight}}if(resultWeight=quorum){return bestError.value}return undefined}values.sort((a,b)=>aa?1:0);const mid=Math.floor(values.length/2);if(values.length%2){return values[mid]}return(values[mid-1]+values[mid]+BN_1)/BN_2}function getAnyResult(quorum,results){const result=checkQuorum(quorum,results);if(result!==undefined){return result}for(const r of results){if(r.value){return r.value}}return undefined}function getFuzzyMode(quorum,results){if(quorum===1){return getNumber(getMedian(quorum,results),"%internal")}const tally=new Map;const add=(result,weight)=>{const t=tally.get(result)||{result:result,weight:0};t.weight+=weight;tally.set(result,t)};for(const{weight,value}of results){const r=getNumber(value);add(r-1,weight);add(r,weight);add(r+1,weight)}let bestWeight=0;let bestResult=undefined;for(const{weight,result}of tally.values()){if(weight>=quorum&&(weight>bestWeight||bestResult!=null&&weight===bestWeight&&result>bestResult)){bestWeight=weight;bestResult=result}}return bestResult}class FallbackProvider extends AbstractProvider{quorum;eventQuorum;eventWorkers;#configs;#height;#initialSyncPromise;constructor(providers,network){super(network);this.#configs=providers.map(p=>{if(p instanceof AbstractProvider){return Object.assign({provider:p},defaultConfig,defaultState)}else{return Object.assign({},defaultConfig,p,defaultState)}});this.#height=-2;this.#initialSyncPromise=null;this.quorum=2;this.eventQuorum=1;this.eventWorkers=1;assertArgument(this.quorum<=this.#configs.reduce((a,c)=>a+c.weight,0),"quorum exceed provider wieght","quorum",this.quorum)}get providerConfigs(){return this.#configs.map(c=>{const result=Object.assign({},c);for(const key in result){if(key[0]==="_"){delete result[key]}}return result})}async _detectNetwork(){return Network.from(getBigInt(await this._perform({method:"chainId"})))}async _translatePerform(provider,req){switch(req.method){case"broadcastTransaction":return await provider.broadcastTransaction(req.signedTransaction);case"call":return await provider.call(Object.assign({},req.transaction,{blockTag:req.blockTag}));case"chainId":return(await provider.getNetwork()).chainId;case"estimateGas":return await provider.estimateGas(req.transaction);case"getBalance":return await provider.getBalance(req.address,req.blockTag);case"getBlock":{const block="blockHash"in req?req.blockHash:req.blockTag;return await provider.getBlock(block,req.includeTransactions)}case"getBlockNumber":return await provider.getBlockNumber();case"getCode":return await provider.getCode(req.address,req.blockTag);case"getGasPrice":return(await provider.getFeeData()).gasPrice;case"getLogs":return await provider.getLogs(req.filter);case"getStorage":return await provider.getStorage(req.address,req.position,req.blockTag);case"getTransaction":return await provider.getTransaction(req.hash);case"getTransactionCount":return await provider.getTransactionCount(req.address,req.blockTag);case"getTransactionReceipt":return await provider.getTransactionReceipt(req.hash);case"getTransactionResult":return await provider.getTransactionResult(req.hash)}}#getNextConfig(running){const configs=Array.from(running).map(r=>r.config);const allConfigs=this.#configs.slice();shuffle(allConfigs);allConfigs.sort((a,b)=>b.priority-a.priority);for(const config of allConfigs){if(configs.indexOf(config)===-1){return config}}return null}#addRunner(running,req){const config=this.#getNextConfig(running);if(config==null){return null}const runner={config:config,result:null,didBump:false,perform:null,staller:null};const now=getTime();runner.perform=(async()=>{try{config.requests++;const result=await this._translatePerform(config.provider,req);runner.result={result:result}}catch(error){config.errorResponses++;runner.result={error:error}}const dt=getTime()-now;config._totalTime+=dt;config.rollingDuration=.95*config.rollingDuration+.05*dt;runner.perform=null})();runner.staller=(async()=>{await stall$2(config.stallTimeout);runner.staller=null})();running.add(runner);return runner}async#initialSync(){let initialSync=this.#initialSyncPromise;if(!initialSync){const promises=[];this.#configs.forEach(config=>{promises.push(waitForSync(config,0));promises.push((async()=>{config._network=await config.provider.getNetwork()})())});this.#initialSyncPromise=initialSync=(async()=>{await Promise.all(promises);let chainId=null;for(const config of this.#configs){const network=config._network;if(chainId==null){chainId=network.chainId}else if(network.chainId!==chainId){assert$1(false,"cannot mix providers on different networks","UNSUPPORTED_OPERATION",{operation:"new FallbackProvider"})}}})()}await initialSync}async#checkQuorum(running,req){const results=[];for(const runner of running){if(runner.result!=null){const{tag,value}=normalizeResult(runner.result);results.push({tag:tag,value:value,weight:runner.config.weight})}}if(results.reduce((a,r)=>a+r.weight,0)({value:c.blockNumber,tag:getNumber(c.blockNumber).toString(),weight:c.weight})))))}const mode=getFuzzyMode(this.quorum,results);if(mode===undefined){return undefined}if(mode>this.#height){this.#height=mode}return this.#height}case"getGasPrice":case"estimateGas":return getMedian(this.quorum,results);case"getBlock":if("blockTag"in req&&req.blockTag==="pending"){return getAnyResult(this.quorum,results)}return checkQuorum(this.quorum,results);case"call":case"chainId":case"getBalance":case"getTransactionCount":case"getCode":case"getStorage":case"getTransaction":case"getTransactionReceipt":case"getLogs":return checkQuorum(this.quorum,results);case"broadcastTransaction":return getAnyResult(this.quorum,results)}assert$1(false,"unsupported method","UNSUPPORTED_OPERATION",{operation:`_perform(${stringify(req.method)})`})}async#waitForQuorum(running,req){if(running.size===0){throw new Error("no runners?!")}const interesting=[];let newRunners=0;for(const runner of running){if(runner.perform){interesting.push(runner.perform)}if(runner.staller){interesting.push(runner.staller);continue}if(runner.didBump){continue}runner.didBump=true;newRunners++}const value=await this.#checkQuorum(running,req);if(value!==undefined){if(value instanceof Error){throw value}return value}for(let i=0;i0,"quorum not met","SERVER_ERROR",{request:"%sub-requests",info:{request:req,results:Array.from(running).map(r=>stringify(r.result))}});await Promise.race(interesting);return await this.#waitForQuorum(running,req)}async _perform(req){if(req.method==="broadcastTransaction"){const results=await Promise.all(this.#configs.map(async({provider,weight})=>{try{const result=await provider._perform(req);return Object.assign(normalizeResult({result:result}),{weight:weight})}catch(error){return Object.assign(normalizeResult({error:error}),{weight:weight})}}));const result=getAnyResult(this.quorum,results);assert$1(result!==undefined,"problem multi-broadcasting","SERVER_ERROR",{request:"%sub-requests",info:{request:req,results:results.map(stringify)}});if(result instanceof Error){throw result}return result}await this.#initialSync();const running=new Set;for(let i=0;i{const payload={method:method,params:params};this.emit("debug",{action:"sendEip1193Request",payload:payload});try{const result=await ethereum.request(payload);this.emit("debug",{action:"receiveEip1193Result",result:result});return result}catch(e){const error=new Error(e.message);error.code=e.code;error.data=e.data;error.payload=payload;this.emit("debug",{action:"receiveEip1193Error",error:error});throw error}}}async send(method,params){await this._start();return await super.send(method,params)}async _send(payload){assertArgument(!Array.isArray(payload),"EIP-1193 does not support batch request","payload",payload);try{const result=await this.#request(payload.method,payload.params||[]);return[{id:payload.id,result:result}]}catch(e){return[{id:payload.id,error:{code:e.code,data:e.data,message:e.message}}]}}getRpcError(payload,error){error=JSON.parse(JSON.stringify(error));switch(error.error.code||-1){case 4001:error.error.message=`ethers-user-denied: ${error.error.message}`;break;case 4200:error.error.message=`ethers-unsupported: ${error.error.message}`;break}return super.getRpcError(payload,error)}async hasSigner(address){if(address==null){address=0}const accounts=await this.send("eth_accounts",[]);if(typeof address==="number"){return accounts.length>address}address=address.toLowerCase();return accounts.filter(a=>a.toLowerCase()===address).length!==0}async getSigner(address){if(address==null){address=0}if(!await this.hasSigner(address)){try{await this.#request("eth_requestAccounts",[])}catch(error){const payload=error.payload;throw this.getRpcError(payload,{id:payload.id,error:error})}}return await super.getSigner(address)}}const defaultApplicationId="62e1ad51b37b8e00394bda3b";function getHost(name){switch(name){case"mainnet":return"eth-mainnet.gateway.pokt.network";case"goerli":return"eth-goerli.gateway.pokt.network";case"matic":return"poly-mainnet.gateway.pokt.network";case"matic-mumbai":return"polygon-mumbai-rpc.gateway.pokt.network"}assertArgument(false,"unsupported network","network",name)}class PocketProvider extends JsonRpcProvider{applicationId;applicationSecret;constructor(_network,applicationId,applicationSecret){if(_network==null){_network="mainnet"}const network=Network.from(_network);if(applicationId==null){applicationId=defaultApplicationId}if(applicationSecret==null){applicationSecret=null}const options={staticNetwork:network};const request=PocketProvider.getRequest(network,applicationId,applicationSecret);super(request,network,options);defineProperties(this,{applicationId:applicationId,applicationSecret:applicationSecret})}_getProvider(chainId){try{return new PocketProvider(chainId,this.applicationId,this.applicationSecret)}catch(error){}return super._getProvider(chainId)}static getRequest(network,applicationId,applicationSecret){if(applicationId==null){applicationId=defaultApplicationId}const request=new FetchRequest(`https:/\/${getHost(network.name)}/v1/lb/${applicationId}`);request.allowGzip=true;if(applicationSecret){request.setCredentials("",applicationSecret)}if(applicationId===defaultApplicationId){request.retryFunc=async(request,response,attempt)=>{showThrottleMessage("PocketProvider");return true}}return request}isCommunityResource(){return this.applicationId===defaultApplicationId}}const IpcSocketProvider=undefined;class BaseWallet extends AbstractSigner{address;#signingKey;constructor(privateKey,provider){super(provider);assertArgument(privateKey&&typeof privateKey.sign==="function","invalid private key","privateKey","[ REDACTED ]");this.#signingKey=privateKey;const address=computeAddress(this.signingKey.publicKey);defineProperties(this,{address:address})}get signingKey(){return this.#signingKey}get privateKey(){return this.signingKey.privateKey}async getAddress(){return this.address}connect(provider){return new BaseWallet(this.#signingKey,provider)}async signTransaction(tx){const{to,from}=await resolveProperties({to:tx.to?resolveAddress(tx.to,this.provider):undefined,from:tx.from?resolveAddress(tx.from,this.provider):undefined});if(to!=null){tx.to=to}if(from!=null){tx.from=from}if(tx.from!=null){assertArgument(getAddress(tx.from)===this.address,"transaction from address mismatch","tx.from",tx.from);delete tx.from}const btx=Transaction.from(tx);btx.signature=this.signingKey.sign(btx.unsignedHash);return btx.serialized}async signMessage(message){return this.signMessageSync(message)}signMessageSync(message){return this.signingKey.sign(hashMessage(message)).serialized}async signTypedData(domain,types,value){const populated=await TypedDataEncoder.resolveNames(domain,types,value,async name=>{assert$1(this.provider!=null,"cannot resolve ENS names without a provider","UNSUPPORTED_OPERATION",{operation:"resolveName",info:{name:name}});const address=await this.provider.resolveName(name);assert$1(address!=null,"unconfigured ENS name","UNCONFIGURED_NAME",{value:name});return address});return this.signingKey.sign(TypedDataEncoder.hash(populated.domain,types,populated.value)).serialized}}const subsChrs=" !#$%&'()*+,-./<=>?@[]^_`{|}~";const Word=/^[a-z]*$/i;function unfold(words,sep){let initial=97;return words.reduce((accum,word)=>{if(word===sep){initial++}else if(word.match(Word)){accum.push(String.fromCharCode(initial)+word)}else{initial=97;accum.push(word)}return accum},[])}function decode(data,subs){for(let i=subsChrs.length-1;i>=0;i--){data=data.split(subsChrs[i]).join(subs.substring(2*i,2*i+2))}const clumps=[];const leftover=data.replace(/(:|([0-9])|([A-Z][a-z]*))/g,(all,item,semi,word)=>{if(semi){for(let i=parseInt(semi);i>=0;i--){clumps.push(";")}}else{clumps.push(item.toLowerCase())}return""});if(leftover){throw new Error(`leftovers: ${JSON.stringify(leftover)}`)}return unfold(unfold(clumps,";"),":")}function decodeOwl(data){assertArgument(data[0]==="0","unsupported auwl data","data",data);return decode(data.substring(1+2*subsChrs.length),data.substring(1,1+2*subsChrs.length))}class Wordlist{locale;constructor(locale){defineProperties(this,{locale:locale})}split(phrase){return phrase.toLowerCase().split(/\s+/g)}join(words){return words.join(" ")}}class WordlistOwl extends Wordlist{#data;#checksum;constructor(locale,data,checksum){super(locale);this.#data=data;this.#checksum=checksum;this.#words=null}get _data(){return this.#data}_decodeWords(){return decodeOwl(this.#data)}#words;#loadWords(){if(this.#words==null){const words=this._decodeWords();const checksum=id(words.join("\n")+"\n");if(checksum!==this.#checksum){throw new Error(`BIP39 Wordlist for ${this.locale} FAILED`)}this.#words=words}return this.#words}getWord(index){const words=this.#loadWords();assertArgument(index>=0&&index=12&&words.length<=24,"invalid mnemonic length","mnemonic","[ REDACTED ]");const entropy=new Uint8Array(Math.ceil(11*words.length/8));let offset=0;for(let i=0;i=0,`invalid mnemonic word at index ${i}`,"mnemonic","[ REDACTED ]");for(let bit=0;bit<11;bit++){if(index&1<<10-bit){entropy[offset>>3]|=1<<7-offset%8}offset++}}const entropyBits=32*words.length/3;const checksumBits=words.length/3;const checksumMask=getUpperMask(checksumBits);const checksum=getBytes(sha256(entropy.slice(0,entropyBits/8)))[0]&checksumMask;assertArgument(checksum===(entropy[entropy.length-1]&checksumMask),"invalid mnemonic checksum","mnemonic","[ REDACTED ]");return hexlify(entropy.slice(0,entropyBits/8))}function entropyToMnemonic(entropy,wordlist){assertArgument(entropy.length%4===0&&entropy.length>=16&&entropy.length<=32,"invalid entropy size","entropy","[ REDACTED ]");if(wordlist==null){wordlist=LangEn.wordlist()}const indices=[0];let remainingBits=11;for(let i=0;i8){indices[indices.length-1]<<=8;indices[indices.length-1]|=entropy[i];remainingBits-=8}else{indices[indices.length-1]<<=remainingBits;indices[indices.length-1]|=entropy[i]>>8-remainingBits;indices.push(entropy[i]&getLowerMask(8-remainingBits));remainingBits+=3}}const checksumBits=entropy.length/4;const checksum=parseInt(sha256(entropy).substring(2,4),16)&getUpperMask(checksumBits);indices[indices.length-1]<<=checksumBits;indices[indices.length-1]|=checksum>>8-checksumBits;return wordlist.join(indices.map(index=>wordlist.getWord(index)))}const _guard$1={};class Mnemonic{phrase;password;wordlist;entropy;constructor(guard,entropy,phrase,password,wordlist){if(password==null){password=""}if(wordlist==null){wordlist=LangEn.wordlist()}assertPrivate(guard,_guard$1,"Mnemonic");defineProperties(this,{phrase:phrase,password:password,wordlist:wordlist,entropy:entropy})}computeSeed(){const salt=toUtf8Bytes("mnemonic"+this.password,"NFKD");return pbkdf2(toUtf8Bytes(this.phrase,"NFKD"),salt,2048,64,"sha512")}static fromPhrase(phrase,password,wordlist){const entropy=mnemonicToEntropy(phrase,wordlist);phrase=entropyToMnemonic(getBytes(entropy),wordlist);return new Mnemonic(_guard$1,entropy,phrase,password,wordlist)}static fromEntropy(_entropy,password,wordlist){const entropy=getBytes(_entropy,"entropy");const phrase=entropyToMnemonic(entropy,wordlist);return new Mnemonic(_guard$1,hexlify(entropy),phrase,password,wordlist)}static entropyToPhrase(_entropy,wordlist){const entropy=getBytes(_entropy,"entropy");return entropyToMnemonic(entropy,wordlist)}static phraseToEntropy(phrase,wordlist){return mnemonicToEntropy(phrase,wordlist)}static isValidMnemonic(phrase,wordlist){try{mnemonicToEntropy(phrase,wordlist);return true}catch(error){}return false}}var __classPrivateFieldSet$4=__$G&&__$G.__classPrivateFieldSet||function(receiver,state,value,kind,f){if(kind==="m")throw new TypeError("Private method is not writable");if(kind==="a"&&!f)throw new TypeError("Private accessor was defined without a setter");if(typeof state==="function"?receiver!==state||!f:!state.has(receiver))throw new TypeError("Cannot write private member to an object whose class did not declare it");return kind==="a"?f.call(receiver,value):f?f.value=value:state.set(receiver,value),value};var __classPrivateFieldGet$4=__$G&&__$G.__classPrivateFieldGet||function(receiver,state,kind,f){if(kind==="a"&&!f)throw new TypeError("Private accessor was defined without a getter");if(typeof state==="function"?receiver!==state||!f:!state.has(receiver))throw new TypeError("Cannot read private member from an object whose class did not declare it");return kind==="m"?f:kind==="a"?f.call(receiver):f?f.value:state.get(receiver)};var _AES_key,_AES_Kd,_AES_Ke;const numberOfRounds={16:10,24:12,32:14};const rcon=[1,2,4,8,16,32,64,128,27,54,108,216,171,77,154,47,94,188,99,198,151,53,106,212,179,125,250,239,197,145];const S=[99,124,119,123,242,107,111,197,48,1,103,43,254,215,171,118,202,130,201,125,250,89,71,240,173,212,162,175,156,164,114,192,183,253,147,38,54,63,247,204,52,165,229,241,113,216,49,21,4,199,35,195,24,150,5,154,7,18,128,226,235,39,178,117,9,131,44,26,27,110,90,160,82,59,214,179,41,227,47,132,83,209,0,237,32,252,177,91,106,203,190,57,74,76,88,207,208,239,170,251,67,77,51,133,69,249,2,127,80,60,159,168,81,163,64,143,146,157,56,245,188,182,218,33,16,255,243,210,205,12,19,236,95,151,68,23,196,167,126,61,100,93,25,115,96,129,79,220,34,42,144,136,70,238,184,20,222,94,11,219,224,50,58,10,73,6,36,92,194,211,172,98,145,149,228,121,231,200,55,109,141,213,78,169,108,86,244,234,101,122,174,8,186,120,37,46,28,166,180,198,232,221,116,31,75,189,139,138,112,62,181,102,72,3,246,14,97,53,87,185,134,193,29,158,225,248,152,17,105,217,142,148,155,30,135,233,206,85,40,223,140,161,137,13,191,230,66,104,65,153,45,15,176,84,187,22];const Si=[82,9,106,213,48,54,165,56,191,64,163,158,129,243,215,251,124,227,57,130,155,47,255,135,52,142,67,68,196,222,233,203,84,123,148,50,166,194,35,61,238,76,149,11,66,250,195,78,8,46,161,102,40,217,36,178,118,91,162,73,109,139,209,37,114,248,246,100,134,104,152,22,212,164,92,204,93,101,182,146,108,112,72,80,253,237,185,218,94,21,70,87,167,141,157,132,144,216,171,0,140,188,211,10,247,228,88,5,184,179,69,6,208,44,30,143,202,63,15,2,193,175,189,3,1,19,138,107,58,145,17,65,79,103,220,234,151,242,207,206,240,180,230,115,150,172,116,34,231,173,53,133,226,249,55,232,28,117,223,110,71,241,26,113,29,41,197,137,111,183,98,14,170,24,190,27,252,86,62,75,198,210,121,32,154,219,192,254,120,205,90,244,31,221,168,51,136,7,199,49,177,18,16,89,39,128,236,95,96,81,127,169,25,181,74,13,45,229,122,159,147,201,156,239,160,224,59,77,174,42,245,176,200,235,187,60,131,83,153,97,23,43,4,126,186,119,214,38,225,105,20,99,85,33,12,125];const T1=[3328402341,4168907908,4000806809,4135287693,4294111757,3597364157,3731845041,2445657428,1613770832,33620227,3462883241,1445669757,3892248089,3050821474,1303096294,3967186586,2412431941,528646813,2311702848,4202528135,4026202645,2992200171,2387036105,4226871307,1101901292,3017069671,1604494077,1169141738,597466303,1403299063,3832705686,2613100635,1974974402,3791519004,1033081774,1277568618,1815492186,2118074177,4126668546,2211236943,1748251740,1369810420,3521504564,4193382664,3799085459,2883115123,1647391059,706024767,134480908,2512897874,1176707941,2646852446,806885416,932615841,168101135,798661301,235341577,605164086,461406363,3756188221,3454790438,1311188841,2142417613,3933566367,302582043,495158174,1479289972,874125870,907746093,3698224818,3025820398,1537253627,2756858614,1983593293,3084310113,2108928974,1378429307,3722699582,1580150641,327451799,2790478837,3117535592,0,3253595436,1075847264,3825007647,2041688520,3059440621,3563743934,2378943302,1740553945,1916352843,2487896798,2555137236,2958579944,2244988746,3151024235,3320835882,1336584933,3992714006,2252555205,2588757463,1714631509,293963156,2319795663,3925473552,67240454,4269768577,2689618160,2017213508,631218106,1269344483,2723238387,1571005438,2151694528,93294474,1066570413,563977660,1882732616,4059428100,1673313503,2008463041,2950355573,1109467491,537923632,3858759450,4260623118,3218264685,2177748300,403442708,638784309,3287084079,3193921505,899127202,2286175436,773265209,2479146071,1437050866,4236148354,2050833735,3362022572,3126681063,840505643,3866325909,3227541664,427917720,2655997905,2749160575,1143087718,1412049534,999329963,193497219,2353415882,3354324521,1807268051,672404540,2816401017,3160301282,369822493,2916866934,3688947771,1681011286,1949973070,336202270,2454276571,201721354,1210328172,3093060836,2680341085,3184776046,1135389935,3294782118,965841320,831886756,3554993207,4068047243,3588745010,2345191491,1849112409,3664604599,26054028,2983581028,2622377682,1235855840,3630984372,2891339514,4092916743,3488279077,3395642799,4101667470,1202630377,268961816,1874508501,4034427016,1243948399,1546530418,941366308,1470539505,1941222599,2546386513,3421038627,2715671932,3899946140,1042226977,2521517021,1639824860,227249030,260737669,3765465232,2084453954,1907733956,3429263018,2420656344,100860677,4160157185,470683154,3261161891,1781871967,2924959737,1773779408,394692241,2579611992,974986535,664706745,3655459128,3958962195,731420851,571543859,3530123707,2849626480,126783113,865375399,765172662,1008606754,361203602,3387549984,2278477385,2857719295,1344809080,2782912378,59542671,1503764984,160008576,437062935,1707065306,3622233649,2218934982,3496503480,2185314755,697932208,1512910199,504303377,2075177163,2824099068,1841019862,739644986];const T2=[2781242211,2230877308,2582542199,2381740923,234877682,3184946027,2984144751,1418839493,1348481072,50462977,2848876391,2102799147,434634494,1656084439,3863849899,2599188086,1167051466,2636087938,1082771913,2281340285,368048890,3954334041,3381544775,201060592,3963727277,1739838676,4250903202,3930435503,3206782108,4149453988,2531553906,1536934080,3262494647,484572669,2923271059,1783375398,1517041206,1098792767,49674231,1334037708,1550332980,4098991525,886171109,150598129,2481090929,1940642008,1398944049,1059722517,201851908,1385547719,1699095331,1587397571,674240536,2704774806,252314885,3039795866,151914247,908333586,2602270848,1038082786,651029483,1766729511,3447698098,2682942837,454166793,2652734339,1951935532,775166490,758520603,3000790638,4004797018,4217086112,4137964114,1299594043,1639438038,3464344499,2068982057,1054729187,1901997871,2534638724,4121318227,1757008337,0,750906861,1614815264,535035132,3363418545,3988151131,3201591914,1183697867,3647454910,1265776953,3734260298,3566750796,3903871064,1250283471,1807470800,717615087,3847203498,384695291,3313910595,3617213773,1432761139,2484176261,3481945413,283769337,100925954,2180939647,4037038160,1148730428,3123027871,3813386408,4087501137,4267549603,3229630528,2315620239,2906624658,3156319645,1215313976,82966005,3747855548,3245848246,1974459098,1665278241,807407632,451280895,251524083,1841287890,1283575245,337120268,891687699,801369324,3787349855,2721421207,3431482436,959321879,1469301956,4065699751,2197585534,1199193405,2898814052,3887750493,724703513,2514908019,2696962144,2551808385,3516813135,2141445340,1715741218,2119445034,2872807568,2198571144,3398190662,700968686,3547052216,1009259540,2041044702,3803995742,487983883,1991105499,1004265696,1449407026,1316239930,504629770,3683797321,168560134,1816667172,3837287516,1570751170,1857934291,4014189740,2797888098,2822345105,2754712981,936633572,2347923833,852879335,1133234376,1500395319,3084545389,2348912013,1689376213,3533459022,3762923945,3034082412,4205598294,133428468,634383082,2949277029,2398386810,3913789102,403703816,3580869306,2297460856,1867130149,1918643758,607656988,4049053350,3346248884,1368901318,600565992,2090982877,2632479860,557719327,3717614411,3697393085,2249034635,2232388234,2430627952,1115438654,3295786421,2865522278,3633334344,84280067,33027830,303828494,2747425121,1600795957,4188952407,3496589753,2434238086,1486471617,658119965,3106381470,953803233,334231800,3005978776,857870609,3151128937,1890179545,2298973838,2805175444,3056442267,574365214,2450884487,550103529,1233637070,4289353045,2018519080,2057691103,2399374476,4166623649,2148108681,387583245,3664101311,836232934,3330556482,3100665960,3280093505,2955516313,2002398509,287182607,3413881008,4238890068,3597515707,975967766];const T3=[1671808611,2089089148,2006576759,2072901243,4061003762,1807603307,1873927791,3310653893,810573872,16974337,1739181671,729634347,4263110654,3613570519,2883997099,1989864566,3393556426,2191335298,3376449993,2106063485,4195741690,1508618841,1204391495,4027317232,2917941677,3563566036,2734514082,2951366063,2629772188,2767672228,1922491506,3227229120,3082974647,4246528509,2477669779,644500518,911895606,1061256767,4144166391,3427763148,878471220,2784252325,3845444069,4043897329,1905517169,3631459288,827548209,356461077,67897348,3344078279,593839651,3277757891,405286936,2527147926,84871685,2595565466,118033927,305538066,2157648768,3795705826,3945188843,661212711,2999812018,1973414517,152769033,2208177539,745822252,439235610,455947803,1857215598,1525593178,2700827552,1391895634,994932283,3596728278,3016654259,695947817,3812548067,795958831,2224493444,1408607827,3513301457,0,3979133421,543178784,4229948412,2982705585,1542305371,1790891114,3410398667,3201918910,961245753,1256100938,1289001036,1491644504,3477767631,3496721360,4012557807,2867154858,4212583931,1137018435,1305975373,861234739,2241073541,1171229253,4178635257,33948674,2139225727,1357946960,1011120188,2679776671,2833468328,1374921297,2751356323,1086357568,2408187279,2460827538,2646352285,944271416,4110742005,3168756668,3066132406,3665145818,560153121,271589392,4279952895,4077846003,3530407890,3444343245,202643468,322250259,3962553324,1608629855,2543990167,1154254916,389623319,3294073796,2817676711,2122513534,1028094525,1689045092,1575467613,422261273,1939203699,1621147744,2174228865,1339137615,3699352540,577127458,712922154,2427141008,2290289544,1187679302,3995715566,3100863416,339486740,3732514782,1591917662,186455563,3681988059,3762019296,844522546,978220090,169743370,1239126601,101321734,611076132,1558493276,3260915650,3547250131,2901361580,1655096418,2443721105,2510565781,3828863972,2039214713,3878868455,3359869896,928607799,1840765549,2374762893,3580146133,1322425422,2850048425,1823791212,1459268694,4094161908,3928346602,1706019429,2056189050,2934523822,135794696,3134549946,2022240376,628050469,779246638,472135708,2800834470,3032970164,3327236038,3894660072,3715932637,1956440180,522272287,1272813131,3185336765,2340818315,2323976074,1888542832,1044544574,3049550261,1722469478,1222152264,50660867,4127324150,236067854,1638122081,895445557,1475980887,3117443513,2257655686,3243809217,489110045,2662934430,3778599393,4162055160,2561878936,288563729,1773916777,3648039385,2391345038,2493985684,2612407707,505560094,2274497927,3911240169,3460925390,1442818645,678973480,3749357023,2358182796,2717407649,2306869641,219617805,3218761151,3862026214,1120306242,1756942440,1103331905,2578459033,762796589,252780047,2966125488,1425844308,3151392187,372911126];const T4=[1667474886,2088535288,2004326894,2071694838,4075949567,1802223062,1869591006,3318043793,808472672,16843522,1734846926,724270422,4278065639,3621216949,2880169549,1987484396,3402253711,2189597983,3385409673,2105378810,4210693615,1499065266,1195886990,4042263547,2913856577,3570689971,2728590687,2947541573,2627518243,2762274643,1920112356,3233831835,3082273397,4261223649,2475929149,640051788,909531756,1061110142,4160160501,3435941763,875846760,2779116625,3857003729,4059105529,1903268834,3638064043,825316194,353713962,67374088,3351728789,589522246,3284360861,404236336,2526454071,84217610,2593830191,117901582,303183396,2155911963,3806477791,3958056653,656894286,2998062463,1970642922,151591698,2206440989,741110872,437923380,454765878,1852748508,1515908788,2694904667,1381168804,993742198,3604373943,3014905469,690584402,3823320797,791638366,2223281939,1398011302,3520161977,0,3991743681,538992704,4244381667,2981218425,1532751286,1785380564,3419096717,3200178535,960056178,1246420628,1280103576,1482221744,3486468741,3503319995,4025428677,2863326543,4227536621,1128514950,1296947098,859002214,2240123921,1162203018,4193849577,33687044,2139062782,1347481760,1010582648,2678045221,2829640523,1364325282,2745433693,1077985408,2408548869,2459086143,2644360225,943212656,4126475505,3166494563,3065430391,3671750063,555836226,269496352,4294908645,4092792573,3537006015,3452783745,202118168,320025894,3974901699,1600119230,2543297077,1145359496,387397934,3301201811,2812801621,2122220284,1027426170,1684319432,1566435258,421079858,1936954854,1616945344,2172753945,1330631070,3705438115,572679748,707427924,2425400123,2290647819,1179044492,4008585671,3099120491,336870440,3739122087,1583276732,185277718,3688593069,3772791771,842159716,976899700,168435220,1229577106,101059084,606366792,1549591736,3267517855,3553849021,2897014595,1650632388,2442242105,2509612081,3840161747,2038008818,3890688725,3368567691,926374254,1835907034,2374863873,3587531953,1313788572,2846482505,1819063512,1448540844,4109633523,3941213647,1701162954,2054852340,2930698567,134748176,3132806511,2021165296,623210314,774795868,471606328,2795958615,3031746419,3334885783,3907527627,3722280097,1953799400,522133822,1263263126,3183336545,2341176845,2324333839,1886425312,1044267644,3048588401,1718004428,1212733584,50529542,4143317495,235803164,1633788866,892690282,1465383342,3115962473,2256965911,3250673817,488449850,2661202215,3789633753,4177007595,2560144171,286339874,1768537042,3654906025,2391705863,2492770099,2610673197,505291324,2273808917,3924369609,3469625735,1431699370,673740880,3755965093,2358021891,2711746649,2307489801,218961690,3217021541,3873845719,1111672452,1751693520,1094828930,2576986153,757954394,252645662,2964376443,1414855848,3149649517,370555436];const T5=[1374988112,2118214995,437757123,975658646,1001089995,530400753,2902087851,1273168787,540080725,2910219766,2295101073,4110568485,1340463100,3307916247,641025152,3043140495,3736164937,632953703,1172967064,1576976609,3274667266,2169303058,2370213795,1809054150,59727847,361929877,3211623147,2505202138,3569255213,1484005843,1239443753,2395588676,1975683434,4102977912,2572697195,666464733,3202437046,4035489047,3374361702,2110667444,1675577880,3843699074,2538681184,1649639237,2976151520,3144396420,4269907996,4178062228,1883793496,2403728665,2497604743,1383856311,2876494627,1917518562,3810496343,1716890410,3001755655,800440835,2261089178,3543599269,807962610,599762354,33778362,3977675356,2328828971,2809771154,4077384432,1315562145,1708848333,101039829,3509871135,3299278474,875451293,2733856160,92987698,2767645557,193195065,1080094634,1584504582,3178106961,1042385657,2531067453,3711829422,1306967366,2438237621,1908694277,67556463,1615861247,429456164,3602770327,2302690252,1742315127,2968011453,126454664,3877198648,2043211483,2709260871,2084704233,4169408201,0,159417987,841739592,504459436,1817866830,4245618683,260388950,1034867998,908933415,168810852,1750902305,2606453969,607530554,202008497,2472011535,3035535058,463180190,2160117071,1641816226,1517767529,470948374,3801332234,3231722213,1008918595,303765277,235474187,4069246893,766945465,337553864,1475418501,2943682380,4003061179,2743034109,4144047775,1551037884,1147550661,1543208500,2336434550,3408119516,3069049960,3102011747,3610369226,1113818384,328671808,2227573024,2236228733,3535486456,2935566865,3341394285,496906059,3702665459,226906860,2009195472,733156972,2842737049,294930682,1206477858,2835123396,2700099354,1451044056,573804783,2269728455,3644379585,2362090238,2564033334,2801107407,2776292904,3669462566,1068351396,742039012,1350078989,1784663195,1417561698,4136440770,2430122216,775550814,2193862645,2673705150,1775276924,1876241833,3475313331,3366754619,270040487,3902563182,3678124923,3441850377,1851332852,3969562369,2203032232,3868552805,2868897406,566021896,4011190502,3135740889,1248802510,3936291284,699432150,832877231,708780849,3332740144,899835584,1951317047,4236429990,3767586992,866637845,4043610186,1106041591,2144161806,395441711,1984812685,1139781709,3433712980,3835036895,2664543715,1282050075,3240894392,1181045119,2640243204,25965917,4203181171,4211818798,3009879386,2463879762,3910161971,1842759443,2597806476,933301370,1509430414,3943906441,3467192302,3076639029,3776767469,2051518780,2631065433,1441952575,404016761,1942435775,1408749034,1610459739,3745345300,2017778566,3400528769,3110650942,941896748,3265478751,371049330,3168937228,675039627,4279080257,967311729,135050206,3635733660,1683407248,2076935265,3576870512,1215061108,3501741890];const T6=[1347548327,1400783205,3273267108,2520393566,3409685355,4045380933,2880240216,2471224067,1428173050,4138563181,2441661558,636813900,4233094615,3620022987,2149987652,2411029155,1239331162,1730525723,2554718734,3781033664,46346101,310463728,2743944855,3328955385,3875770207,2501218972,3955191162,3667219033,768917123,3545789473,692707433,1150208456,1786102409,2029293177,1805211710,3710368113,3065962831,401639597,1724457132,3028143674,409198410,2196052529,1620529459,1164071807,3769721975,2226875310,486441376,2499348523,1483753576,428819965,2274680428,3075636216,598438867,3799141122,1474502543,711349675,129166120,53458370,2592523643,2782082824,4063242375,2988687269,3120694122,1559041666,730517276,2460449204,4042459122,2706270690,3446004468,3573941694,533804130,2328143614,2637442643,2695033685,839224033,1973745387,957055980,2856345839,106852767,1371368976,4181598602,1033297158,2933734917,1179510461,3046200461,91341917,1862534868,4284502037,605657339,2547432937,3431546947,2003294622,3182487618,2282195339,954669403,3682191598,1201765386,3917234703,3388507166,0,2198438022,1211247597,2887651696,1315723890,4227665663,1443857720,507358933,657861945,1678381017,560487590,3516619604,975451694,2970356327,261314535,3535072918,2652609425,1333838021,2724322336,1767536459,370938394,182621114,3854606378,1128014560,487725847,185469197,2918353863,3106780840,3356761769,2237133081,1286567175,3152976349,4255350624,2683765030,3160175349,3309594171,878443390,1988838185,3704300486,1756818940,1673061617,3403100636,272786309,1075025698,545572369,2105887268,4174560061,296679730,1841768865,1260232239,4091327024,3960309330,3497509347,1814803222,2578018489,4195456072,575138148,3299409036,446754879,3629546796,4011996048,3347532110,3252238545,4270639778,915985419,3483825537,681933534,651868046,2755636671,3828103837,223377554,2607439820,1649704518,3270937875,3901806776,1580087799,4118987695,3198115200,2087309459,2842678573,3016697106,1003007129,2802849917,1860738147,2077965243,164439672,4100872472,32283319,2827177882,1709610350,2125135846,136428751,3874428392,3652904859,3460984630,3572145929,3593056380,2939266226,824852259,818324884,3224740454,930369212,2801566410,2967507152,355706840,1257309336,4148292826,243256656,790073846,2373340630,1296297904,1422699085,3756299780,3818836405,457992840,3099667487,2135319889,77422314,1560382517,1945798516,788204353,1521706781,1385356242,870912086,325965383,2358957921,2050466060,2388260884,2313884476,4006521127,901210569,3990953189,1014646705,1503449823,1062597235,2031621326,3212035895,3931371469,1533017514,350174575,2256028891,2177544179,1052338372,741876788,1606591296,1914052035,213705253,2334669897,1107234197,1899603969,3725069491,2631447780,2422494913,1635502980,1893020342,1950903388,1120974935];const T7=[2807058932,1699970625,2764249623,1586903591,1808481195,1173430173,1487645946,59984867,4199882800,1844882806,1989249228,1277555970,3623636965,3419915562,1149249077,2744104290,1514790577,459744698,244860394,3235995134,1963115311,4027744588,2544078150,4190530515,1608975247,2627016082,2062270317,1507497298,2200818878,567498868,1764313568,3359936201,2305455554,2037970062,1047239e3,1910319033,1337376481,2904027272,2892417312,984907214,1243112415,830661914,861968209,2135253587,2011214180,2927934315,2686254721,731183368,1750626376,4246310725,1820824798,4172763771,3542330227,48394827,2404901663,2871682645,671593195,3254988725,2073724613,145085239,2280796200,2779915199,1790575107,2187128086,472615631,3029510009,4075877127,3802222185,4107101658,3201631749,1646252340,4270507174,1402811438,1436590835,3778151818,3950355702,3963161475,4020912224,2667994737,273792366,2331590177,104699613,95345982,3175501286,2377486676,1560637892,3564045318,369057872,4213447064,3919042237,1137477952,2658625497,1119727848,2340947849,1530455833,4007360968,172466556,266959938,516552836,0,2256734592,3980931627,1890328081,1917742170,4294704398,945164165,3575528878,958871085,3647212047,2787207260,1423022939,775562294,1739656202,3876557655,2530391278,2443058075,3310321856,547512796,1265195639,437656594,3121275539,719700128,3762502690,387781147,218828297,3350065803,2830708150,2848461854,428169201,122466165,3720081049,1627235199,648017665,4122762354,1002783846,2117360635,695634755,3336358691,4234721005,4049844452,3704280881,2232435299,574624663,287343814,612205898,1039717051,840019705,2708326185,793451934,821288114,1391201670,3822090177,376187827,3113855344,1224348052,1679968233,2361698556,1058709744,752375421,2431590963,1321699145,3519142200,2734591178,188127444,2177869557,3727205754,2384911031,3215212461,2648976442,2450346104,3432737375,1180849278,331544205,3102249176,4150144569,2952102595,2159976285,2474404304,766078933,313773861,2570832044,2108100632,1668212892,3145456443,2013908262,418672217,3070356634,2594734927,1852171925,3867060991,3473416636,3907448597,2614737639,919489135,164948639,2094410160,2997825956,590424639,2486224549,1723872674,3157750862,3399941250,3501252752,3625268135,2555048196,3673637356,1343127501,4130281361,3599595085,2957853679,1297403050,81781910,3051593425,2283490410,532201772,1367295589,3926170974,895287692,1953757831,1093597963,492483431,3528626907,1446242576,1192455638,1636604631,209336225,344873464,1015671571,669961897,3375740769,3857572124,2973530695,3747192018,1933530610,3464042516,935293895,3454686199,2858115069,1863638845,3683022916,4085369519,3292445032,875313188,1080017571,3279033885,621591778,1233856572,2504130317,24197544,3017672716,3835484340,3247465558,2220981195,3060847922,1551124588,1463996600];const T8=[4104605777,1097159550,396673818,660510266,2875968315,2638606623,4200115116,3808662347,821712160,1986918061,3430322568,38544885,3856137295,718002117,893681702,1654886325,2975484382,3122358053,3926825029,4274053469,796197571,1290801793,1184342925,3556361835,2405426947,2459735317,1836772287,1381620373,3196267988,1948373848,3764988233,3385345166,3263785589,2390325492,1480485785,3111247143,3780097726,2293045232,548169417,3459953789,3746175075,439452389,1362321559,1400849762,1685577905,1806599355,2174754046,137073913,1214797936,1174215055,3731654548,2079897426,1943217067,1258480242,529487843,1437280870,3945269170,3049390895,3313212038,923313619,679998e3,3215307299,57326082,377642221,3474729866,2041877159,133361907,1776460110,3673476453,96392454,878845905,2801699524,777231668,4082475170,2330014213,4142626212,2213296395,1626319424,1906247262,1846563261,562755902,3708173718,1040559837,3871163981,1418573201,3294430577,114585348,1343618912,2566595609,3186202582,1078185097,3651041127,3896688048,2307622919,425408743,3371096953,2081048481,1108339068,2216610296,0,2156299017,736970802,292596766,1517440620,251657213,2235061775,2933202493,758720310,265905162,1554391400,1532285339,908999204,174567692,1474760595,4002861748,2610011675,3234156416,3693126241,2001430874,303699484,2478443234,2687165888,585122620,454499602,151849742,2345119218,3064510765,514443284,4044981591,1963412655,2581445614,2137062819,19308535,1928707164,1715193156,4219352155,1126790795,600235211,3992742070,3841024952,836553431,1669664834,2535604243,3323011204,1243905413,3141400786,4180808110,698445255,2653899549,2989552604,2253581325,3252932727,3004591147,1891211689,2487810577,3915653703,4237083816,4030667424,2100090966,865136418,1229899655,953270745,3399679628,3557504664,4118925222,2061379749,3079546586,2915017791,983426092,2022837584,1607244650,2118541908,2366882550,3635996816,972512814,3283088770,1568718495,3499326569,3576539503,621982671,2895723464,410887952,2623762152,1002142683,645401037,1494807662,2595684844,1335535747,2507040230,4293295786,3167684641,367585007,3885750714,1865862730,2668221674,2960971305,2763173681,1059270954,2777952454,2724642869,1320957812,2194319100,2429595872,2815956275,77089521,3973773121,3444575871,2448830231,1305906550,4021308739,2857194700,2516901860,3518358430,1787304780,740276417,1699839814,1592394909,2352307457,2272556026,188821243,1729977011,3687994002,274084841,3594982253,3613494426,2701949495,4162096729,322734571,2837966542,1640576439,484830689,1202797690,3537852828,4067639125,349075736,3342319475,4157467219,4255800159,1030690015,1155237496,2951971274,1757691577,607398968,2738905026,499347990,3794078908,1011452712,227885567,2818666809,213114376,3034881240,1455525988,3414450555,850817237,1817998408,3092726480];const U1=[0,235474187,470948374,303765277,941896748,908933415,607530554,708780849,1883793496,2118214995,1817866830,1649639237,1215061108,1181045119,1417561698,1517767529,3767586992,4003061179,4236429990,4069246893,3635733660,3602770327,3299278474,3400528769,2430122216,2664543715,2362090238,2193862645,2835123396,2801107407,3035535058,3135740889,3678124923,3576870512,3341394285,3374361702,3810496343,3977675356,4279080257,4043610186,2876494627,2776292904,3076639029,3110650942,2472011535,2640243204,2403728665,2169303058,1001089995,899835584,666464733,699432150,59727847,226906860,530400753,294930682,1273168787,1172967064,1475418501,1509430414,1942435775,2110667444,1876241833,1641816226,2910219766,2743034109,2976151520,3211623147,2505202138,2606453969,2302690252,2269728455,3711829422,3543599269,3240894392,3475313331,3843699074,3943906441,4178062228,4144047775,1306967366,1139781709,1374988112,1610459739,1975683434,2076935265,1775276924,1742315127,1034867998,866637845,566021896,800440835,92987698,193195065,429456164,395441711,1984812685,2017778566,1784663195,1683407248,1315562145,1080094634,1383856311,1551037884,101039829,135050206,437757123,337553864,1042385657,807962610,573804783,742039012,2531067453,2564033334,2328828971,2227573024,2935566865,2700099354,3001755655,3168937228,3868552805,3902563182,4203181171,4102977912,3736164937,3501741890,3265478751,3433712980,1106041591,1340463100,1576976609,1408749034,2043211483,2009195472,1708848333,1809054150,832877231,1068351396,766945465,599762354,159417987,126454664,361929877,463180190,2709260871,2943682380,3178106961,3009879386,2572697195,2538681184,2236228733,2336434550,3509871135,3745345300,3441850377,3274667266,3910161971,3877198648,4110568485,4211818798,2597806476,2497604743,2261089178,2295101073,2733856160,2902087851,3202437046,2968011453,3936291284,3835036895,4136440770,4169408201,3535486456,3702665459,3467192302,3231722213,2051518780,1951317047,1716890410,1750902305,1113818384,1282050075,1584504582,1350078989,168810852,67556463,371049330,404016761,841739592,1008918595,775550814,540080725,3969562369,3801332234,4035489047,4269907996,3569255213,3669462566,3366754619,3332740144,2631065433,2463879762,2160117071,2395588676,2767645557,2868897406,3102011747,3069049960,202008497,33778362,270040487,504459436,875451293,975658646,675039627,641025152,2084704233,1917518562,1615861247,1851332852,1147550661,1248802510,1484005843,1451044056,933301370,967311729,733156972,632953703,260388950,25965917,328671808,496906059,1206477858,1239443753,1543208500,1441952575,2144161806,1908694277,1675577880,1842759443,3610369226,3644379585,3408119516,3307916247,4011190502,3776767469,4077384432,4245618683,2809771154,2842737049,3144396420,3043140495,2673705150,2438237621,2203032232,2370213795];const U2=[0,185469197,370938394,487725847,741876788,657861945,975451694,824852259,1483753576,1400783205,1315723890,1164071807,1950903388,2135319889,1649704518,1767536459,2967507152,3152976349,2801566410,2918353863,2631447780,2547432937,2328143614,2177544179,3901806776,3818836405,4270639778,4118987695,3299409036,3483825537,3535072918,3652904859,2077965243,1893020342,1841768865,1724457132,1474502543,1559041666,1107234197,1257309336,598438867,681933534,901210569,1052338372,261314535,77422314,428819965,310463728,3409685355,3224740454,3710368113,3593056380,3875770207,3960309330,4045380933,4195456072,2471224067,2554718734,2237133081,2388260884,3212035895,3028143674,2842678573,2724322336,4138563181,4255350624,3769721975,3955191162,3667219033,3516619604,3431546947,3347532110,2933734917,2782082824,3099667487,3016697106,2196052529,2313884476,2499348523,2683765030,1179510461,1296297904,1347548327,1533017514,1786102409,1635502980,2087309459,2003294622,507358933,355706840,136428751,53458370,839224033,957055980,605657339,790073846,2373340630,2256028891,2607439820,2422494913,2706270690,2856345839,3075636216,3160175349,3573941694,3725069491,3273267108,3356761769,4181598602,4063242375,4011996048,3828103837,1033297158,915985419,730517276,545572369,296679730,446754879,129166120,213705253,1709610350,1860738147,1945798516,2029293177,1239331162,1120974935,1606591296,1422699085,4148292826,4233094615,3781033664,3931371469,3682191598,3497509347,3446004468,3328955385,2939266226,2755636671,3106780840,2988687269,2198438022,2282195339,2501218972,2652609425,1201765386,1286567175,1371368976,1521706781,1805211710,1620529459,2105887268,1988838185,533804130,350174575,164439672,46346101,870912086,954669403,636813900,788204353,2358957921,2274680428,2592523643,2441661558,2695033685,2880240216,3065962831,3182487618,3572145929,3756299780,3270937875,3388507166,4174560061,4091327024,4006521127,3854606378,1014646705,930369212,711349675,560487590,272786309,457992840,106852767,223377554,1678381017,1862534868,1914052035,2031621326,1211247597,1128014560,1580087799,1428173050,32283319,182621114,401639597,486441376,768917123,651868046,1003007129,818324884,1503449823,1385356242,1333838021,1150208456,1973745387,2125135846,1673061617,1756818940,2970356327,3120694122,2802849917,2887651696,2637442643,2520393566,2334669897,2149987652,3917234703,3799141122,4284502037,4100872472,3309594171,3460984630,3545789473,3629546796,2050466060,1899603969,1814803222,1730525723,1443857720,1560382517,1075025698,1260232239,575138148,692707433,878443390,1062597235,243256656,91341917,409198410,325965383,3403100636,3252238545,3704300486,3620022987,3874428392,3990953189,4042459122,4227665663,2460449204,2578018489,2226875310,2411029155,3198115200,3046200461,2827177882,2743944855];const U3=[0,218828297,437656594,387781147,875313188,958871085,775562294,590424639,1750626376,1699970625,1917742170,2135253587,1551124588,1367295589,1180849278,1265195639,3501252752,3720081049,3399941250,3350065803,3835484340,3919042237,4270507174,4085369519,3102249176,3051593425,2734591178,2952102595,2361698556,2177869557,2530391278,2614737639,3145456443,3060847922,2708326185,2892417312,2404901663,2187128086,2504130317,2555048196,3542330227,3727205754,3375740769,3292445032,3876557655,3926170974,4246310725,4027744588,1808481195,1723872674,1910319033,2094410160,1608975247,1391201670,1173430173,1224348052,59984867,244860394,428169201,344873464,935293895,984907214,766078933,547512796,1844882806,1627235199,2011214180,2062270317,1507497298,1423022939,1137477952,1321699145,95345982,145085239,532201772,313773861,830661914,1015671571,731183368,648017665,3175501286,2957853679,2807058932,2858115069,2305455554,2220981195,2474404304,2658625497,3575528878,3625268135,3473416636,3254988725,3778151818,3963161475,4213447064,4130281361,3599595085,3683022916,3432737375,3247465558,3802222185,4020912224,4172763771,4122762354,3201631749,3017672716,2764249623,2848461854,2331590177,2280796200,2431590963,2648976442,104699613,188127444,472615631,287343814,840019705,1058709744,671593195,621591778,1852171925,1668212892,1953757831,2037970062,1514790577,1463996600,1080017571,1297403050,3673637356,3623636965,3235995134,3454686199,4007360968,3822090177,4107101658,4190530515,2997825956,3215212461,2830708150,2779915199,2256734592,2340947849,2627016082,2443058075,172466556,122466165,273792366,492483431,1047239e3,861968209,612205898,695634755,1646252340,1863638845,2013908262,1963115311,1446242576,1530455833,1277555970,1093597963,1636604631,1820824798,2073724613,1989249228,1436590835,1487645946,1337376481,1119727848,164948639,81781910,331544205,516552836,1039717051,821288114,669961897,719700128,2973530695,3157750862,2871682645,2787207260,2232435299,2283490410,2667994737,2450346104,3647212047,3564045318,3279033885,3464042516,3980931627,3762502690,4150144569,4199882800,3070356634,3121275539,2904027272,2686254721,2200818878,2384911031,2570832044,2486224549,3747192018,3528626907,3310321856,3359936201,3950355702,3867060991,4049844452,4234721005,1739656202,1790575107,2108100632,1890328081,1402811438,1586903591,1233856572,1149249077,266959938,48394827,369057872,418672217,1002783846,919489135,567498868,752375421,209336225,24197544,376187827,459744698,945164165,895287692,574624663,793451934,1679968233,1764313568,2117360635,1933530610,1343127501,1560637892,1243112415,1192455638,3704280881,3519142200,3336358691,3419915562,3907448597,3857572124,4075877127,4294704398,3029510009,3113855344,2927934315,2744104290,2159976285,2377486676,2594734927,2544078150];const U4=[0,151849742,303699484,454499602,607398968,758720310,908999204,1059270954,1214797936,1097159550,1517440620,1400849762,1817998408,1699839814,2118541908,2001430874,2429595872,2581445614,2194319100,2345119218,3034881240,3186202582,2801699524,2951971274,3635996816,3518358430,3399679628,3283088770,4237083816,4118925222,4002861748,3885750714,1002142683,850817237,698445255,548169417,529487843,377642221,227885567,77089521,1943217067,2061379749,1640576439,1757691577,1474760595,1592394909,1174215055,1290801793,2875968315,2724642869,3111247143,2960971305,2405426947,2253581325,2638606623,2487810577,3808662347,3926825029,4044981591,4162096729,3342319475,3459953789,3576539503,3693126241,1986918061,2137062819,1685577905,1836772287,1381620373,1532285339,1078185097,1229899655,1040559837,923313619,740276417,621982671,439452389,322734571,137073913,19308535,3871163981,4021308739,4104605777,4255800159,3263785589,3414450555,3499326569,3651041127,2933202493,2815956275,3167684641,3049390895,2330014213,2213296395,2566595609,2448830231,1305906550,1155237496,1607244650,1455525988,1776460110,1626319424,2079897426,1928707164,96392454,213114376,396673818,514443284,562755902,679998e3,865136418,983426092,3708173718,3557504664,3474729866,3323011204,4180808110,4030667424,3945269170,3794078908,2507040230,2623762152,2272556026,2390325492,2975484382,3092726480,2738905026,2857194700,3973773121,3856137295,4274053469,4157467219,3371096953,3252932727,3673476453,3556361835,2763173681,2915017791,3064510765,3215307299,2156299017,2307622919,2459735317,2610011675,2081048481,1963412655,1846563261,1729977011,1480485785,1362321559,1243905413,1126790795,878845905,1030690015,645401037,796197571,274084841,425408743,38544885,188821243,3613494426,3731654548,3313212038,3430322568,4082475170,4200115116,3780097726,3896688048,2668221674,2516901860,2366882550,2216610296,3141400786,2989552604,2837966542,2687165888,1202797690,1320957812,1437280870,1554391400,1669664834,1787304780,1906247262,2022837584,265905162,114585348,499347990,349075736,736970802,585122620,972512814,821712160,2595684844,2478443234,2293045232,2174754046,3196267988,3079546586,2895723464,2777952454,3537852828,3687994002,3234156416,3385345166,4142626212,4293295786,3841024952,3992742070,174567692,57326082,410887952,292596766,777231668,660510266,1011452712,893681702,1108339068,1258480242,1343618912,1494807662,1715193156,1865862730,1948373848,2100090966,2701949495,2818666809,3004591147,3122358053,2235061775,2352307457,2535604243,2653899549,3915653703,3764988233,4219352155,4067639125,3444575871,3294430577,3746175075,3594982253,836553431,953270745,600235211,718002117,367585007,484830689,133361907,251657213,2041877159,1891211689,1806599355,1654886325,1568718495,1418573201,1335535747,1184342925];function convertToInt32(bytes){const result=[];for(let i=0;i>2;__classPrivateFieldGet$4(this,_AES_Ke,"f")[index][i%4]=tk[i];__classPrivateFieldGet$4(this,_AES_Kd,"f")[rounds-index][i%4]=tk[i]}let rconpointer=0;let t=KC,tt;while(t>16&255]<<24^S[tt>>8&255]<<16^S[tt&255]<<8^S[tt>>24&255]^rcon[rconpointer]<<24;rconpointer+=1;if(KC!=8){for(let i=1;i>8&255]<<8^S[tt>>16&255]<<16^S[tt>>24&255]<<24;for(let i=KC/2+1;i>2;c=t%4;__classPrivateFieldGet$4(this,_AES_Ke,"f")[r][c]=tk[i];__classPrivateFieldGet$4(this,_AES_Kd,"f")[rounds-r][c]=tk[i++];t++}}for(let r=1;r>24&255]^U2[tt>>16&255]^U3[tt>>8&255]^U4[tt&255]}}}get key(){return __classPrivateFieldGet$4(this,_AES_key,"f").slice()}encrypt(plaintext){if(plaintext.length!=16){throw new TypeError("invalid plaintext size (must be 16 bytes)")}const rounds=__classPrivateFieldGet$4(this,_AES_Ke,"f").length-1;const a=[0,0,0,0];let t=convertToInt32(plaintext);for(let i=0;i<4;i++){t[i]^=__classPrivateFieldGet$4(this,_AES_Ke,"f")[0][i]}for(let r=1;r>24&255]^T2[t[(i+1)%4]>>16&255]^T3[t[(i+2)%4]>>8&255]^T4[t[(i+3)%4]&255]^__classPrivateFieldGet$4(this,_AES_Ke,"f")[r][i]}t=a.slice()}const result=new Uint8Array(16);let tt=0;for(let i=0;i<4;i++){tt=__classPrivateFieldGet$4(this,_AES_Ke,"f")[rounds][i];result[4*i]=(S[t[i]>>24&255]^tt>>24)&255;result[4*i+1]=(S[t[(i+1)%4]>>16&255]^tt>>16)&255;result[4*i+2]=(S[t[(i+2)%4]>>8&255]^tt>>8)&255;result[4*i+3]=(S[t[(i+3)%4]&255]^tt)&255}return result}decrypt(ciphertext){if(ciphertext.length!=16){throw new TypeError("invalid ciphertext size (must be 16 bytes)")}const rounds=__classPrivateFieldGet$4(this,_AES_Kd,"f").length-1;const a=[0,0,0,0];let t=convertToInt32(ciphertext);for(let i=0;i<4;i++){t[i]^=__classPrivateFieldGet$4(this,_AES_Kd,"f")[0][i]}for(let r=1;r>24&255]^T6[t[(i+3)%4]>>16&255]^T7[t[(i+2)%4]>>8&255]^T8[t[(i+1)%4]&255]^__classPrivateFieldGet$4(this,_AES_Kd,"f")[r][i]}t=a.slice()}const result=new Uint8Array(16);let tt=0;for(let i=0;i<4;i++){tt=__classPrivateFieldGet$4(this,_AES_Kd,"f")[rounds][i];result[4*i]=(Si[t[i]>>24&255]^tt>>24)&255;result[4*i+1]=(Si[t[(i+3)%4]>>16&255]^tt>>16)&255;result[4*i+2]=(Si[t[(i+2)%4]>>8&255]^tt>>8)&255;result[4*i+3]=(Si[t[(i+1)%4]&255]^tt)&255}return result}}_AES_key=new WeakMap,_AES_Kd=new WeakMap,_AES_Ke=new WeakMap;class ModeOfOperation{constructor(name,key,cls){if(cls&&!(this instanceof cls)){throw new Error(`${name} must be instantiated with "new"`)}Object.defineProperties(this,{aes:{enumerable:true,value:new AES(key)},name:{enumerable:true,value:name}})}}var __classPrivateFieldSet$3=__$G&&__$G.__classPrivateFieldSet||function(receiver,state,value,kind,f){if(kind==="m")throw new TypeError("Private method is not writable");if(kind==="a"&&!f)throw new TypeError("Private accessor was defined without a setter");if(typeof state==="function"?receiver!==state||!f:!state.has(receiver))throw new TypeError("Cannot write private member to an object whose class did not declare it");return kind==="a"?f.call(receiver,value):f?f.value=value:state.set(receiver,value),value};var __classPrivateFieldGet$3=__$G&&__$G.__classPrivateFieldGet||function(receiver,state,kind,f){if(kind==="a"&&!f)throw new TypeError("Private accessor was defined without a getter");if(typeof state==="function"?receiver!==state||!f:!state.has(receiver))throw new TypeError("Cannot read private member from an object whose class did not declare it");return kind==="m"?f:kind==="a"?f.call(receiver):f?f.value:state.get(receiver)};var _CBC_iv,_CBC_lastBlock;class CBC extends ModeOfOperation{constructor(key,iv){super("ECC",key,CBC);_CBC_iv.set(this,void 0);_CBC_lastBlock.set(this,void 0);if(iv){if(iv.length%16){throw new TypeError("invalid iv size (must be 16 bytes)")}__classPrivateFieldSet$3(this,_CBC_iv,new Uint8Array(iv),"f")}else{__classPrivateFieldSet$3(this,_CBC_iv,new Uint8Array(16),"f")}__classPrivateFieldSet$3(this,_CBC_lastBlock,this.iv,"f")}get iv(){return new Uint8Array(__classPrivateFieldGet$3(this,_CBC_iv,"f"))}encrypt(plaintext){if(plaintext.length%16){throw new TypeError("invalid plaintext size (must be multiple of 16 bytes)")}const ciphertext=new Uint8Array(plaintext.length);for(let i=0;iNumber.MAX_SAFE_INTEGER){throw new TypeError("invalid counter initial integer value")}for(let index=15;index>=0;--index){__classPrivateFieldGet$1(this,_CTR_counter,"f")[index]=value%256;value=Math.floor(value/256)}}setCounterBytes(value){if(value.length!==16){throw new TypeError("invalid counter initial Uint8Array value length")}__classPrivateFieldGet$1(this,_CTR_counter,"f").set(value)}increment(){for(let i=15;i>=0;i--){if(__classPrivateFieldGet$1(this,_CTR_counter,"f")[i]===255){__classPrivateFieldGet$1(this,_CTR_counter,"f")[i]=0}else{__classPrivateFieldGet$1(this,_CTR_counter,"f")[i]++;break}}}encrypt(plaintext){var _a,_b;const crypttext=new Uint8Array(plaintext);for(let i=0;i16){throw new TypeError("PKCS#7 padding byte out of range")}const length=data.length-padder;for(let i=0;i0&&(N&N-1)===0,"invalid kdf.N","kdf.N",N);assertArgument(r>0&&p>0,"invalid kdf","kdf",kdf);const dkLen=spelunk(data,"crypto.kdfparams.dklen:int!");assertArgument(dkLen===32,"invalid kdf.dklen","kdf.dflen",dkLen);return{name:"scrypt",salt:salt,N:N,r:r,p:p,dkLen:64}}else if(kdf.toLowerCase()==="pbkdf2"){const salt=spelunk(data,"crypto.kdfparams.salt:data!");const prf=spelunk(data,"crypto.kdfparams.prf:string!");const algorithm=prf.split("-").pop();assertArgument(algorithm==="sha256"||algorithm==="sha512","invalid kdf.pdf","kdf.pdf",prf);const count=spelunk(data,"crypto.kdfparams.c:int!");const dkLen=spelunk(data,"crypto.kdfparams.dklen:int!");assertArgument(dkLen===32,"invalid kdf.dklen","kdf.dklen",dkLen);return{name:"pbkdf2",salt:salt,count:count,dkLen:dkLen,algorithm:algorithm}}}assertArgument(false,"unsupported key-derivation function","kdf",kdf)}function decryptKeystoreJsonSync(json,_password){const data=JSON.parse(json);const password=getPassword(_password);const params=getDecryptKdfParams(data);if(params.name==="pbkdf2"){const{salt,count,dkLen,algorithm}=params;const key=pbkdf2(password,salt,count,dkLen,algorithm);return getAccount(data,key)}assert$1(params.name==="scrypt","cannot be reached","UNKNOWN_ERROR",{params:params});const{salt,N,r,p,dkLen}=params;const key=scryptSync(password,salt,N,r,p,dkLen);return getAccount(data,key)}function stall$1(duration){return new Promise(resolve=>{setTimeout(()=>{resolve()},duration)})}async function decryptKeystoreJson(json,_password,progress){const data=JSON.parse(json);const password=getPassword(_password);const params=getDecryptKdfParams(data);if(params.name==="pbkdf2"){if(progress){progress(0);await stall$1(0)}const{salt,count,dkLen,algorithm}=params;const key=pbkdf2(password,salt,count,dkLen,algorithm);if(progress){progress(1);await stall$1(0)}return getAccount(data,key)}assert$1(params.name==="scrypt","cannot be reached","UNKNOWN_ERROR",{params:params});const{salt,N,r,p,dkLen}=params;const key=await scrypt(password,salt,N,r,p,dkLen,progress);return getAccount(data,key)}function getEncryptKdfParams(options){const salt=options.salt!=null?getBytes(options.salt,"options.salt"):randomBytes(32);let N=1<<17,r=8,p=1;if(options.scrypt){if(options.scrypt.N){N=options.scrypt.N}if(options.scrypt.r){r=options.scrypt.r}if(options.scrypt.p){p=options.scrypt.p}}assertArgument(typeof N==="number"&&N>0&&Number.isSafeInteger(N)&&(BigInt(N)&BigInt(N-1))===BigInt(0),"invalid scrypt N parameter","options.N",N);assertArgument(typeof r==="number"&&r>0&&Number.isSafeInteger(r),"invalid scrypt r parameter","options.r",r);assertArgument(typeof p==="number"&&p>0&&Number.isSafeInteger(p),"invalid scrypt p parameter","options.p",p);return{name:"scrypt",dkLen:32,salt:salt,N:N,r:r,p:p}}function _encryptKeystore(key,kdf,account,options){const privateKey=getBytes(account.privateKey,"privateKey");const iv=options.iv!=null?getBytes(options.iv,"options.iv"):randomBytes(16);assertArgument(iv.length===16,"invalid options.iv length","options.iv",options.iv);const uuidRandom=options.uuid!=null?getBytes(options.uuid,"options.uuid"):randomBytes(16);assertArgument(uuidRandom.length===16,"invalid options.uuid length","options.uuid",options.iv);const derivedKey=key.slice(0,16);const macPrefix=key.slice(16,32);const aesCtr=new CTR(derivedKey,iv);const ciphertext=getBytes(aesCtr.encrypt(privateKey));const mac=keccak256(concat([macPrefix,ciphertext]));const data={address:account.address.substring(2).toLowerCase(),id:uuidV4(uuidRandom),version:3,Crypto:{cipher:"aes-128-ctr",cipherparams:{iv:hexlify(iv).substring(2)},ciphertext:hexlify(ciphertext).substring(2),kdf:"scrypt",kdfparams:{salt:hexlify(kdf.salt).substring(2),n:kdf.N,dklen:32,p:kdf.p,r:kdf.r},mac:mac.substring(2)}};if(account.mnemonic){const client=options.client!=null?options.client:`ethers/${version}`;const path=account.mnemonic.path||defaultPath$1;const locale=account.mnemonic.locale||"en";const mnemonicKey=key.slice(32,64);const entropy=getBytes(account.mnemonic.entropy,"account.mnemonic.entropy");const mnemonicIv=randomBytes(16);const mnemonicAesCtr=new CTR(mnemonicKey,mnemonicIv);const mnemonicCiphertext=getBytes(mnemonicAesCtr.encrypt(entropy));const now=new Date;const timestamp=now.getUTCFullYear()+"-"+zpad$1(now.getUTCMonth()+1,2)+"-"+zpad$1(now.getUTCDate(),2)+"T"+zpad$1(now.getUTCHours(),2)+"-"+zpad$1(now.getUTCMinutes(),2)+"-"+zpad$1(now.getUTCSeconds(),2)+".0Z";const gethFilename="UTC--"+timestamp+"--"+data.address;data["x-ethers"]={client:client,gethFilename:gethFilename,path:path,locale:locale,mnemonicCounter:hexlify(mnemonicIv).substring(2),mnemonicCiphertext:hexlify(mnemonicCiphertext).substring(2),version:"0.1"}}return JSON.stringify(data)}function encryptKeystoreJsonSync(account,password,options){if(options==null){options={}}const passwordBytes=getPassword(password);const kdf=getEncryptKdfParams(options);const key=scryptSync(passwordBytes,kdf.salt,kdf.N,kdf.r,kdf.p,64);return _encryptKeystore(getBytes(key),kdf,account,options)}async function encryptKeystoreJson(account,password,options){if(options==null){options={}}const passwordBytes=getPassword(password);const kdf=getEncryptKdfParams(options);const key=await scrypt(passwordBytes,kdf.salt,kdf.N,kdf.r,kdf.p,64,options.progressCallback);return _encryptKeystore(getBytes(key),kdf,account,options)}const defaultPath="m/44'/60'/0'/0/0";const MasterSecret=new Uint8Array([66,105,116,99,111,105,110,32,115,101,101,100]);const HardenedBit=2147483648;const N=BigInt("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141");const Nibbles="0123456789abcdef";function zpad(value,length){let result="";while(value){result=Nibbles[value%16]+result;value=Math.trunc(value/16)}while(result.length=0;i-=8){data[33+(i>>3)]=index>>24-i&255}const I=getBytes(computeHmac("sha512",chainCode,data));return{IL:I.slice(0,32),IR:I.slice(32)}}function derivePath(node,path){const components=path.split("/");assertArgument(components.length>0&&(components[0]==="m"||node.depth>0),"invalid path","path",path);if(components[0]==="m"){components.shift()}let result=node;for(let i=0;i=16&&seed.length<=64,"invalid seed","seed","[REDACTED]");const I=getBytes(computeHmac("sha512",MasterSecret,seed));const signingKey=new SigningKey(hexlify(I.slice(0,32)));return new HDNodeWallet(_guard,signingKey,"0x00000000",hexlify(I.slice(32)),"m",0,0,mnemonic,null)}static fromExtendedKey(extendedKey){const bytes=toBeArray(decodeBase58(extendedKey));assertArgument(bytes.length===82||encodeBase58Check(bytes.slice(0,78))===extendedKey,"invalid extended key","extendedKey","[ REDACTED ]");const depth=bytes[4];const parentFingerprint=hexlify(bytes.slice(5,9));const index=parseInt(hexlify(bytes.slice(9,13)).substring(2),16);const chainCode=hexlify(bytes.slice(13,45));const key=bytes.slice(45,78);switch(hexlify(bytes.slice(0,4))){case"0x0488b21e":case"0x043587cf":{const publicKey=hexlify(key);return new HDNodeVoidWallet(_guard,computeAddress(publicKey),publicKey,parentFingerprint,chainCode,null,index,depth,null)}case"0x0488ade4":case"0x04358394 ":if(key[0]!==0){break}return new HDNodeWallet(_guard,new SigningKey(key.slice(1)),parentFingerprint,chainCode,null,index,depth,null,null)}assertArgument(false,"invalid extended key prefix","extendedKey","[ REDACTED ]")}static createRandom(password,path,wordlist){if(password==null){password=""}if(path==null){path=defaultPath}if(wordlist==null){wordlist=LangEn.wordlist()}const mnemonic=Mnemonic.fromEntropy(randomBytes(16),password,wordlist);return HDNodeWallet.#fromSeed(mnemonic.computeSeed(),mnemonic).derivePath(path)}static fromMnemonic(mnemonic,path){if(!path){path=defaultPath}return HDNodeWallet.#fromSeed(mnemonic.computeSeed(),mnemonic).derivePath(path)}static fromPhrase(phrase,password,path,wordlist){if(password==null){password=""}if(path==null){path=defaultPath}if(wordlist==null){wordlist=LangEn.wordlist()}const mnemonic=Mnemonic.fromPhrase(phrase,password,wordlist);return HDNodeWallet.#fromSeed(mnemonic.computeSeed(),mnemonic).derivePath(path)}static fromSeed(seed){return HDNodeWallet.#fromSeed(seed,null)}}class HDNodeVoidWallet extends VoidSigner{publicKey;fingerprint;parentFingerprint;chainCode;path;index;depth;constructor(guard,address,publicKey,parentFingerprint,chainCode,path,index,depth,provider){super(address,provider);assertPrivate(guard,_guard,"HDNodeVoidWallet");defineProperties(this,{publicKey:publicKey});const fingerprint=dataSlice(ripemd160(sha256(publicKey)),0,4);defineProperties(this,{publicKey:publicKey,fingerprint:fingerprint,parentFingerprint:parentFingerprint,chainCode:chainCode,path:path,index:index,depth:depth})}connect(provider){return new HDNodeVoidWallet(_guard,this.address,this.publicKey,this.parentFingerprint,this.chainCode,this.path,this.index,this.depth,provider)}get extendedKey(){assert$1(this.depth<256,"Depth too deep","UNSUPPORTED_OPERATION",{operation:"extendedKey"});return encodeBase58Check(concat(["0x0488B21E",zpad(this.depth,1),this.parentFingerprint,zpad(this.index,4),this.chainCode,this.publicKey]))}hasPath(){return this.path!=null}deriveChild(_index){const index=getNumber(_index,"index");assertArgument(index<=4294967295,"invalid index","index",index);let path=this.path;if(path){path+="/"+(index&~HardenedBit);if(index&HardenedBit){path+="'"}}const{IR,IL}=ser_I(index,this.chainCode,this.publicKey,null);const Ki=SigningKey.addPoints(IL,this.publicKey,true);const address=computeAddress(Ki);return new HDNodeVoidWallet(_guard,address,Ki,this.fingerprint,hexlify(IR),path,index,this.depth+1,this.provider)}derivePath(path){return derivePath(this,path)}}function getAccountPath(_index){const index=getNumber(_index,"index");assertArgument(index>=0&&index=0&&index{setTimeout(()=>{resolve()},duration)})}class Wallet extends BaseWallet{constructor(key,provider){if(typeof key==="string"&&!key.startsWith("0x")){key="0x"+key}let signingKey=typeof key==="string"?new SigningKey(key):key;super(signingKey,provider)}connect(provider){return new Wallet(this.signingKey,provider)}async encrypt(password,progressCallback){const account={address:this.address,privateKey:this.privateKey};return await encryptKeystoreJson(account,password,{progressCallback:progressCallback})}encryptSync(password){const account={address:this.address,privateKey:this.privateKey};return encryptKeystoreJsonSync(account,password)}static#fromAccount(account){assertArgument(account,"invalid JSON wallet","json","[ REDACTED ]");if("mnemonic"in account&&account.mnemonic&&account.mnemonic.locale==="en"){const mnemonic=Mnemonic.fromEntropy(account.mnemonic.entropy);const wallet=HDNodeWallet.fromMnemonic(mnemonic,account.mnemonic.path);if(wallet.address===account.address&&wallet.privateKey===account.privateKey){return wallet}console.log("WARNING: JSON mismatch address/privateKey != mnemonic; fallback onto private key")}const wallet=new Wallet(account.privateKey);assertArgument(wallet.address===account.address,"address/privateKey mismatch","json","[ REDACTED ]");return wallet}static async fromEncryptedJson(json,password,progress){let account=null;if(isKeystoreJson(json)){account=await decryptKeystoreJson(json,password,progress)}else if(isCrowdsaleJson(json)){if(progress){progress(0);await stall(0)}account=decryptCrowdsaleJson(json,password);if(progress){progress(1);await stall(0)}}return Wallet.#fromAccount(account)}static fromEncryptedJsonSync(json,password){let account=null;if(isKeystoreJson(json)){account=decryptKeystoreJsonSync(json,password)}else if(isCrowdsaleJson(json)){account=decryptCrowdsaleJson(json,password)}else{assertArgument(false,"invalid JSON wallet","json","[ REDACTED ]")}return Wallet.#fromAccount(account)}static createRandom(provider){const wallet=HDNodeWallet.createRandom();if(provider){return wallet.connect(provider)}return wallet}static fromPhrase(phrase,provider){const wallet=HDNodeWallet.fromPhrase(phrase);if(provider){return wallet.connect(provider)}return wallet}}const Base64=")!@#$%^&*(ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_";function decodeBits(width,data){const maxValue=(1<=width){const value=accum>>bits-width;accum&=(1<{const match=accent.match(/^([a-z]*)([0-9]+)([0-9])(.*)$/);assertArgument(match!==null,"internal error parsing accents","accents",accents);let posOffset=0;const positions=decodeBits(parseInt(match[3]),match[4]);const charCode=parseInt(match[2]);const regex=new RegExp(`([${match[1]}])`,"g");words=words.replace(regex,(all,letter)=>{const rem=--positions[posOffset];if(rem===0){letter=String.fromCharCode(letter.charCodeAt(0),charCode);posOffset++}return letter})});return words.split(",")}class WordlistOwlA extends WordlistOwl{#accent;constructor(locale,data,accent,checksum){super(locale,data,checksum);this.#accent=accent}get _accent(){return this.#accent}_decodeWords(){return decodeOwlA(this._data,this._accent)}}const wordlists={en:LangEn.wordlist()};var ethers=Object.freeze({__proto__:null,version:version,decodeBytes32String:decodeBytes32String,encodeBytes32String:encodeBytes32String,AbiCoder:AbiCoder,ConstructorFragment:ConstructorFragment,ErrorFragment:ErrorFragment,EventFragment:EventFragment,Fragment:Fragment,FallbackFragment:FallbackFragment,FunctionFragment:FunctionFragment,NamedFragment:NamedFragment,ParamType:ParamType,StructFragment:StructFragment,checkResultErrors:checkResultErrors,ErrorDescription:ErrorDescription,Indexed:Indexed,Interface:Interface,LogDescription:LogDescription,Result:Result,TransactionDescription:TransactionDescription,Typed:Typed,getAddress:getAddress,getIcapAddress:getIcapAddress,getCreateAddress:getCreateAddress,getCreate2Address:getCreate2Address,isAddressable:isAddressable,isAddress:isAddress,resolveAddress:resolveAddress,ZeroAddress:ZeroAddress,WeiPerEther:WeiPerEther,MaxUint256:MaxUint256,MinInt256:MinInt256,MaxInt256:MaxInt256,N:N$1,ZeroHash:ZeroHash,EtherSymbol:EtherSymbol,MessagePrefix:MessagePrefix,BaseContract:BaseContract,Contract:Contract,ContractFactory:ContractFactory,ContractEventPayload:ContractEventPayload,ContractTransactionReceipt:ContractTransactionReceipt,ContractTransactionResponse:ContractTransactionResponse,ContractUnknownEventPayload:ContractUnknownEventPayload,EventLog:EventLog,computeHmac:computeHmac,randomBytes:randomBytes,keccak256:keccak256,ripemd160:ripemd160,sha256:sha256,sha512:sha512,pbkdf2:pbkdf2,scrypt:scrypt,scryptSync:scryptSync,lock:lock,Signature:Signature,SigningKey:SigningKey,id:id,ensNormalize:ensNormalize,isValidName:isValidName,namehash:namehash,dnsEncode:dnsEncode,hashMessage:hashMessage,verifyMessage:verifyMessage,solidityPacked:solidityPacked,solidityPackedKeccak256:solidityPackedKeccak256,solidityPackedSha256:solidityPackedSha256,TypedDataEncoder:TypedDataEncoder,verifyTypedData:verifyTypedData,getDefaultProvider:getDefaultProvider,Block:Block,FeeData:FeeData,Log:Log,TransactionReceipt:TransactionReceipt,TransactionResponse:TransactionResponse,AbstractSigner:AbstractSigner,NonceManager:NonceManager,VoidSigner:VoidSigner,AbstractProvider:AbstractProvider,FallbackProvider:FallbackProvider,JsonRpcApiProvider:JsonRpcApiProvider,JsonRpcProvider:JsonRpcProvider,JsonRpcSigner:JsonRpcSigner,BrowserProvider:BrowserProvider,AlchemyProvider:AlchemyProvider,AnkrProvider:AnkrProvider,CloudflareProvider:CloudflareProvider,EtherscanProvider:EtherscanProvider,InfuraProvider:InfuraProvider,InfuraWebSocketProvider:InfuraWebSocketProvider,PocketProvider:PocketProvider,QuickNodeProvider:QuickNodeProvider,IpcSocketProvider:IpcSocketProvider,SocketProvider:SocketProvider,WebSocketProvider:WebSocketProvider,EnsResolver:EnsResolver,Network:Network,EnsPlugin:EnsPlugin,EtherscanPlugin:EtherscanPlugin,FeeDataNetworkPlugin:FeeDataNetworkPlugin,GasCostPlugin:GasCostPlugin,NetworkPlugin:NetworkPlugin,SocketBlockSubscriber:SocketBlockSubscriber,SocketEventSubscriber:SocketEventSubscriber,SocketPendingSubscriber:SocketPendingSubscriber,SocketSubscriber:SocketSubscriber,UnmanagedSubscriber:UnmanagedSubscriber,copyRequest:copyRequest,showThrottleMessage:showThrottleMessage,accessListify:accessListify,computeAddress:computeAddress,recoverAddress:recoverAddress,Transaction:Transaction,decodeBase58:decodeBase58,encodeBase58:encodeBase58,decodeBase64:decodeBase64,encodeBase64:encodeBase64,concat:concat,dataLength:dataLength,dataSlice:dataSlice,getBytes:getBytes,getBytesCopy:getBytesCopy,hexlify:hexlify,isHexString:isHexString,isBytesLike:isBytesLike,stripZerosLeft:stripZerosLeft,zeroPadBytes:zeroPadBytes,zeroPadValue:zeroPadValue,defineProperties:defineProperties,resolveProperties:resolveProperties,assert:assert$1,assertArgument:assertArgument,assertArgumentCount:assertArgumentCount,assertNormalize:assertNormalize,assertPrivate:assertPrivate,makeError:makeError,isCallException:isCallException,isError:isError,EventPayload:EventPayload,FetchRequest:FetchRequest,FetchResponse:FetchResponse,FetchCancelSignal:FetchCancelSignal,FixedNumber:FixedNumber,getBigInt:getBigInt,getNumber:getNumber,getUint:getUint,toBeArray:toBeArray,toBigInt:toBigInt,toBeHex:toBeHex,toNumber:toNumber,toQuantity:toQuantity,fromTwos:fromTwos,toTwos:toTwos,mask:mask,formatEther:formatEther,parseEther:parseEther,formatUnits:formatUnits,parseUnits:parseUnits,toUtf8Bytes:toUtf8Bytes,toUtf8CodePoints:toUtf8CodePoints,toUtf8String:toUtf8String,Utf8ErrorFuncs:Utf8ErrorFuncs,decodeRlp:decodeRlp,encodeRlp:encodeRlp,uuidV4:uuidV4,Mnemonic:Mnemonic,BaseWallet:BaseWallet,HDNodeWallet:HDNodeWallet,HDNodeVoidWallet:HDNodeVoidWallet,Wallet:Wallet,defaultPath:defaultPath,getAccountPath:getAccountPath,getIndexedAccountPath:getIndexedAccountPath,isCrowdsaleJson:isCrowdsaleJson,isKeystoreJson:isKeystoreJson,decryptCrowdsaleJson:decryptCrowdsaleJson,decryptKeystoreJsonSync:decryptKeystoreJsonSync,decryptKeystoreJson:decryptKeystoreJson,encryptKeystoreJson:encryptKeystoreJson,encryptKeystoreJsonSync:encryptKeystoreJsonSync,Wordlist:Wordlist,LangEn:LangEn,WordlistOwl:WordlistOwl,WordlistOwlA:WordlistOwlA,wordlists:wordlists});export{AbiCoder,AbstractProvider,AbstractSigner,AlchemyProvider,AnkrProvider,BaseContract,BaseWallet,Block,BrowserProvider,CloudflareProvider,ConstructorFragment,Contract,ContractEventPayload,ContractFactory,ContractTransactionReceipt,ContractTransactionResponse,ContractUnknownEventPayload,EnsPlugin,EnsResolver,ErrorDescription,ErrorFragment,EtherSymbol,EtherscanPlugin,EtherscanProvider,EventFragment,EventLog,EventPayload,FallbackFragment,FallbackProvider,FeeData,FeeDataNetworkPlugin,FetchCancelSignal,FetchRequest,FetchResponse,FixedNumber,Fragment,FunctionFragment,GasCostPlugin,HDNodeVoidWallet,HDNodeWallet,Indexed,InfuraProvider,InfuraWebSocketProvider,Interface,IpcSocketProvider,JsonRpcApiProvider,JsonRpcProvider,JsonRpcSigner,LangEn,Log,LogDescription,MaxInt256,MaxUint256,MessagePrefix,MinInt256,Mnemonic,N$1 as N,NamedFragment,Network,NetworkPlugin,NonceManager,ParamType,PocketProvider,QuickNodeProvider,Result,Signature,SigningKey,SocketBlockSubscriber,SocketEventSubscriber,SocketPendingSubscriber,SocketProvider,SocketSubscriber,StructFragment,Transaction,TransactionDescription,TransactionReceipt,TransactionResponse,Typed,TypedDataEncoder,UnmanagedSubscriber,Utf8ErrorFuncs,VoidSigner,Wallet,WebSocketProvider,WeiPerEther,Wordlist,WordlistOwl,WordlistOwlA,ZeroAddress,ZeroHash,accessListify,assert$1 as assert,assertArgument,assertArgumentCount,assertNormalize,assertPrivate,checkResultErrors,computeAddress,computeHmac,concat,copyRequest,dataLength,dataSlice,decodeBase58,decodeBase64,decodeBytes32String,decodeRlp,decryptCrowdsaleJson,decryptKeystoreJson,decryptKeystoreJsonSync,defaultPath,defineProperties,dnsEncode,encodeBase58,encodeBase64,encodeBytes32String,encodeRlp,encryptKeystoreJson,encryptKeystoreJsonSync,ensNormalize,ethers,formatEther,formatUnits,fromTwos,getAccountPath,getAddress,getBigInt,getBytes,getBytesCopy,getCreate2Address,getCreateAddress,getDefaultProvider,getIcapAddress,getIndexedAccountPath,getNumber,getUint,hashMessage,hexlify,id,isAddress,isAddressable,isBytesLike,isCallException,isCrowdsaleJson,isError,isHexString,isKeystoreJson,isValidName,keccak256,lock,makeError,mask,namehash,parseEther,parseUnits,pbkdf2,randomBytes,recoverAddress,resolveAddress,resolveProperties,ripemd160,scrypt,scryptSync,sha256,sha512,showThrottleMessage,solidityPacked,solidityPackedKeccak256,solidityPackedSha256,stripZerosLeft,toBeArray,toBeHex,toBigInt,toNumber,toQuantity,toTwos,toUtf8Bytes,toUtf8CodePoints,toUtf8String,uuidV4,verifyMessage,verifyTypedData,version,wordlists,zeroPadBytes,zeroPadValue}; \ No newline at end of file diff --git a/assets/javascripts/images.js b/assets/javascripts/images.js new file mode 100644 index 000000000..3d124307d --- /dev/null +++ b/assets/javascripts/images.js @@ -0,0 +1,8 @@ +var images = document.getElementsByTagName('img'); +for (var i = 0, l = images.length; i < l; ++i) { + const im = images[i]; + if (im.classList.contains("allow-zoom")) { + im.title = 'Click to enlarge'; + im.outerHTML = '' + im.outerHTML + ''; + } +}; \ No newline at end of file diff --git a/assets/javascripts/links.js b/assets/javascripts/links.js new file mode 100644 index 000000000..ab8cb28d6 --- /dev/null +++ b/assets/javascripts/links.js @@ -0,0 +1,26 @@ +// External links +var links = document.getElementsByTagName('a'); +for (var i = 0, l = links.length; i < l; ++i) { + const lk = links[i]; + if (lk.hostname != undefined && lk.hostname !== location.hostname) { + lk.setAttribute("target", "_blank"); + lk.setAttribute("rel", "noopener noreferrer"); + } +}; + +// Tutorial comments in source code +var comments = document.getElementsByClassName('c1'); +var h3s = document.getElementsByTagName('h3'); +const re = /^\/\/ ([0-9]+)\./; +for (var i = 0, l = comments.length; i < l; ++i) { + const c = comments[i]; + // Find all code comments starting with a number and a dot + const r = c.innerText.match(re); + if (r) { + // Locate target header + const target = [...h3s].find((e) => e.id.startsWith(`${r[1]}-`)); + // Add link + if (target) + c.outerHTML = `` + c.outerHTML + ''; + } +} \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.ar.min.js b/assets/javascripts/lunr/min/lunr.ar.min.js new file mode 100644 index 000000000..248ddc5d1 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.ar.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ar=function(){this.pipeline.reset(),this.pipeline.add(e.ar.trimmer,e.ar.stopWordFilter,e.ar.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ar.stemmer))},e.ar.wordCharacters="ء-ٛٱـ",e.ar.trimmer=e.trimmerSupport.generateTrimmer(e.ar.wordCharacters),e.Pipeline.registerFunction(e.ar.trimmer,"trimmer-ar"),e.ar.stemmer=function(){var e=this;return e.result=!1,e.preRemoved=!1,e.sufRemoved=!1,e.pre={pre1:"ف ك ب و س ل ن ا ي ت",pre2:"ال لل",pre3:"بال وال فال تال كال ولل",pre4:"فبال كبال وبال وكال"},e.suf={suf1:"ه ك ت ن ا ي",suf2:"نك نه ها وك يا اه ون ين تن تم نا وا ان كم كن ني نن ما هم هن تك ته ات يه",suf3:"تين كهم نيه نهم ونه وها يهم ونا ونك وني وهم تكم تنا تها تني تهم كما كها ناه نكم هنا تان يها",suf4:"كموه ناها ونني ونهم تكما تموه تكاه كماه ناكم ناهم نيها وننا"},e.patterns=JSON.parse('{"pt43":[{"pt":[{"c":"ا","l":1}]},{"pt":[{"c":"ا,ت,ن,ي","l":0}],"mPt":[{"c":"ف","l":0,"m":1},{"c":"ع","l":1,"m":2},{"c":"ل","l":2,"m":3}]},{"pt":[{"c":"و","l":2}],"mPt":[{"c":"ف","l":0,"m":0},{"c":"ع","l":1,"m":1},{"c":"ل","l":2,"m":3}]},{"pt":[{"c":"ا","l":2}]},{"pt":[{"c":"ي","l":2}],"mPt":[{"c":"ف","l":0,"m":0},{"c":"ع","l":1,"m":1},{"c":"ا","l":2},{"c":"ل","l":3,"m":3}]},{"pt":[{"c":"م","l":0}]}],"pt53":[{"pt":[{"c":"ت","l":0},{"c":"ا","l":2}]},{"pt":[{"c":"ا,ن,ت,ي","l":0},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ت","l":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":0},{"c":"ا","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ع","l":2,"m":3},{"c":"ل","l":3,"m":4},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":0},{"c":"ا","l":3}],"mPt":[{"c":"ف","l":0,"m":1},{"c":"ع","l":1,"m":2},{"c":"ل","l":2,"m":4}]},{"pt":[{"c":"ا","l":3},{"c":"ن","l":4}]},{"pt":[{"c":"ت","l":0},{"c":"ي","l":3}]},{"pt":[{"c":"م","l":0},{"c":"و","l":3}]},{"pt":[{"c":"ا","l":1},{"c":"و","l":3}]},{"pt":[{"c":"و","l":1},{"c":"ا","l":2}]},{"pt":[{"c":"م","l":0},{"c":"ا","l":3}]},{"pt":[{"c":"م","l":0},{"c":"ي","l":3}]},{"pt":[{"c":"ا","l":2},{"c":"ن","l":3}]},{"pt":[{"c":"م","l":0},{"c":"ن","l":1}],"mPt":[{"c":"ا","l":0},{"c":"ن","l":1},{"c":"ف","l":2,"m":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"م","l":0},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ت","l":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"م","l":0},{"c":"ا","l":2}]},{"pt":[{"c":"م","l":1},{"c":"ا","l":3}]},{"pt":[{"c":"ي,ت,ا,ن","l":0},{"c":"ت","l":1}],"mPt":[{"c":"ف","l":0,"m":2},{"c":"ع","l":1,"m":3},{"c":"ا","l":2},{"c":"ل","l":3,"m":4}]},{"pt":[{"c":"ت,ي,ا,ن","l":0},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ت","l":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":2},{"c":"ي","l":3}]},{"pt":[{"c":"ا,ي,ت,ن","l":0},{"c":"ن","l":1}],"mPt":[{"c":"ا","l":0},{"c":"ن","l":1},{"c":"ف","l":2,"m":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":3},{"c":"ء","l":4}]}],"pt63":[{"pt":[{"c":"ا","l":0},{"c":"ت","l":2},{"c":"ا","l":4}]},{"pt":[{"c":"ا,ت,ن,ي","l":0},{"c":"س","l":1},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"س","l":1},{"c":"ت","l":2},{"c":"ف","l":3,"m":3},{"c":"ع","l":4,"m":4},{"c":"ا","l":5},{"c":"ل","l":6,"m":5}]},{"pt":[{"c":"ا,ن,ت,ي","l":0},{"c":"و","l":3}]},{"pt":[{"c":"م","l":0},{"c":"س","l":1},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"س","l":1},{"c":"ت","l":2},{"c":"ف","l":3,"m":3},{"c":"ع","l":4,"m":4},{"c":"ا","l":5},{"c":"ل","l":6,"m":5}]},{"pt":[{"c":"ي","l":1},{"c":"ي","l":3},{"c":"ا","l":4},{"c":"ء","l":5}]},{"pt":[{"c":"ا","l":0},{"c":"ن","l":1},{"c":"ا","l":4}]}],"pt54":[{"pt":[{"c":"ت","l":0}]},{"pt":[{"c":"ا,ي,ت,ن","l":0}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ع","l":2,"m":2},{"c":"ل","l":3,"m":3},{"c":"ر","l":4,"m":4},{"c":"ا","l":5},{"c":"ر","l":6,"m":4}]},{"pt":[{"c":"م","l":0}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ع","l":2,"m":2},{"c":"ل","l":3,"m":3},{"c":"ر","l":4,"m":4},{"c":"ا","l":5},{"c":"ر","l":6,"m":4}]},{"pt":[{"c":"ا","l":2}]},{"pt":[{"c":"ا","l":0},{"c":"ن","l":2}]}],"pt64":[{"pt":[{"c":"ا","l":0},{"c":"ا","l":4}]},{"pt":[{"c":"م","l":0},{"c":"ت","l":1}]}],"pt73":[{"pt":[{"c":"ا","l":0},{"c":"س","l":1},{"c":"ت","l":2},{"c":"ا","l":5}]}],"pt75":[{"pt":[{"c":"ا","l":0},{"c":"ا","l":5}]}]}'),e.execArray=["cleanWord","removeDiacritics","cleanAlef","removeStopWords","normalizeHamzaAndAlef","removeStartWaw","removePre432","removeEndTaa","wordCheck"],e.stem=function(){var r=0;for(e.result=!1,e.preRemoved=!1,e.sufRemoved=!1;r=0)return!0},e.normalizeHamzaAndAlef=function(){return e.word=e.word.replace("ؤ","ء"),e.word=e.word.replace("ئ","ء"),e.word=e.word.replace(/([\u0627])\1+/gi,"ا"),!1},e.removeEndTaa=function(){return!(e.word.length>2)||(e.word=e.word.replace(/[\u0627]$/,""),e.word=e.word.replace("ة",""),!1)},e.removeStartWaw=function(){return e.word.length>3&&"و"==e.word[0]&&"و"==e.word[1]&&(e.word=e.word.slice(1)),!1},e.removePre432=function(){var r=e.word;if(e.word.length>=7){var t=new RegExp("^("+e.pre.pre4.split(" ").join("|")+")");e.word=e.word.replace(t,"")}if(e.word==r&&e.word.length>=6){var c=new RegExp("^("+e.pre.pre3.split(" ").join("|")+")");e.word=e.word.replace(c,"")}if(e.word==r&&e.word.length>=5){var l=new RegExp("^("+e.pre.pre2.split(" ").join("|")+")");e.word=e.word.replace(l,"")}return r!=e.word&&(e.preRemoved=!0),!1},e.patternCheck=function(r){for(var t=0;t3){var t=new RegExp("^("+e.pre.pre1.split(" ").join("|")+")");e.word=e.word.replace(t,"")}return r!=e.word&&(e.preRemoved=!0),!1},e.removeSuf1=function(){var r=e.word;if(0==e.sufRemoved&&e.word.length>3){var t=new RegExp("("+e.suf.suf1.split(" ").join("|")+")$");e.word=e.word.replace(t,"")}return r!=e.word&&(e.sufRemoved=!0),!1},e.removeSuf432=function(){var r=e.word;if(e.word.length>=6){var t=new RegExp("("+e.suf.suf4.split(" ").join("|")+")$");e.word=e.word.replace(t,"")}if(e.word==r&&e.word.length>=5){var c=new RegExp("("+e.suf.suf3.split(" ").join("|")+")$");e.word=e.word.replace(c,"")}if(e.word==r&&e.word.length>=4){var l=new RegExp("("+e.suf.suf2.split(" ").join("|")+")$");e.word=e.word.replace(l,"")}return r!=e.word&&(e.sufRemoved=!0),!1},e.wordCheck=function(){for(var r=(e.word,[e.removeSuf432,e.removeSuf1,e.removePre1]),t=0,c=!1;e.word.length>=7&&!e.result&&t=f.limit)return;f.cursor++}for(;!f.out_grouping(w,97,248);){if(f.cursor>=f.limit)return;f.cursor++}d=f.cursor,d=d&&(r=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,e=f.find_among_b(c,32),f.limit_backward=r,e))switch(f.bra=f.cursor,e){case 1:f.slice_del();break;case 2:f.in_grouping_b(p,97,229)&&f.slice_del()}}function t(){var e,r=f.limit-f.cursor;f.cursor>=d&&(e=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,f.find_among_b(l,4)?(f.bra=f.cursor,f.limit_backward=e,f.cursor=f.limit-r,f.cursor>f.limit_backward&&(f.cursor--,f.bra=f.cursor,f.slice_del())):f.limit_backward=e)}function s(){var e,r,i,n=f.limit-f.cursor;if(f.ket=f.cursor,f.eq_s_b(2,"st")&&(f.bra=f.cursor,f.eq_s_b(2,"ig")&&f.slice_del()),f.cursor=f.limit-n,f.cursor>=d&&(r=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,e=f.find_among_b(m,5),f.limit_backward=r,e))switch(f.bra=f.cursor,e){case 1:f.slice_del(),i=f.limit-f.cursor,t(),f.cursor=f.limit-i;break;case 2:f.slice_from("løs")}}function o(){var e;f.cursor>=d&&(e=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,f.out_grouping_b(w,97,248)?(f.bra=f.cursor,u=f.slice_to(u),f.limit_backward=e,f.eq_v_b(u)&&f.slice_del()):f.limit_backward=e)}var a,d,u,c=[new r("hed",-1,1),new r("ethed",0,1),new r("ered",-1,1),new r("e",-1,1),new r("erede",3,1),new r("ende",3,1),new r("erende",5,1),new r("ene",3,1),new r("erne",3,1),new r("ere",3,1),new r("en",-1,1),new r("heden",10,1),new r("eren",10,1),new r("er",-1,1),new r("heder",13,1),new r("erer",13,1),new r("s",-1,2),new r("heds",16,1),new r("es",16,1),new r("endes",18,1),new r("erendes",19,1),new r("enes",18,1),new r("ernes",18,1),new r("eres",18,1),new r("ens",16,1),new r("hedens",24,1),new r("erens",24,1),new r("ers",16,1),new r("ets",16,1),new r("erets",28,1),new r("et",-1,1),new r("eret",30,1)],l=[new r("gd",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1)],m=[new r("ig",-1,1),new r("lig",0,1),new r("elig",1,1),new r("els",-1,1),new r("løst",-1,2)],w=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],p=[239,254,42,3,0,0,0,0,0,0,0,0,0,0,0,0,16],f=new i;this.setCurrent=function(e){f.setCurrent(e)},this.getCurrent=function(){return f.getCurrent()},this.stem=function(){var r=f.cursor;return e(),f.limit_backward=r,f.cursor=f.limit,n(),f.cursor=f.limit,t(),f.cursor=f.limit,s(),f.cursor=f.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.da.stemmer,"stemmer-da"),e.da.stopWordFilter=e.generateStopWordFilter("ad af alle alt anden at blev blive bliver da de dem den denne der deres det dette dig din disse dog du efter eller en end er et for fra ham han hans har havde have hende hendes her hos hun hvad hvis hvor i ikke ind jeg jer jo kunne man mange med meget men mig min mine mit mod ned noget nogle nu når og også om op os over på selv sig sin sine sit skal skulle som sådan thi til ud under var vi vil ville vor være været".split(" ")),e.Pipeline.registerFunction(e.da.stopWordFilter,"stopWordFilter-da")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.de.min.js b/assets/javascripts/lunr/min/lunr.de.min.js new file mode 100644 index 000000000..f3b5c108c --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.de.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `German` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.de=function(){this.pipeline.reset(),this.pipeline.add(e.de.trimmer,e.de.stopWordFilter,e.de.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.de.stemmer))},e.de.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.de.trimmer=e.trimmerSupport.generateTrimmer(e.de.wordCharacters),e.Pipeline.registerFunction(e.de.trimmer,"trimmer-de"),e.de.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(e,r,n){return!(!v.eq_s(1,e)||(v.ket=v.cursor,!v.in_grouping(p,97,252)))&&(v.slice_from(r),v.cursor=n,!0)}function i(){for(var r,n,i,s,t=v.cursor;;)if(r=v.cursor,v.bra=r,v.eq_s(1,"ß"))v.ket=v.cursor,v.slice_from("ss");else{if(r>=v.limit)break;v.cursor=r+1}for(v.cursor=t;;)for(n=v.cursor;;){if(i=v.cursor,v.in_grouping(p,97,252)){if(s=v.cursor,v.bra=s,e("u","U",i))break;if(v.cursor=s,e("y","Y",i))break}if(i>=v.limit)return void(v.cursor=n);v.cursor=i+1}}function s(){for(;!v.in_grouping(p,97,252);){if(v.cursor>=v.limit)return!0;v.cursor++}for(;!v.out_grouping(p,97,252);){if(v.cursor>=v.limit)return!0;v.cursor++}return!1}function t(){m=v.limit,l=m;var e=v.cursor+3;0<=e&&e<=v.limit&&(d=e,s()||(m=v.cursor,m=v.limit)return;v.cursor++}}}function c(){return m<=v.cursor}function u(){return l<=v.cursor}function a(){var e,r,n,i,s=v.limit-v.cursor;if(v.ket=v.cursor,(e=v.find_among_b(w,7))&&(v.bra=v.cursor,c()))switch(e){case 1:v.slice_del();break;case 2:v.slice_del(),v.ket=v.cursor,v.eq_s_b(1,"s")&&(v.bra=v.cursor,v.eq_s_b(3,"nis")&&v.slice_del());break;case 3:v.in_grouping_b(g,98,116)&&v.slice_del()}if(v.cursor=v.limit-s,v.ket=v.cursor,(e=v.find_among_b(f,4))&&(v.bra=v.cursor,c()))switch(e){case 1:v.slice_del();break;case 2:if(v.in_grouping_b(k,98,116)){var t=v.cursor-3;v.limit_backward<=t&&t<=v.limit&&(v.cursor=t,v.slice_del())}}if(v.cursor=v.limit-s,v.ket=v.cursor,(e=v.find_among_b(_,8))&&(v.bra=v.cursor,u()))switch(e){case 1:v.slice_del(),v.ket=v.cursor,v.eq_s_b(2,"ig")&&(v.bra=v.cursor,r=v.limit-v.cursor,v.eq_s_b(1,"e")||(v.cursor=v.limit-r,u()&&v.slice_del()));break;case 2:n=v.limit-v.cursor,v.eq_s_b(1,"e")||(v.cursor=v.limit-n,v.slice_del());break;case 3:if(v.slice_del(),v.ket=v.cursor,i=v.limit-v.cursor,!v.eq_s_b(2,"er")&&(v.cursor=v.limit-i,!v.eq_s_b(2,"en")))break;v.bra=v.cursor,c()&&v.slice_del();break;case 4:v.slice_del(),v.ket=v.cursor,e=v.find_among_b(b,2),e&&(v.bra=v.cursor,u()&&1==e&&v.slice_del())}}var d,l,m,h=[new r("",-1,6),new r("U",0,2),new r("Y",0,1),new r("ä",0,3),new r("ö",0,4),new r("ü",0,5)],w=[new r("e",-1,2),new r("em",-1,1),new r("en",-1,2),new r("ern",-1,1),new r("er",-1,1),new r("s",-1,3),new r("es",5,2)],f=[new r("en",-1,1),new r("er",-1,1),new r("st",-1,2),new r("est",2,1)],b=[new r("ig",-1,1),new r("lich",-1,1)],_=[new r("end",-1,1),new r("ig",-1,2),new r("ung",-1,1),new r("lich",-1,3),new r("isch",-1,2),new r("ik",-1,2),new r("heit",-1,3),new r("keit",-1,4)],p=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32,8],g=[117,30,5],k=[117,30,4],v=new n;this.setCurrent=function(e){v.setCurrent(e)},this.getCurrent=function(){return v.getCurrent()},this.stem=function(){var e=v.cursor;return i(),v.cursor=e,t(),v.limit_backward=e,v.cursor=v.limit,a(),v.cursor=v.limit_backward,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.de.stemmer,"stemmer-de"),e.de.stopWordFilter=e.generateStopWordFilter("aber alle allem allen aller alles als also am an ander andere anderem anderen anderer anderes anderm andern anderr anders auch auf aus bei bin bis bist da damit dann das dasselbe dazu daß dein deine deinem deinen deiner deines dem demselben den denn denselben der derer derselbe derselben des desselben dessen dich die dies diese dieselbe dieselben diesem diesen dieser dieses dir doch dort du durch ein eine einem einen einer eines einig einige einigem einigen einiger einiges einmal er es etwas euch euer eure eurem euren eurer eures für gegen gewesen hab habe haben hat hatte hatten hier hin hinter ich ihm ihn ihnen ihr ihre ihrem ihren ihrer ihres im in indem ins ist jede jedem jeden jeder jedes jene jenem jenen jener jenes jetzt kann kein keine keinem keinen keiner keines können könnte machen man manche manchem manchen mancher manches mein meine meinem meinen meiner meines mich mir mit muss musste nach nicht nichts noch nun nur ob oder ohne sehr sein seine seinem seinen seiner seines selbst sich sie sind so solche solchem solchen solcher solches soll sollte sondern sonst um und uns unse unsem unsen unser unses unter viel vom von vor war waren warst was weg weil weiter welche welchem welchen welcher welches wenn werde werden wie wieder will wir wird wirst wo wollen wollte während würde würden zu zum zur zwar zwischen über".split(" ")),e.Pipeline.registerFunction(e.de.stopWordFilter,"stopWordFilter-de")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.du.min.js b/assets/javascripts/lunr/min/lunr.du.min.js new file mode 100644 index 000000000..49a0f3f0a --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.du.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Dutch` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");console.warn('[Lunr Languages] Please use the "nl" instead of the "du". The "nl" code is the standard code for Dutch language, and "du" will be removed in the next major versions.'),e.du=function(){this.pipeline.reset(),this.pipeline.add(e.du.trimmer,e.du.stopWordFilter,e.du.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.du.stemmer))},e.du.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.du.trimmer=e.trimmerSupport.generateTrimmer(e.du.wordCharacters),e.Pipeline.registerFunction(e.du.trimmer,"trimmer-du"),e.du.stemmer=function(){var r=e.stemmerSupport.Among,i=e.stemmerSupport.SnowballProgram,n=new function(){function e(){for(var e,r,i,o=C.cursor;;){if(C.bra=C.cursor,e=C.find_among(b,11))switch(C.ket=C.cursor,e){case 1:C.slice_from("a");continue;case 2:C.slice_from("e");continue;case 3:C.slice_from("i");continue;case 4:C.slice_from("o");continue;case 5:C.slice_from("u");continue;case 6:if(C.cursor>=C.limit)break;C.cursor++;continue}break}for(C.cursor=o,C.bra=o,C.eq_s(1,"y")?(C.ket=C.cursor,C.slice_from("Y")):C.cursor=o;;)if(r=C.cursor,C.in_grouping(q,97,232)){if(i=C.cursor,C.bra=i,C.eq_s(1,"i"))C.ket=C.cursor,C.in_grouping(q,97,232)&&(C.slice_from("I"),C.cursor=r);else if(C.cursor=i,C.eq_s(1,"y"))C.ket=C.cursor,C.slice_from("Y"),C.cursor=r;else if(n(r))break}else if(n(r))break}function n(e){return C.cursor=e,e>=C.limit||(C.cursor++,!1)}function o(){_=C.limit,f=_,t()||(_=C.cursor,_<3&&(_=3),t()||(f=C.cursor))}function t(){for(;!C.in_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}for(;!C.out_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}return!1}function s(){for(var e;;)if(C.bra=C.cursor,e=C.find_among(p,3))switch(C.ket=C.cursor,e){case 1:C.slice_from("y");break;case 2:C.slice_from("i");break;case 3:if(C.cursor>=C.limit)return;C.cursor++}}function u(){return _<=C.cursor}function c(){return f<=C.cursor}function a(){var e=C.limit-C.cursor;C.find_among_b(g,3)&&(C.cursor=C.limit-e,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del()))}function l(){var e;w=!1,C.ket=C.cursor,C.eq_s_b(1,"e")&&(C.bra=C.cursor,u()&&(e=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-e,C.slice_del(),w=!0,a())))}function m(){var e;u()&&(e=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-e,C.eq_s_b(3,"gem")||(C.cursor=C.limit-e,C.slice_del(),a())))}function d(){var e,r,i,n,o,t,s=C.limit-C.cursor;if(C.ket=C.cursor,e=C.find_among_b(h,5))switch(C.bra=C.cursor,e){case 1:u()&&C.slice_from("heid");break;case 2:m();break;case 3:u()&&C.out_grouping_b(z,97,232)&&C.slice_del()}if(C.cursor=C.limit-s,l(),C.cursor=C.limit-s,C.ket=C.cursor,C.eq_s_b(4,"heid")&&(C.bra=C.cursor,c()&&(r=C.limit-C.cursor,C.eq_s_b(1,"c")||(C.cursor=C.limit-r,C.slice_del(),C.ket=C.cursor,C.eq_s_b(2,"en")&&(C.bra=C.cursor,m())))),C.cursor=C.limit-s,C.ket=C.cursor,e=C.find_among_b(k,6))switch(C.bra=C.cursor,e){case 1:if(c()){if(C.slice_del(),i=C.limit-C.cursor,C.ket=C.cursor,C.eq_s_b(2,"ig")&&(C.bra=C.cursor,c()&&(n=C.limit-C.cursor,!C.eq_s_b(1,"e")))){C.cursor=C.limit-n,C.slice_del();break}C.cursor=C.limit-i,a()}break;case 2:c()&&(o=C.limit-C.cursor,C.eq_s_b(1,"e")||(C.cursor=C.limit-o,C.slice_del()));break;case 3:c()&&(C.slice_del(),l());break;case 4:c()&&C.slice_del();break;case 5:c()&&w&&C.slice_del()}C.cursor=C.limit-s,C.out_grouping_b(j,73,232)&&(t=C.limit-C.cursor,C.find_among_b(v,4)&&C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-t,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del())))}var f,_,w,b=[new r("",-1,6),new r("á",0,1),new r("ä",0,1),new r("é",0,2),new r("ë",0,2),new r("í",0,3),new r("ï",0,3),new r("ó",0,4),new r("ö",0,4),new r("ú",0,5),new r("ü",0,5)],p=[new r("",-1,3),new r("I",0,2),new r("Y",0,1)],g=[new r("dd",-1,-1),new r("kk",-1,-1),new r("tt",-1,-1)],h=[new r("ene",-1,2),new r("se",-1,3),new r("en",-1,2),new r("heden",2,1),new r("s",-1,3)],k=[new r("end",-1,1),new r("ig",-1,2),new r("ing",-1,1),new r("lijk",-1,3),new r("baar",-1,4),new r("bar",-1,5)],v=[new r("aa",-1,-1),new r("ee",-1,-1),new r("oo",-1,-1),new r("uu",-1,-1)],q=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],j=[1,0,0,17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],z=[17,67,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],C=new i;this.setCurrent=function(e){C.setCurrent(e)},this.getCurrent=function(){return C.getCurrent()},this.stem=function(){var r=C.cursor;return e(),C.cursor=r,o(),C.limit_backward=r,C.cursor=C.limit,d(),C.cursor=C.limit_backward,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.du.stemmer,"stemmer-du"),e.du.stopWordFilter=e.generateStopWordFilter(" aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou".split(" ")),e.Pipeline.registerFunction(e.du.stopWordFilter,"stopWordFilter-du")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.es.min.js b/assets/javascripts/lunr/min/lunr.es.min.js new file mode 100644 index 000000000..2989d3426 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.es.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Spanish` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,s){"function"==typeof define&&define.amd?define(s):"object"==typeof exports?module.exports=s():s()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.es=function(){this.pipeline.reset(),this.pipeline.add(e.es.trimmer,e.es.stopWordFilter,e.es.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.es.stemmer))},e.es.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.es.trimmer=e.trimmerSupport.generateTrimmer(e.es.wordCharacters),e.Pipeline.registerFunction(e.es.trimmer,"trimmer-es"),e.es.stemmer=function(){var s=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,n=new function(){function e(){if(A.out_grouping(x,97,252)){for(;!A.in_grouping(x,97,252);){if(A.cursor>=A.limit)return!0;A.cursor++}return!1}return!0}function n(){if(A.in_grouping(x,97,252)){var s=A.cursor;if(e()){if(A.cursor=s,!A.in_grouping(x,97,252))return!0;for(;!A.out_grouping(x,97,252);){if(A.cursor>=A.limit)return!0;A.cursor++}}return!1}return!0}function i(){var s,r=A.cursor;if(n()){if(A.cursor=r,!A.out_grouping(x,97,252))return;if(s=A.cursor,e()){if(A.cursor=s,!A.in_grouping(x,97,252)||A.cursor>=A.limit)return;A.cursor++}}g=A.cursor}function a(){for(;!A.in_grouping(x,97,252);){if(A.cursor>=A.limit)return!1;A.cursor++}for(;!A.out_grouping(x,97,252);){if(A.cursor>=A.limit)return!1;A.cursor++}return!0}function t(){var e=A.cursor;g=A.limit,p=g,v=g,i(),A.cursor=e,a()&&(p=A.cursor,a()&&(v=A.cursor))}function o(){for(var e;;){if(A.bra=A.cursor,e=A.find_among(k,6))switch(A.ket=A.cursor,e){case 1:A.slice_from("a");continue;case 2:A.slice_from("e");continue;case 3:A.slice_from("i");continue;case 4:A.slice_from("o");continue;case 5:A.slice_from("u");continue;case 6:if(A.cursor>=A.limit)break;A.cursor++;continue}break}}function u(){return g<=A.cursor}function w(){return p<=A.cursor}function c(){return v<=A.cursor}function m(){var e;if(A.ket=A.cursor,A.find_among_b(y,13)&&(A.bra=A.cursor,(e=A.find_among_b(q,11))&&u()))switch(e){case 1:A.bra=A.cursor,A.slice_from("iendo");break;case 2:A.bra=A.cursor,A.slice_from("ando");break;case 3:A.bra=A.cursor,A.slice_from("ar");break;case 4:A.bra=A.cursor,A.slice_from("er");break;case 5:A.bra=A.cursor,A.slice_from("ir");break;case 6:A.slice_del();break;case 7:A.eq_s_b(1,"u")&&A.slice_del()}}function l(e,s){if(!c())return!0;A.slice_del(),A.ket=A.cursor;var r=A.find_among_b(e,s);return r&&(A.bra=A.cursor,1==r&&c()&&A.slice_del()),!1}function d(e){return!c()||(A.slice_del(),A.ket=A.cursor,A.eq_s_b(2,e)&&(A.bra=A.cursor,c()&&A.slice_del()),!1)}function b(){var e;if(A.ket=A.cursor,e=A.find_among_b(S,46)){switch(A.bra=A.cursor,e){case 1:if(!c())return!1;A.slice_del();break;case 2:if(d("ic"))return!1;break;case 3:if(!c())return!1;A.slice_from("log");break;case 4:if(!c())return!1;A.slice_from("u");break;case 5:if(!c())return!1;A.slice_from("ente");break;case 6:if(!w())return!1;A.slice_del(),A.ket=A.cursor,e=A.find_among_b(C,4),e&&(A.bra=A.cursor,c()&&(A.slice_del(),1==e&&(A.ket=A.cursor,A.eq_s_b(2,"at")&&(A.bra=A.cursor,c()&&A.slice_del()))));break;case 7:if(l(P,3))return!1;break;case 8:if(l(F,3))return!1;break;case 9:if(d("at"))return!1}return!0}return!1}function f(){var e,s;if(A.cursor>=g&&(s=A.limit_backward,A.limit_backward=g,A.ket=A.cursor,e=A.find_among_b(W,12),A.limit_backward=s,e)){if(A.bra=A.cursor,1==e){if(!A.eq_s_b(1,"u"))return!1;A.slice_del()}return!0}return!1}function _(){var e,s,r,n;if(A.cursor>=g&&(s=A.limit_backward,A.limit_backward=g,A.ket=A.cursor,e=A.find_among_b(L,96),A.limit_backward=s,e))switch(A.bra=A.cursor,e){case 1:r=A.limit-A.cursor,A.eq_s_b(1,"u")?(n=A.limit-A.cursor,A.eq_s_b(1,"g")?A.cursor=A.limit-n:A.cursor=A.limit-r):A.cursor=A.limit-r,A.bra=A.cursor;case 2:A.slice_del()}}function h(){var e,s;if(A.ket=A.cursor,e=A.find_among_b(z,8))switch(A.bra=A.cursor,e){case 1:u()&&A.slice_del();break;case 2:u()&&(A.slice_del(),A.ket=A.cursor,A.eq_s_b(1,"u")&&(A.bra=A.cursor,s=A.limit-A.cursor,A.eq_s_b(1,"g")&&(A.cursor=A.limit-s,u()&&A.slice_del())))}}var v,p,g,k=[new s("",-1,6),new s("á",0,1),new s("é",0,2),new s("í",0,3),new s("ó",0,4),new s("ú",0,5)],y=[new s("la",-1,-1),new s("sela",0,-1),new s("le",-1,-1),new s("me",-1,-1),new s("se",-1,-1),new s("lo",-1,-1),new s("selo",5,-1),new s("las",-1,-1),new s("selas",7,-1),new s("les",-1,-1),new s("los",-1,-1),new s("selos",10,-1),new s("nos",-1,-1)],q=[new s("ando",-1,6),new s("iendo",-1,6),new s("yendo",-1,7),new s("ándo",-1,2),new s("iéndo",-1,1),new s("ar",-1,6),new s("er",-1,6),new s("ir",-1,6),new s("ár",-1,3),new s("ér",-1,4),new s("ír",-1,5)],C=[new s("ic",-1,-1),new s("ad",-1,-1),new s("os",-1,-1),new s("iv",-1,1)],P=[new s("able",-1,1),new s("ible",-1,1),new s("ante",-1,1)],F=[new s("ic",-1,1),new s("abil",-1,1),new s("iv",-1,1)],S=[new s("ica",-1,1),new s("ancia",-1,2),new s("encia",-1,5),new s("adora",-1,2),new s("osa",-1,1),new s("ista",-1,1),new s("iva",-1,9),new s("anza",-1,1),new s("logía",-1,3),new s("idad",-1,8),new s("able",-1,1),new s("ible",-1,1),new s("ante",-1,2),new s("mente",-1,7),new s("amente",13,6),new s("ación",-1,2),new s("ución",-1,4),new s("ico",-1,1),new s("ismo",-1,1),new s("oso",-1,1),new s("amiento",-1,1),new s("imiento",-1,1),new s("ivo",-1,9),new s("ador",-1,2),new s("icas",-1,1),new s("ancias",-1,2),new s("encias",-1,5),new s("adoras",-1,2),new s("osas",-1,1),new s("istas",-1,1),new s("ivas",-1,9),new s("anzas",-1,1),new s("logías",-1,3),new s("idades",-1,8),new s("ables",-1,1),new s("ibles",-1,1),new s("aciones",-1,2),new s("uciones",-1,4),new s("adores",-1,2),new s("antes",-1,2),new s("icos",-1,1),new s("ismos",-1,1),new s("osos",-1,1),new s("amientos",-1,1),new s("imientos",-1,1),new s("ivos",-1,9)],W=[new s("ya",-1,1),new s("ye",-1,1),new s("yan",-1,1),new s("yen",-1,1),new s("yeron",-1,1),new s("yendo",-1,1),new s("yo",-1,1),new s("yas",-1,1),new s("yes",-1,1),new s("yais",-1,1),new s("yamos",-1,1),new s("yó",-1,1)],L=[new s("aba",-1,2),new s("ada",-1,2),new s("ida",-1,2),new s("ara",-1,2),new s("iera",-1,2),new s("ía",-1,2),new s("aría",5,2),new s("ería",5,2),new s("iría",5,2),new s("ad",-1,2),new s("ed",-1,2),new s("id",-1,2),new s("ase",-1,2),new s("iese",-1,2),new s("aste",-1,2),new s("iste",-1,2),new s("an",-1,2),new s("aban",16,2),new s("aran",16,2),new s("ieran",16,2),new s("ían",16,2),new s("arían",20,2),new s("erían",20,2),new s("irían",20,2),new s("en",-1,1),new s("asen",24,2),new s("iesen",24,2),new s("aron",-1,2),new s("ieron",-1,2),new s("arán",-1,2),new s("erán",-1,2),new s("irán",-1,2),new s("ado",-1,2),new s("ido",-1,2),new s("ando",-1,2),new s("iendo",-1,2),new s("ar",-1,2),new s("er",-1,2),new s("ir",-1,2),new s("as",-1,2),new s("abas",39,2),new s("adas",39,2),new s("idas",39,2),new s("aras",39,2),new s("ieras",39,2),new s("ías",39,2),new s("arías",45,2),new s("erías",45,2),new s("irías",45,2),new s("es",-1,1),new s("ases",49,2),new s("ieses",49,2),new s("abais",-1,2),new s("arais",-1,2),new s("ierais",-1,2),new s("íais",-1,2),new s("aríais",55,2),new s("eríais",55,2),new s("iríais",55,2),new s("aseis",-1,2),new s("ieseis",-1,2),new s("asteis",-1,2),new s("isteis",-1,2),new s("áis",-1,2),new s("éis",-1,1),new s("aréis",64,2),new s("eréis",64,2),new s("iréis",64,2),new s("ados",-1,2),new s("idos",-1,2),new s("amos",-1,2),new s("ábamos",70,2),new s("áramos",70,2),new s("iéramos",70,2),new s("íamos",70,2),new s("aríamos",74,2),new s("eríamos",74,2),new s("iríamos",74,2),new s("emos",-1,1),new s("aremos",78,2),new s("eremos",78,2),new s("iremos",78,2),new s("ásemos",78,2),new s("iésemos",78,2),new s("imos",-1,2),new s("arás",-1,2),new s("erás",-1,2),new s("irás",-1,2),new s("ís",-1,2),new s("ará",-1,2),new s("erá",-1,2),new s("irá",-1,2),new s("aré",-1,2),new s("eré",-1,2),new s("iré",-1,2),new s("ió",-1,2)],z=[new s("a",-1,1),new s("e",-1,2),new s("o",-1,1),new s("os",-1,1),new s("á",-1,1),new s("é",-1,2),new s("í",-1,1),new s("ó",-1,1)],x=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,4,10],A=new r;this.setCurrent=function(e){A.setCurrent(e)},this.getCurrent=function(){return A.getCurrent()},this.stem=function(){var e=A.cursor;return t(),A.limit_backward=e,A.cursor=A.limit,m(),A.cursor=A.limit,b()||(A.cursor=A.limit,f()||(A.cursor=A.limit,_())),A.cursor=A.limit,h(),A.cursor=A.limit_backward,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.es.stemmer,"stemmer-es"),e.es.stopWordFilter=e.generateStopWordFilter("a al algo algunas algunos ante antes como con contra cual cuando de del desde donde durante e el ella ellas ellos en entre era erais eran eras eres es esa esas ese eso esos esta estaba estabais estaban estabas estad estada estadas estado estados estamos estando estar estaremos estará estarán estarás estaré estaréis estaría estaríais estaríamos estarían estarías estas este estemos esto estos estoy estuve estuviera estuvierais estuvieran estuvieras estuvieron estuviese estuvieseis estuviesen estuvieses estuvimos estuviste estuvisteis estuviéramos estuviésemos estuvo está estábamos estáis están estás esté estéis estén estés fue fuera fuerais fueran fueras fueron fuese fueseis fuesen fueses fui fuimos fuiste fuisteis fuéramos fuésemos ha habida habidas habido habidos habiendo habremos habrá habrán habrás habré habréis habría habríais habríamos habrían habrías habéis había habíais habíamos habían habías han has hasta hay haya hayamos hayan hayas hayáis he hemos hube hubiera hubierais hubieran hubieras hubieron hubiese hubieseis hubiesen hubieses hubimos hubiste hubisteis hubiéramos hubiésemos hubo la las le les lo los me mi mis mucho muchos muy más mí mía mías mío míos nada ni no nos nosotras nosotros nuestra nuestras nuestro nuestros o os otra otras otro otros para pero poco por porque que quien quienes qué se sea seamos sean seas seremos será serán serás seré seréis sería seríais seríamos serían serías seáis sido siendo sin sobre sois somos son soy su sus suya suyas suyo suyos sí también tanto te tendremos tendrá tendrán tendrás tendré tendréis tendría tendríais tendríamos tendrían tendrías tened tenemos tenga tengamos tengan tengas tengo tengáis tenida tenidas tenido tenidos teniendo tenéis tenía teníais teníamos tenían tenías ti tiene tienen tienes todo todos tu tus tuve tuviera tuvierais tuvieran tuvieras tuvieron tuviese tuvieseis tuviesen tuvieses tuvimos tuviste tuvisteis tuviéramos tuviésemos tuvo tuya tuyas tuyo tuyos tú un una uno unos vosotras vosotros vuestra vuestras vuestro vuestros y ya yo él éramos".split(" ")),e.Pipeline.registerFunction(e.es.stopWordFilter,"stopWordFilter-es")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.fi.min.js b/assets/javascripts/lunr/min/lunr.fi.min.js new file mode 100644 index 000000000..29f5dfcea --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.fi.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Finnish` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(i,e){"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e():e()(i.lunr)}(this,function(){return function(i){if(void 0===i)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===i.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");i.fi=function(){this.pipeline.reset(),this.pipeline.add(i.fi.trimmer,i.fi.stopWordFilter,i.fi.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(i.fi.stemmer))},i.fi.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",i.fi.trimmer=i.trimmerSupport.generateTrimmer(i.fi.wordCharacters),i.Pipeline.registerFunction(i.fi.trimmer,"trimmer-fi"),i.fi.stemmer=function(){var e=i.stemmerSupport.Among,r=i.stemmerSupport.SnowballProgram,n=new function(){function i(){f=A.limit,d=f,n()||(f=A.cursor,n()||(d=A.cursor))}function n(){for(var i;;){if(i=A.cursor,A.in_grouping(W,97,246))break;if(A.cursor=i,i>=A.limit)return!0;A.cursor++}for(A.cursor=i;!A.out_grouping(W,97,246);){if(A.cursor>=A.limit)return!0;A.cursor++}return!1}function t(){return d<=A.cursor}function s(){var i,e;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(h,10)){switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:if(!A.in_grouping_b(x,97,246))return;break;case 2:if(!t())return}A.slice_del()}else A.limit_backward=e}function o(){var i,e,r;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(v,9))switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:r=A.limit-A.cursor,A.eq_s_b(1,"k")||(A.cursor=A.limit-r,A.slice_del());break;case 2:A.slice_del(),A.ket=A.cursor,A.eq_s_b(3,"kse")&&(A.bra=A.cursor,A.slice_from("ksi"));break;case 3:A.slice_del();break;case 4:A.find_among_b(p,6)&&A.slice_del();break;case 5:A.find_among_b(g,6)&&A.slice_del();break;case 6:A.find_among_b(j,2)&&A.slice_del()}else A.limit_backward=e}function l(){return A.find_among_b(q,7)}function a(){return A.eq_s_b(1,"i")&&A.in_grouping_b(L,97,246)}function u(){var i,e,r;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(C,30)){switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:if(!A.eq_s_b(1,"a"))return;break;case 2:case 9:if(!A.eq_s_b(1,"e"))return;break;case 3:if(!A.eq_s_b(1,"i"))return;break;case 4:if(!A.eq_s_b(1,"o"))return;break;case 5:if(!A.eq_s_b(1,"ä"))return;break;case 6:if(!A.eq_s_b(1,"ö"))return;break;case 7:if(r=A.limit-A.cursor,!l()&&(A.cursor=A.limit-r,!A.eq_s_b(2,"ie"))){A.cursor=A.limit-r;break}if(A.cursor=A.limit-r,A.cursor<=A.limit_backward){A.cursor=A.limit-r;break}A.cursor--,A.bra=A.cursor;break;case 8:if(!A.in_grouping_b(W,97,246)||!A.out_grouping_b(W,97,246))return}A.slice_del(),k=!0}else A.limit_backward=e}function c(){var i,e,r;if(A.cursor>=d)if(e=A.limit_backward,A.limit_backward=d,A.ket=A.cursor,i=A.find_among_b(P,14)){if(A.bra=A.cursor,A.limit_backward=e,1==i){if(r=A.limit-A.cursor,A.eq_s_b(2,"po"))return;A.cursor=A.limit-r}A.slice_del()}else A.limit_backward=e}function m(){var i;A.cursor>=f&&(i=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,A.find_among_b(F,2)?(A.bra=A.cursor,A.limit_backward=i,A.slice_del()):A.limit_backward=i)}function w(){var i,e,r,n,t,s;if(A.cursor>=f){if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,A.eq_s_b(1,"t")&&(A.bra=A.cursor,r=A.limit-A.cursor,A.in_grouping_b(W,97,246)&&(A.cursor=A.limit-r,A.slice_del(),A.limit_backward=e,n=A.limit-A.cursor,A.cursor>=d&&(A.cursor=d,t=A.limit_backward,A.limit_backward=A.cursor,A.cursor=A.limit-n,A.ket=A.cursor,i=A.find_among_b(S,2))))){if(A.bra=A.cursor,A.limit_backward=t,1==i){if(s=A.limit-A.cursor,A.eq_s_b(2,"po"))return;A.cursor=A.limit-s}return void A.slice_del()}A.limit_backward=e}}function _(){var i,e,r,n;if(A.cursor>=f){for(i=A.limit_backward,A.limit_backward=f,e=A.limit-A.cursor,l()&&(A.cursor=A.limit-e,A.ket=A.cursor,A.cursor>A.limit_backward&&(A.cursor--,A.bra=A.cursor,A.slice_del())),A.cursor=A.limit-e,A.ket=A.cursor,A.in_grouping_b(y,97,228)&&(A.bra=A.cursor,A.out_grouping_b(W,97,246)&&A.slice_del()),A.cursor=A.limit-e,A.ket=A.cursor,A.eq_s_b(1,"j")&&(A.bra=A.cursor,r=A.limit-A.cursor,A.eq_s_b(1,"o")?A.slice_del():(A.cursor=A.limit-r,A.eq_s_b(1,"u")&&A.slice_del())),A.cursor=A.limit-e,A.ket=A.cursor,A.eq_s_b(1,"o")&&(A.bra=A.cursor,A.eq_s_b(1,"j")&&A.slice_del()),A.cursor=A.limit-e,A.limit_backward=i;;){if(n=A.limit-A.cursor,A.out_grouping_b(W,97,246)){A.cursor=A.limit-n;break}if(A.cursor=A.limit-n,A.cursor<=A.limit_backward)return;A.cursor--}A.ket=A.cursor,A.cursor>A.limit_backward&&(A.cursor--,A.bra=A.cursor,b=A.slice_to(),A.eq_v_b(b)&&A.slice_del())}}var k,b,d,f,h=[new e("pa",-1,1),new e("sti",-1,2),new e("kaan",-1,1),new e("han",-1,1),new e("kin",-1,1),new e("hän",-1,1),new e("kään",-1,1),new e("ko",-1,1),new e("pä",-1,1),new e("kö",-1,1)],p=[new e("lla",-1,-1),new e("na",-1,-1),new e("ssa",-1,-1),new e("ta",-1,-1),new e("lta",3,-1),new e("sta",3,-1)],g=[new e("llä",-1,-1),new e("nä",-1,-1),new e("ssä",-1,-1),new e("tä",-1,-1),new e("ltä",3,-1),new e("stä",3,-1)],j=[new e("lle",-1,-1),new e("ine",-1,-1)],v=[new e("nsa",-1,3),new e("mme",-1,3),new e("nne",-1,3),new e("ni",-1,2),new e("si",-1,1),new e("an",-1,4),new e("en",-1,6),new e("än",-1,5),new e("nsä",-1,3)],q=[new e("aa",-1,-1),new e("ee",-1,-1),new e("ii",-1,-1),new e("oo",-1,-1),new e("uu",-1,-1),new e("ää",-1,-1),new e("öö",-1,-1)],C=[new e("a",-1,8),new e("lla",0,-1),new e("na",0,-1),new e("ssa",0,-1),new e("ta",0,-1),new e("lta",4,-1),new e("sta",4,-1),new e("tta",4,9),new e("lle",-1,-1),new e("ine",-1,-1),new e("ksi",-1,-1),new e("n",-1,7),new e("han",11,1),new e("den",11,-1,a),new e("seen",11,-1,l),new e("hen",11,2),new e("tten",11,-1,a),new e("hin",11,3),new e("siin",11,-1,a),new e("hon",11,4),new e("hän",11,5),new e("hön",11,6),new e("ä",-1,8),new e("llä",22,-1),new e("nä",22,-1),new e("ssä",22,-1),new e("tä",22,-1),new e("ltä",26,-1),new e("stä",26,-1),new e("ttä",26,9)],P=[new e("eja",-1,-1),new e("mma",-1,1),new e("imma",1,-1),new e("mpa",-1,1),new e("impa",3,-1),new e("mmi",-1,1),new e("immi",5,-1),new e("mpi",-1,1),new e("impi",7,-1),new e("ejä",-1,-1),new e("mmä",-1,1),new e("immä",10,-1),new e("mpä",-1,1),new e("impä",12,-1)],F=[new e("i",-1,-1),new e("j",-1,-1)],S=[new e("mma",-1,1),new e("imma",0,-1)],y=[17,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8],W=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],L=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],x=[17,97,24,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],A=new r;this.setCurrent=function(i){A.setCurrent(i)},this.getCurrent=function(){return A.getCurrent()},this.stem=function(){var e=A.cursor;return i(),k=!1,A.limit_backward=e,A.cursor=A.limit,s(),A.cursor=A.limit,o(),A.cursor=A.limit,u(),A.cursor=A.limit,c(),A.cursor=A.limit,k?(m(),A.cursor=A.limit):(A.cursor=A.limit,w(),A.cursor=A.limit),_(),!0}};return function(i){return"function"==typeof i.update?i.update(function(i){return n.setCurrent(i),n.stem(),n.getCurrent()}):(n.setCurrent(i),n.stem(),n.getCurrent())}}(),i.Pipeline.registerFunction(i.fi.stemmer,"stemmer-fi"),i.fi.stopWordFilter=i.generateStopWordFilter("ei eivät emme en et ette että he heidän heidät heihin heille heillä heiltä heissä heistä heitä hän häneen hänelle hänellä häneltä hänen hänessä hänestä hänet häntä itse ja johon joiden joihin joiksi joilla joille joilta joina joissa joista joita joka joksi jolla jolle jolta jona jonka jos jossa josta jota jotka kanssa keiden keihin keiksi keille keillä keiltä keinä keissä keistä keitä keneen keneksi kenelle kenellä keneltä kenen kenenä kenessä kenestä kenet ketkä ketkä ketä koska kuin kuka kun me meidän meidät meihin meille meillä meiltä meissä meistä meitä mihin miksi mikä mille millä miltä minkä minkä minua minulla minulle minulta minun minussa minusta minut minuun minä minä missä mistä mitkä mitä mukaan mutta ne niiden niihin niiksi niille niillä niiltä niin niin niinä niissä niistä niitä noiden noihin noiksi noilla noille noilta noin noina noissa noista noita nuo nyt näiden näihin näiksi näille näillä näiltä näinä näissä näistä näitä nämä ole olemme olen olet olette oli olimme olin olisi olisimme olisin olisit olisitte olisivat olit olitte olivat olla olleet ollut on ovat poikki se sekä sen siihen siinä siitä siksi sille sillä sillä siltä sinua sinulla sinulle sinulta sinun sinussa sinusta sinut sinuun sinä sinä sitä tai te teidän teidät teihin teille teillä teiltä teissä teistä teitä tuo tuohon tuoksi tuolla tuolle tuolta tuon tuona tuossa tuosta tuota tähän täksi tälle tällä tältä tämä tämän tänä tässä tästä tätä vaan vai vaikka yli".split(" ")),i.Pipeline.registerFunction(i.fi.stopWordFilter,"stopWordFilter-fi")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.fr.min.js b/assets/javascripts/lunr/min/lunr.fr.min.js new file mode 100644 index 000000000..68cd0094a --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.fr.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `French` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.fr=function(){this.pipeline.reset(),this.pipeline.add(e.fr.trimmer,e.fr.stopWordFilter,e.fr.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.fr.stemmer))},e.fr.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.fr.trimmer=e.trimmerSupport.generateTrimmer(e.fr.wordCharacters),e.Pipeline.registerFunction(e.fr.trimmer,"trimmer-fr"),e.fr.stemmer=function(){var r=e.stemmerSupport.Among,s=e.stemmerSupport.SnowballProgram,i=new function(){function e(e,r,s){return!(!W.eq_s(1,e)||(W.ket=W.cursor,!W.in_grouping(F,97,251)))&&(W.slice_from(r),W.cursor=s,!0)}function i(e,r,s){return!!W.eq_s(1,e)&&(W.ket=W.cursor,W.slice_from(r),W.cursor=s,!0)}function n(){for(var r,s;;){if(r=W.cursor,W.in_grouping(F,97,251)){if(W.bra=W.cursor,s=W.cursor,e("u","U",r))continue;if(W.cursor=s,e("i","I",r))continue;if(W.cursor=s,i("y","Y",r))continue}if(W.cursor=r,W.bra=r,!e("y","Y",r)){if(W.cursor=r,W.eq_s(1,"q")&&(W.bra=W.cursor,i("u","U",r)))continue;if(W.cursor=r,r>=W.limit)return;W.cursor++}}}function t(){for(;!W.in_grouping(F,97,251);){if(W.cursor>=W.limit)return!0;W.cursor++}for(;!W.out_grouping(F,97,251);){if(W.cursor>=W.limit)return!0;W.cursor++}return!1}function u(){var e=W.cursor;if(q=W.limit,g=q,p=q,W.in_grouping(F,97,251)&&W.in_grouping(F,97,251)&&W.cursor=W.limit){W.cursor=q;break}W.cursor++}while(!W.in_grouping(F,97,251))}q=W.cursor,W.cursor=e,t()||(g=W.cursor,t()||(p=W.cursor))}function o(){for(var e,r;;){if(r=W.cursor,W.bra=r,!(e=W.find_among(h,4)))break;switch(W.ket=W.cursor,e){case 1:W.slice_from("i");break;case 2:W.slice_from("u");break;case 3:W.slice_from("y");break;case 4:if(W.cursor>=W.limit)return;W.cursor++}}}function c(){return q<=W.cursor}function a(){return g<=W.cursor}function l(){return p<=W.cursor}function w(){var e,r;if(W.ket=W.cursor,e=W.find_among_b(C,43)){switch(W.bra=W.cursor,e){case 1:if(!l())return!1;W.slice_del();break;case 2:if(!l())return!1;W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"ic")&&(W.bra=W.cursor,l()?W.slice_del():W.slice_from("iqU"));break;case 3:if(!l())return!1;W.slice_from("log");break;case 4:if(!l())return!1;W.slice_from("u");break;case 5:if(!l())return!1;W.slice_from("ent");break;case 6:if(!c())return!1;if(W.slice_del(),W.ket=W.cursor,e=W.find_among_b(z,6))switch(W.bra=W.cursor,e){case 1:l()&&(W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"at")&&(W.bra=W.cursor,l()&&W.slice_del()));break;case 2:l()?W.slice_del():a()&&W.slice_from("eux");break;case 3:l()&&W.slice_del();break;case 4:c()&&W.slice_from("i")}break;case 7:if(!l())return!1;if(W.slice_del(),W.ket=W.cursor,e=W.find_among_b(y,3))switch(W.bra=W.cursor,e){case 1:l()?W.slice_del():W.slice_from("abl");break;case 2:l()?W.slice_del():W.slice_from("iqU");break;case 3:l()&&W.slice_del()}break;case 8:if(!l())return!1;if(W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"at")&&(W.bra=W.cursor,l()&&(W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"ic")))){W.bra=W.cursor,l()?W.slice_del():W.slice_from("iqU");break}break;case 9:W.slice_from("eau");break;case 10:if(!a())return!1;W.slice_from("al");break;case 11:if(l())W.slice_del();else{if(!a())return!1;W.slice_from("eux")}break;case 12:if(!a()||!W.out_grouping_b(F,97,251))return!1;W.slice_del();break;case 13:return c()&&W.slice_from("ant"),!1;case 14:return c()&&W.slice_from("ent"),!1;case 15:return r=W.limit-W.cursor,W.in_grouping_b(F,97,251)&&c()&&(W.cursor=W.limit-r,W.slice_del()),!1}return!0}return!1}function f(){var e,r;if(W.cursor=q){if(s=W.limit_backward,W.limit_backward=q,W.ket=W.cursor,e=W.find_among_b(P,7))switch(W.bra=W.cursor,e){case 1:if(l()){if(i=W.limit-W.cursor,!W.eq_s_b(1,"s")&&(W.cursor=W.limit-i,!W.eq_s_b(1,"t")))break;W.slice_del()}break;case 2:W.slice_from("i");break;case 3:W.slice_del();break;case 4:W.eq_s_b(2,"gu")&&W.slice_del()}W.limit_backward=s}}function b(){var e=W.limit-W.cursor;W.find_among_b(U,5)&&(W.cursor=W.limit-e,W.ket=W.cursor,W.cursor>W.limit_backward&&(W.cursor--,W.bra=W.cursor,W.slice_del()))}function d(){for(var e,r=1;W.out_grouping_b(F,97,251);)r--;if(r<=0){if(W.ket=W.cursor,e=W.limit-W.cursor,!W.eq_s_b(1,"é")&&(W.cursor=W.limit-e,!W.eq_s_b(1,"è")))return;W.bra=W.cursor,W.slice_from("e")}}function k(){if(!w()&&(W.cursor=W.limit,!f()&&(W.cursor=W.limit,!m())))return W.cursor=W.limit,void _();W.cursor=W.limit,W.ket=W.cursor,W.eq_s_b(1,"Y")?(W.bra=W.cursor,W.slice_from("i")):(W.cursor=W.limit,W.eq_s_b(1,"ç")&&(W.bra=W.cursor,W.slice_from("c")))}var p,g,q,v=[new r("col",-1,-1),new r("par",-1,-1),new r("tap",-1,-1)],h=[new r("",-1,4),new r("I",0,1),new r("U",0,2),new r("Y",0,3)],z=[new r("iqU",-1,3),new r("abl",-1,3),new r("Ièr",-1,4),new r("ièr",-1,4),new r("eus",-1,2),new r("iv",-1,1)],y=[new r("ic",-1,2),new r("abil",-1,1),new r("iv",-1,3)],C=[new r("iqUe",-1,1),new r("atrice",-1,2),new r("ance",-1,1),new r("ence",-1,5),new r("logie",-1,3),new r("able",-1,1),new r("isme",-1,1),new r("euse",-1,11),new r("iste",-1,1),new r("ive",-1,8),new r("if",-1,8),new r("usion",-1,4),new r("ation",-1,2),new r("ution",-1,4),new r("ateur",-1,2),new r("iqUes",-1,1),new r("atrices",-1,2),new r("ances",-1,1),new r("ences",-1,5),new r("logies",-1,3),new r("ables",-1,1),new r("ismes",-1,1),new r("euses",-1,11),new r("istes",-1,1),new r("ives",-1,8),new r("ifs",-1,8),new r("usions",-1,4),new r("ations",-1,2),new r("utions",-1,4),new r("ateurs",-1,2),new r("ments",-1,15),new r("ements",30,6),new r("issements",31,12),new r("ités",-1,7),new r("ment",-1,15),new r("ement",34,6),new r("issement",35,12),new r("amment",34,13),new r("emment",34,14),new r("aux",-1,10),new r("eaux",39,9),new r("eux",-1,1),new r("ité",-1,7)],x=[new r("ira",-1,1),new r("ie",-1,1),new r("isse",-1,1),new r("issante",-1,1),new r("i",-1,1),new r("irai",4,1),new r("ir",-1,1),new r("iras",-1,1),new r("ies",-1,1),new r("îmes",-1,1),new r("isses",-1,1),new r("issantes",-1,1),new r("îtes",-1,1),new r("is",-1,1),new r("irais",13,1),new r("issais",13,1),new r("irions",-1,1),new r("issions",-1,1),new r("irons",-1,1),new r("issons",-1,1),new r("issants",-1,1),new r("it",-1,1),new r("irait",21,1),new r("issait",21,1),new r("issant",-1,1),new r("iraIent",-1,1),new r("issaIent",-1,1),new r("irent",-1,1),new r("issent",-1,1),new r("iront",-1,1),new r("ît",-1,1),new r("iriez",-1,1),new r("issiez",-1,1),new r("irez",-1,1),new r("issez",-1,1)],I=[new r("a",-1,3),new r("era",0,2),new r("asse",-1,3),new r("ante",-1,3),new r("ée",-1,2),new r("ai",-1,3),new r("erai",5,2),new r("er",-1,2),new r("as",-1,3),new r("eras",8,2),new r("âmes",-1,3),new r("asses",-1,3),new r("antes",-1,3),new r("âtes",-1,3),new r("ées",-1,2),new r("ais",-1,3),new r("erais",15,2),new r("ions",-1,1),new r("erions",17,2),new r("assions",17,3),new r("erons",-1,2),new r("ants",-1,3),new r("és",-1,2),new r("ait",-1,3),new r("erait",23,2),new r("ant",-1,3),new r("aIent",-1,3),new r("eraIent",26,2),new r("èrent",-1,2),new r("assent",-1,3),new r("eront",-1,2),new r("ât",-1,3),new r("ez",-1,2),new r("iez",32,2),new r("eriez",33,2),new r("assiez",33,3),new r("erez",32,2),new r("é",-1,2)],P=[new r("e",-1,3),new r("Ière",0,2),new r("ière",0,2),new r("ion",-1,1),new r("Ier",-1,2),new r("ier",-1,2),new r("ë",-1,4)],U=[new r("ell",-1,-1),new r("eill",-1,-1),new r("enn",-1,-1),new r("onn",-1,-1),new r("ett",-1,-1)],F=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,128,130,103,8,5],S=[1,65,20,0,0,0,0,0,0,0,0,0,0,0,0,0,128],W=new s;this.setCurrent=function(e){W.setCurrent(e)},this.getCurrent=function(){return W.getCurrent()},this.stem=function(){var e=W.cursor;return n(),W.cursor=e,u(),W.limit_backward=e,W.cursor=W.limit,k(),W.cursor=W.limit,b(),W.cursor=W.limit,d(),W.cursor=W.limit_backward,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.fr.stemmer,"stemmer-fr"),e.fr.stopWordFilter=e.generateStopWordFilter("ai aie aient aies ait as au aura aurai auraient aurais aurait auras aurez auriez aurions aurons auront aux avaient avais avait avec avez aviez avions avons ayant ayez ayons c ce ceci celà ces cet cette d dans de des du elle en es est et eu eue eues eurent eus eusse eussent eusses eussiez eussions eut eux eûmes eût eûtes furent fus fusse fussent fusses fussiez fussions fut fûmes fût fûtes ici il ils j je l la le les leur leurs lui m ma mais me mes moi mon même n ne nos notre nous on ont ou par pas pour qu que quel quelle quelles quels qui s sa sans se sera serai seraient serais serait seras serez seriez serions serons seront ses soi soient sois soit sommes son sont soyez soyons suis sur t ta te tes toi ton tu un une vos votre vous y à étaient étais était étant étiez étions été étée étées étés êtes".split(" ")),e.Pipeline.registerFunction(e.fr.stopWordFilter,"stopWordFilter-fr")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.hi.min.js b/assets/javascripts/lunr/min/lunr.hi.min.js new file mode 100644 index 000000000..7dbc41402 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.hi.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hi=function(){this.pipeline.reset(),this.pipeline.add(e.hi.trimmer,e.hi.stopWordFilter,e.hi.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.hi.stemmer))},e.hi.wordCharacters="ऀ-ःऄ-एऐ-टठ-यर-िी-ॏॐ-य़ॠ-९॰-ॿa-zA-Za-zA-Z0-90-9",e.hi.trimmer=e.trimmerSupport.generateTrimmer(e.hi.wordCharacters),e.Pipeline.registerFunction(e.hi.trimmer,"trimmer-hi"),e.hi.stopWordFilter=e.generateStopWordFilter("अत अपना अपनी अपने अभी अंदर आदि आप इत्यादि इन इनका इन्हीं इन्हें इन्हों इस इसका इसकी इसके इसमें इसी इसे उन उनका उनकी उनके उनको उन्हीं उन्हें उन्हों उस उसके उसी उसे एक एवं एस ऐसे और कई कर करता करते करना करने करें कहते कहा का काफ़ी कि कितना किन्हें किन्हों किया किर किस किसी किसे की कुछ कुल के को कोई कौन कौनसा गया घर जब जहाँ जा जितना जिन जिन्हें जिन्हों जिस जिसे जीधर जैसा जैसे जो तक तब तरह तिन तिन्हें तिन्हों तिस तिसे तो था थी थे दबारा दिया दुसरा दूसरे दो द्वारा न नके नहीं ना निहायत नीचे ने पर पहले पूरा पे फिर बनी बही बहुत बाद बाला बिलकुल भी भीतर मगर मानो मे में यदि यह यहाँ यही या यिह ये रखें रहा रहे ऱ्वासा लिए लिये लेकिन व वग़ैरह वर्ग वह वहाँ वहीं वाले वुह वे वो सकता सकते सबसे सभी साथ साबुत साभ सारा से सो संग ही हुआ हुई हुए है हैं हो होता होती होते होना होने".split(" ")),e.hi.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var r=e.wordcut;r.init(),e.hi.tokenizer=function(i){if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(r){return isLunr2?new e.Token(r.toLowerCase()):r.toLowerCase()});var t=i.toString().toLowerCase().replace(/^\s+/,"");return r.cut(t).split("|")},e.Pipeline.registerFunction(e.hi.stemmer,"stemmer-hi"),e.Pipeline.registerFunction(e.hi.stopWordFilter,"stopWordFilter-hi")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.hu.min.js b/assets/javascripts/lunr/min/lunr.hu.min.js new file mode 100644 index 000000000..ed9d909f7 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.hu.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Hungarian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hu=function(){this.pipeline.reset(),this.pipeline.add(e.hu.trimmer,e.hu.stopWordFilter,e.hu.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.hu.stemmer))},e.hu.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.hu.trimmer=e.trimmerSupport.generateTrimmer(e.hu.wordCharacters),e.Pipeline.registerFunction(e.hu.trimmer,"trimmer-hu"),e.hu.stemmer=function(){var n=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,i=new function(){function e(){var e,n=L.cursor;if(d=L.limit,L.in_grouping(W,97,252))for(;;){if(e=L.cursor,L.out_grouping(W,97,252))return L.cursor=e,L.find_among(g,8)||(L.cursor=e,e=L.limit)return void(d=e);L.cursor++}if(L.cursor=n,L.out_grouping(W,97,252)){for(;!L.in_grouping(W,97,252);){if(L.cursor>=L.limit)return;L.cursor++}d=L.cursor}}function i(){return d<=L.cursor}function a(){var e;if(L.ket=L.cursor,(e=L.find_among_b(h,2))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("a");break;case 2:L.slice_from("e")}}function t(){var e=L.limit-L.cursor;return!!L.find_among_b(p,23)&&(L.cursor=L.limit-e,!0)}function s(){if(L.cursor>L.limit_backward){L.cursor--,L.ket=L.cursor;var e=L.cursor-1;L.limit_backward<=e&&e<=L.limit&&(L.cursor=e,L.bra=e,L.slice_del())}}function c(){var e;if(L.ket=L.cursor,(e=L.find_among_b(_,2))&&(L.bra=L.cursor,i())){if((1==e||2==e)&&!t())return;L.slice_del(),s()}}function o(){L.ket=L.cursor,L.find_among_b(v,44)&&(L.bra=L.cursor,i()&&(L.slice_del(),a()))}function w(){var e;if(L.ket=L.cursor,(e=L.find_among_b(z,3))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("e");break;case 2:case 3:L.slice_from("a")}}function l(){var e;if(L.ket=L.cursor,(e=L.find_among_b(y,6))&&(L.bra=L.cursor,i()))switch(e){case 1:case 2:L.slice_del();break;case 3:L.slice_from("a");break;case 4:L.slice_from("e")}}function u(){var e;if(L.ket=L.cursor,(e=L.find_among_b(j,2))&&(L.bra=L.cursor,i())){if((1==e||2==e)&&!t())return;L.slice_del(),s()}}function m(){var e;if(L.ket=L.cursor,(e=L.find_among_b(C,7))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("a");break;case 2:L.slice_from("e");break;case 3:case 4:case 5:case 6:case 7:L.slice_del()}}function k(){var e;if(L.ket=L.cursor,(e=L.find_among_b(P,12))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 7:case 9:L.slice_del();break;case 2:case 5:case 8:L.slice_from("e");break;case 3:case 6:L.slice_from("a")}}function f(){var e;if(L.ket=L.cursor,(e=L.find_among_b(F,31))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 7:case 8:case 9:case 12:case 13:case 16:case 17:case 18:L.slice_del();break;case 2:case 5:case 10:case 14:case 19:L.slice_from("a");break;case 3:case 6:case 11:case 15:case 20:L.slice_from("e")}}function b(){var e;if(L.ket=L.cursor,(e=L.find_among_b(S,42))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 5:case 6:case 9:case 10:case 11:case 14:case 15:case 16:case 17:case 20:case 21:case 24:case 25:case 26:case 29:L.slice_del();break;case 2:case 7:case 12:case 18:case 22:case 27:L.slice_from("a");break;case 3:case 8:case 13:case 19:case 23:case 28:L.slice_from("e")}}var d,g=[new n("cs",-1,-1),new n("dzs",-1,-1),new n("gy",-1,-1),new n("ly",-1,-1),new n("ny",-1,-1),new n("sz",-1,-1),new n("ty",-1,-1),new n("zs",-1,-1)],h=[new n("á",-1,1),new n("é",-1,2)],p=[new n("bb",-1,-1),new n("cc",-1,-1),new n("dd",-1,-1),new n("ff",-1,-1),new n("gg",-1,-1),new n("jj",-1,-1),new n("kk",-1,-1),new n("ll",-1,-1),new n("mm",-1,-1),new n("nn",-1,-1),new n("pp",-1,-1),new n("rr",-1,-1),new n("ccs",-1,-1),new n("ss",-1,-1),new n("zzs",-1,-1),new n("tt",-1,-1),new n("vv",-1,-1),new n("ggy",-1,-1),new n("lly",-1,-1),new n("nny",-1,-1),new n("tty",-1,-1),new n("ssz",-1,-1),new n("zz",-1,-1)],_=[new n("al",-1,1),new n("el",-1,2)],v=[new n("ba",-1,-1),new n("ra",-1,-1),new n("be",-1,-1),new n("re",-1,-1),new n("ig",-1,-1),new n("nak",-1,-1),new n("nek",-1,-1),new n("val",-1,-1),new n("vel",-1,-1),new n("ul",-1,-1),new n("nál",-1,-1),new n("nél",-1,-1),new n("ból",-1,-1),new n("ról",-1,-1),new n("tól",-1,-1),new n("bõl",-1,-1),new n("rõl",-1,-1),new n("tõl",-1,-1),new n("ül",-1,-1),new n("n",-1,-1),new n("an",19,-1),new n("ban",20,-1),new n("en",19,-1),new n("ben",22,-1),new n("képpen",22,-1),new n("on",19,-1),new n("ön",19,-1),new n("képp",-1,-1),new n("kor",-1,-1),new n("t",-1,-1),new n("at",29,-1),new n("et",29,-1),new n("ként",29,-1),new n("anként",32,-1),new n("enként",32,-1),new n("onként",32,-1),new n("ot",29,-1),new n("ért",29,-1),new n("öt",29,-1),new n("hez",-1,-1),new n("hoz",-1,-1),new n("höz",-1,-1),new n("vá",-1,-1),new n("vé",-1,-1)],z=[new n("án",-1,2),new n("én",-1,1),new n("ánként",-1,3)],y=[new n("stul",-1,2),new n("astul",0,1),new n("ástul",0,3),new n("stül",-1,2),new n("estül",3,1),new n("éstül",3,4)],j=[new n("á",-1,1),new n("é",-1,2)],C=[new n("k",-1,7),new n("ak",0,4),new n("ek",0,6),new n("ok",0,5),new n("ák",0,1),new n("ék",0,2),new n("ök",0,3)],P=[new n("éi",-1,7),new n("áéi",0,6),new n("ééi",0,5),new n("é",-1,9),new n("ké",3,4),new n("aké",4,1),new n("eké",4,1),new n("oké",4,1),new n("áké",4,3),new n("éké",4,2),new n("öké",4,1),new n("éé",3,8)],F=[new n("a",-1,18),new n("ja",0,17),new n("d",-1,16),new n("ad",2,13),new n("ed",2,13),new n("od",2,13),new n("ád",2,14),new n("éd",2,15),new n("öd",2,13),new n("e",-1,18),new n("je",9,17),new n("nk",-1,4),new n("unk",11,1),new n("ánk",11,2),new n("énk",11,3),new n("ünk",11,1),new n("uk",-1,8),new n("juk",16,7),new n("ájuk",17,5),new n("ük",-1,8),new n("jük",19,7),new n("éjük",20,6),new n("m",-1,12),new n("am",22,9),new n("em",22,9),new n("om",22,9),new n("ám",22,10),new n("ém",22,11),new n("o",-1,18),new n("á",-1,19),new n("é",-1,20)],S=[new n("id",-1,10),new n("aid",0,9),new n("jaid",1,6),new n("eid",0,9),new n("jeid",3,6),new n("áid",0,7),new n("éid",0,8),new n("i",-1,15),new n("ai",7,14),new n("jai",8,11),new n("ei",7,14),new n("jei",10,11),new n("ái",7,12),new n("éi",7,13),new n("itek",-1,24),new n("eitek",14,21),new n("jeitek",15,20),new n("éitek",14,23),new n("ik",-1,29),new n("aik",18,26),new n("jaik",19,25),new n("eik",18,26),new n("jeik",21,25),new n("áik",18,27),new n("éik",18,28),new n("ink",-1,20),new n("aink",25,17),new n("jaink",26,16),new n("eink",25,17),new n("jeink",28,16),new n("áink",25,18),new n("éink",25,19),new n("aitok",-1,21),new n("jaitok",32,20),new n("áitok",-1,22),new n("im",-1,5),new n("aim",35,4),new n("jaim",36,1),new n("eim",35,4),new n("jeim",38,1),new n("áim",35,2),new n("éim",35,3)],W=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,52,14],L=new r;this.setCurrent=function(e){L.setCurrent(e)},this.getCurrent=function(){return L.getCurrent()},this.stem=function(){var n=L.cursor;return e(),L.limit_backward=n,L.cursor=L.limit,c(),L.cursor=L.limit,o(),L.cursor=L.limit,w(),L.cursor=L.limit,l(),L.cursor=L.limit,u(),L.cursor=L.limit,k(),L.cursor=L.limit,f(),L.cursor=L.limit,b(),L.cursor=L.limit,m(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.hu.stemmer,"stemmer-hu"),e.hu.stopWordFilter=e.generateStopWordFilter("a abban ahhoz ahogy ahol aki akik akkor alatt amely amelyek amelyekben amelyeket amelyet amelynek ami amikor amit amolyan amíg annak arra arról az azok azon azonban azt aztán azután azzal azért be belül benne bár cikk cikkek cikkeket csak de e ebben eddig egy egyes egyetlen egyik egyre egyéb egész ehhez ekkor el ellen elsõ elég elõ elõször elõtt emilyen ennek erre ez ezek ezen ezt ezzel ezért fel felé hanem hiszen hogy hogyan igen ill ill. illetve ilyen ilyenkor ismét ison itt jobban jó jól kell kellett keressünk keresztül ki kívül között közül legalább legyen lehet lehetett lenne lenni lesz lett maga magát majd majd meg mellett mely melyek mert mi mikor milyen minden mindenki mindent mindig mint mintha mit mivel miért most már más másik még míg nagy nagyobb nagyon ne nekem neki nem nincs néha néhány nélkül olyan ott pedig persze rá s saját sem semmi sok sokat sokkal szemben szerint szinte számára talán tehát teljes tovább továbbá több ugyanis utolsó után utána vagy vagyis vagyok valaki valami valamint való van vannak vele vissza viszont volna volt voltak voltam voltunk által általában át én éppen és így õ õk õket össze úgy új újabb újra".split(" ")),e.Pipeline.registerFunction(e.hu.stopWordFilter,"stopWordFilter-hu")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.it.min.js b/assets/javascripts/lunr/min/lunr.it.min.js new file mode 100644 index 000000000..344b6a3c0 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.it.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Italian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.it=function(){this.pipeline.reset(),this.pipeline.add(e.it.trimmer,e.it.stopWordFilter,e.it.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.it.stemmer))},e.it.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.it.trimmer=e.trimmerSupport.generateTrimmer(e.it.wordCharacters),e.Pipeline.registerFunction(e.it.trimmer,"trimmer-it"),e.it.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(e,r,n){return!(!x.eq_s(1,e)||(x.ket=x.cursor,!x.in_grouping(L,97,249)))&&(x.slice_from(r),x.cursor=n,!0)}function i(){for(var r,n,i,o,t=x.cursor;;){if(x.bra=x.cursor,r=x.find_among(h,7))switch(x.ket=x.cursor,r){case 1:x.slice_from("à");continue;case 2:x.slice_from("è");continue;case 3:x.slice_from("ì");continue;case 4:x.slice_from("ò");continue;case 5:x.slice_from("ù");continue;case 6:x.slice_from("qU");continue;case 7:if(x.cursor>=x.limit)break;x.cursor++;continue}break}for(x.cursor=t;;)for(n=x.cursor;;){if(i=x.cursor,x.in_grouping(L,97,249)){if(x.bra=x.cursor,o=x.cursor,e("u","U",i))break;if(x.cursor=o,e("i","I",i))break}if(x.cursor=i,x.cursor>=x.limit)return void(x.cursor=n);x.cursor++}}function o(e){if(x.cursor=e,!x.in_grouping(L,97,249))return!1;for(;!x.out_grouping(L,97,249);){if(x.cursor>=x.limit)return!1;x.cursor++}return!0}function t(){if(x.in_grouping(L,97,249)){var e=x.cursor;if(x.out_grouping(L,97,249)){for(;!x.in_grouping(L,97,249);){if(x.cursor>=x.limit)return o(e);x.cursor++}return!0}return o(e)}return!1}function s(){var e,r=x.cursor;if(!t()){if(x.cursor=r,!x.out_grouping(L,97,249))return;if(e=x.cursor,x.out_grouping(L,97,249)){for(;!x.in_grouping(L,97,249);){if(x.cursor>=x.limit)return x.cursor=e,void(x.in_grouping(L,97,249)&&x.cursor=x.limit)return;x.cursor++}k=x.cursor}function a(){for(;!x.in_grouping(L,97,249);){if(x.cursor>=x.limit)return!1;x.cursor++}for(;!x.out_grouping(L,97,249);){if(x.cursor>=x.limit)return!1;x.cursor++}return!0}function u(){var e=x.cursor;k=x.limit,p=k,g=k,s(),x.cursor=e,a()&&(p=x.cursor,a()&&(g=x.cursor))}function c(){for(var e;;){if(x.bra=x.cursor,!(e=x.find_among(q,3)))break;switch(x.ket=x.cursor,e){case 1:x.slice_from("i");break;case 2:x.slice_from("u");break;case 3:if(x.cursor>=x.limit)return;x.cursor++}}}function w(){return k<=x.cursor}function l(){return p<=x.cursor}function m(){return g<=x.cursor}function f(){var e;if(x.ket=x.cursor,x.find_among_b(C,37)&&(x.bra=x.cursor,(e=x.find_among_b(z,5))&&w()))switch(e){case 1:x.slice_del();break;case 2:x.slice_from("e")}}function v(){var e;if(x.ket=x.cursor,!(e=x.find_among_b(S,51)))return!1;switch(x.bra=x.cursor,e){case 1:if(!m())return!1;x.slice_del();break;case 2:if(!m())return!1;x.slice_del(),x.ket=x.cursor,x.eq_s_b(2,"ic")&&(x.bra=x.cursor,m()&&x.slice_del());break;case 3:if(!m())return!1;x.slice_from("log");break;case 4:if(!m())return!1;x.slice_from("u");break;case 5:if(!m())return!1;x.slice_from("ente");break;case 6:if(!w())return!1;x.slice_del();break;case 7:if(!l())return!1;x.slice_del(),x.ket=x.cursor,e=x.find_among_b(P,4),e&&(x.bra=x.cursor,m()&&(x.slice_del(),1==e&&(x.ket=x.cursor,x.eq_s_b(2,"at")&&(x.bra=x.cursor,m()&&x.slice_del()))));break;case 8:if(!m())return!1;x.slice_del(),x.ket=x.cursor,e=x.find_among_b(F,3),e&&(x.bra=x.cursor,1==e&&m()&&x.slice_del());break;case 9:if(!m())return!1;x.slice_del(),x.ket=x.cursor,x.eq_s_b(2,"at")&&(x.bra=x.cursor,m()&&(x.slice_del(),x.ket=x.cursor,x.eq_s_b(2,"ic")&&(x.bra=x.cursor,m()&&x.slice_del())))}return!0}function b(){var e,r;x.cursor>=k&&(r=x.limit_backward,x.limit_backward=k,x.ket=x.cursor,e=x.find_among_b(W,87),e&&(x.bra=x.cursor,1==e&&x.slice_del()),x.limit_backward=r)}function d(){var e=x.limit-x.cursor;if(x.ket=x.cursor,x.in_grouping_b(y,97,242)&&(x.bra=x.cursor,w()&&(x.slice_del(),x.ket=x.cursor,x.eq_s_b(1,"i")&&(x.bra=x.cursor,w()))))return void x.slice_del();x.cursor=x.limit-e}function _(){d(),x.ket=x.cursor,x.eq_s_b(1,"h")&&(x.bra=x.cursor,x.in_grouping_b(U,99,103)&&w()&&x.slice_del())}var g,p,k,h=[new r("",-1,7),new r("qu",0,6),new r("á",0,1),new r("é",0,2),new r("í",0,3),new r("ó",0,4),new r("ú",0,5)],q=[new r("",-1,3),new r("I",0,1),new r("U",0,2)],C=[new r("la",-1,-1),new r("cela",0,-1),new r("gliela",0,-1),new r("mela",0,-1),new r("tela",0,-1),new r("vela",0,-1),new r("le",-1,-1),new r("cele",6,-1),new r("gliele",6,-1),new r("mele",6,-1),new r("tele",6,-1),new r("vele",6,-1),new r("ne",-1,-1),new r("cene",12,-1),new r("gliene",12,-1),new r("mene",12,-1),new r("sene",12,-1),new r("tene",12,-1),new r("vene",12,-1),new r("ci",-1,-1),new r("li",-1,-1),new r("celi",20,-1),new r("glieli",20,-1),new r("meli",20,-1),new r("teli",20,-1),new r("veli",20,-1),new r("gli",20,-1),new r("mi",-1,-1),new r("si",-1,-1),new r("ti",-1,-1),new r("vi",-1,-1),new r("lo",-1,-1),new r("celo",31,-1),new r("glielo",31,-1),new r("melo",31,-1),new r("telo",31,-1),new r("velo",31,-1)],z=[new r("ando",-1,1),new r("endo",-1,1),new r("ar",-1,2),new r("er",-1,2),new r("ir",-1,2)],P=[new r("ic",-1,-1),new r("abil",-1,-1),new r("os",-1,-1),new r("iv",-1,1)],F=[new r("ic",-1,1),new r("abil",-1,1),new r("iv",-1,1)],S=[new r("ica",-1,1),new r("logia",-1,3),new r("osa",-1,1),new r("ista",-1,1),new r("iva",-1,9),new r("anza",-1,1),new r("enza",-1,5),new r("ice",-1,1),new r("atrice",7,1),new r("iche",-1,1),new r("logie",-1,3),new r("abile",-1,1),new r("ibile",-1,1),new r("usione",-1,4),new r("azione",-1,2),new r("uzione",-1,4),new r("atore",-1,2),new r("ose",-1,1),new r("ante",-1,1),new r("mente",-1,1),new r("amente",19,7),new r("iste",-1,1),new r("ive",-1,9),new r("anze",-1,1),new r("enze",-1,5),new r("ici",-1,1),new r("atrici",25,1),new r("ichi",-1,1),new r("abili",-1,1),new r("ibili",-1,1),new r("ismi",-1,1),new r("usioni",-1,4),new r("azioni",-1,2),new r("uzioni",-1,4),new r("atori",-1,2),new r("osi",-1,1),new r("anti",-1,1),new r("amenti",-1,6),new r("imenti",-1,6),new r("isti",-1,1),new r("ivi",-1,9),new r("ico",-1,1),new r("ismo",-1,1),new r("oso",-1,1),new r("amento",-1,6),new r("imento",-1,6),new r("ivo",-1,9),new r("ità",-1,8),new r("istà",-1,1),new r("istè",-1,1),new r("istì",-1,1)],W=[new r("isca",-1,1),new r("enda",-1,1),new r("ata",-1,1),new r("ita",-1,1),new r("uta",-1,1),new r("ava",-1,1),new r("eva",-1,1),new r("iva",-1,1),new r("erebbe",-1,1),new r("irebbe",-1,1),new r("isce",-1,1),new r("ende",-1,1),new r("are",-1,1),new r("ere",-1,1),new r("ire",-1,1),new r("asse",-1,1),new r("ate",-1,1),new r("avate",16,1),new r("evate",16,1),new r("ivate",16,1),new r("ete",-1,1),new r("erete",20,1),new r("irete",20,1),new r("ite",-1,1),new r("ereste",-1,1),new r("ireste",-1,1),new r("ute",-1,1),new r("erai",-1,1),new r("irai",-1,1),new r("isci",-1,1),new r("endi",-1,1),new r("erei",-1,1),new r("irei",-1,1),new r("assi",-1,1),new r("ati",-1,1),new r("iti",-1,1),new r("eresti",-1,1),new r("iresti",-1,1),new r("uti",-1,1),new r("avi",-1,1),new r("evi",-1,1),new r("ivi",-1,1),new r("isco",-1,1),new r("ando",-1,1),new r("endo",-1,1),new r("Yamo",-1,1),new r("iamo",-1,1),new r("avamo",-1,1),new r("evamo",-1,1),new r("ivamo",-1,1),new r("eremo",-1,1),new r("iremo",-1,1),new r("assimo",-1,1),new r("ammo",-1,1),new r("emmo",-1,1),new r("eremmo",54,1),new r("iremmo",54,1),new r("immo",-1,1),new r("ano",-1,1),new r("iscano",58,1),new r("avano",58,1),new r("evano",58,1),new r("ivano",58,1),new r("eranno",-1,1),new r("iranno",-1,1),new r("ono",-1,1),new r("iscono",65,1),new r("arono",65,1),new r("erono",65,1),new r("irono",65,1),new r("erebbero",-1,1),new r("irebbero",-1,1),new r("assero",-1,1),new r("essero",-1,1),new r("issero",-1,1),new r("ato",-1,1),new r("ito",-1,1),new r("uto",-1,1),new r("avo",-1,1),new r("evo",-1,1),new r("ivo",-1,1),new r("ar",-1,1),new r("ir",-1,1),new r("erà",-1,1),new r("irà",-1,1),new r("erò",-1,1),new r("irò",-1,1)],L=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2,1],y=[17,65,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2],U=[17],x=new n;this.setCurrent=function(e){x.setCurrent(e)},this.getCurrent=function(){return x.getCurrent()},this.stem=function(){var e=x.cursor;return i(),x.cursor=e,u(),x.limit_backward=e,x.cursor=x.limit,f(),x.cursor=x.limit,v()||(x.cursor=x.limit,b()),x.cursor=x.limit,_(),x.cursor=x.limit_backward,c(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.it.stemmer,"stemmer-it"),e.it.stopWordFilter=e.generateStopWordFilter("a abbia abbiamo abbiano abbiate ad agl agli ai al all alla alle allo anche avemmo avendo avesse avessero avessi avessimo aveste avesti avete aveva avevamo avevano avevate avevi avevo avrai avranno avrebbe avrebbero avrei avremmo avremo avreste avresti avrete avrà avrò avuta avute avuti avuto c che chi ci coi col come con contro cui da dagl dagli dai dal dall dalla dalle dallo degl degli dei del dell della delle dello di dov dove e ebbe ebbero ebbi ed era erano eravamo eravate eri ero essendo faccia facciamo facciano facciate faccio facemmo facendo facesse facessero facessi facessimo faceste facesti faceva facevamo facevano facevate facevi facevo fai fanno farai faranno farebbe farebbero farei faremmo faremo fareste faresti farete farà farò fece fecero feci fosse fossero fossi fossimo foste fosti fu fui fummo furono gli ha hai hanno ho i il in io l la le lei li lo loro lui ma mi mia mie miei mio ne negl negli nei nel nell nella nelle nello noi non nostra nostre nostri nostro o per perché più quale quanta quante quanti quanto quella quelle quelli quello questa queste questi questo sarai saranno sarebbe sarebbero sarei saremmo saremo sareste saresti sarete sarà sarò se sei si sia siamo siano siate siete sono sta stai stando stanno starai staranno starebbe starebbero starei staremmo staremo stareste staresti starete starà starò stava stavamo stavano stavate stavi stavo stemmo stesse stessero stessi stessimo steste stesti stette stettero stetti stia stiamo stiano stiate sto su sua sue sugl sugli sui sul sull sulla sulle sullo suo suoi ti tra tu tua tue tuo tuoi tutti tutto un una uno vi voi vostra vostre vostri vostro è".split(" ")),e.Pipeline.registerFunction(e.it.stopWordFilter,"stopWordFilter-it")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.ja.min.js b/assets/javascripts/lunr/min/lunr.ja.min.js new file mode 100644 index 000000000..5f254ebe9 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.ja.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.ja=function(){this.pipeline.reset(),this.pipeline.add(e.ja.trimmer,e.ja.stopWordFilter,e.ja.stemmer),r?this.tokenizer=e.ja.tokenizer:(e.tokenizer&&(e.tokenizer=e.ja.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.ja.tokenizer))};var t=new e.TinySegmenter;e.ja.tokenizer=function(i){var n,o,s,p,a,u,m,l,c,f;if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(t){return r?new e.Token(t.toLowerCase()):t.toLowerCase()});for(o=i.toString().toLowerCase().replace(/^\s+/,""),n=o.length-1;n>=0;n--)if(/\S/.test(o.charAt(n))){o=o.substring(0,n+1);break}for(a=[],s=o.length,c=0,l=0;c<=s;c++)if(u=o.charAt(c),m=c-l,u.match(/\s/)||c==s){if(m>0)for(p=t.segment(o.slice(l,c)).filter(function(e){return!!e}),f=l,n=0;n=C.limit)break;C.cursor++;continue}break}for(C.cursor=o,C.bra=o,C.eq_s(1,"y")?(C.ket=C.cursor,C.slice_from("Y")):C.cursor=o;;)if(e=C.cursor,C.in_grouping(q,97,232)){if(i=C.cursor,C.bra=i,C.eq_s(1,"i"))C.ket=C.cursor,C.in_grouping(q,97,232)&&(C.slice_from("I"),C.cursor=e);else if(C.cursor=i,C.eq_s(1,"y"))C.ket=C.cursor,C.slice_from("Y"),C.cursor=e;else if(n(e))break}else if(n(e))break}function n(r){return C.cursor=r,r>=C.limit||(C.cursor++,!1)}function o(){_=C.limit,d=_,t()||(_=C.cursor,_<3&&(_=3),t()||(d=C.cursor))}function t(){for(;!C.in_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}for(;!C.out_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}return!1}function s(){for(var r;;)if(C.bra=C.cursor,r=C.find_among(p,3))switch(C.ket=C.cursor,r){case 1:C.slice_from("y");break;case 2:C.slice_from("i");break;case 3:if(C.cursor>=C.limit)return;C.cursor++}}function u(){return _<=C.cursor}function c(){return d<=C.cursor}function a(){var r=C.limit-C.cursor;C.find_among_b(g,3)&&(C.cursor=C.limit-r,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del()))}function l(){var r;w=!1,C.ket=C.cursor,C.eq_s_b(1,"e")&&(C.bra=C.cursor,u()&&(r=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-r,C.slice_del(),w=!0,a())))}function m(){var r;u()&&(r=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-r,C.eq_s_b(3,"gem")||(C.cursor=C.limit-r,C.slice_del(),a())))}function f(){var r,e,i,n,o,t,s=C.limit-C.cursor;if(C.ket=C.cursor,r=C.find_among_b(h,5))switch(C.bra=C.cursor,r){case 1:u()&&C.slice_from("heid");break;case 2:m();break;case 3:u()&&C.out_grouping_b(j,97,232)&&C.slice_del()}if(C.cursor=C.limit-s,l(),C.cursor=C.limit-s,C.ket=C.cursor,C.eq_s_b(4,"heid")&&(C.bra=C.cursor,c()&&(e=C.limit-C.cursor,C.eq_s_b(1,"c")||(C.cursor=C.limit-e,C.slice_del(),C.ket=C.cursor,C.eq_s_b(2,"en")&&(C.bra=C.cursor,m())))),C.cursor=C.limit-s,C.ket=C.cursor,r=C.find_among_b(k,6))switch(C.bra=C.cursor,r){case 1:if(c()){if(C.slice_del(),i=C.limit-C.cursor,C.ket=C.cursor,C.eq_s_b(2,"ig")&&(C.bra=C.cursor,c()&&(n=C.limit-C.cursor,!C.eq_s_b(1,"e")))){C.cursor=C.limit-n,C.slice_del();break}C.cursor=C.limit-i,a()}break;case 2:c()&&(o=C.limit-C.cursor,C.eq_s_b(1,"e")||(C.cursor=C.limit-o,C.slice_del()));break;case 3:c()&&(C.slice_del(),l());break;case 4:c()&&C.slice_del();break;case 5:c()&&w&&C.slice_del()}C.cursor=C.limit-s,C.out_grouping_b(z,73,232)&&(t=C.limit-C.cursor,C.find_among_b(v,4)&&C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-t,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del())))}var d,_,w,b=[new e("",-1,6),new e("á",0,1),new e("ä",0,1),new e("é",0,2),new e("ë",0,2),new e("í",0,3),new e("ï",0,3),new e("ó",0,4),new e("ö",0,4),new e("ú",0,5),new e("ü",0,5)],p=[new e("",-1,3),new e("I",0,2),new e("Y",0,1)],g=[new e("dd",-1,-1),new e("kk",-1,-1),new e("tt",-1,-1)],h=[new e("ene",-1,2),new e("se",-1,3),new e("en",-1,2),new e("heden",2,1),new e("s",-1,3)],k=[new e("end",-1,1),new e("ig",-1,2),new e("ing",-1,1),new e("lijk",-1,3),new e("baar",-1,4),new e("bar",-1,5)],v=[new e("aa",-1,-1),new e("ee",-1,-1),new e("oo",-1,-1),new e("uu",-1,-1)],q=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],z=[1,0,0,17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],j=[17,67,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],C=new i;this.setCurrent=function(r){C.setCurrent(r)},this.getCurrent=function(){return C.getCurrent()},this.stem=function(){var e=C.cursor;return r(),C.cursor=e,o(),C.limit_backward=e,C.cursor=C.limit,f(),C.cursor=C.limit_backward,s(),!0}};return function(r){return"function"==typeof r.update?r.update(function(r){return n.setCurrent(r),n.stem(),n.getCurrent()}):(n.setCurrent(r),n.stem(),n.getCurrent())}}(),r.Pipeline.registerFunction(r.nl.stemmer,"stemmer-nl"),r.nl.stopWordFilter=r.generateStopWordFilter(" aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou".split(" ")),r.Pipeline.registerFunction(r.nl.stopWordFilter,"stopWordFilter-nl")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.no.min.js b/assets/javascripts/lunr/min/lunr.no.min.js new file mode 100644 index 000000000..92bc7e4e8 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.no.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Norwegian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.no=function(){this.pipeline.reset(),this.pipeline.add(e.no.trimmer,e.no.stopWordFilter,e.no.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.no.stemmer))},e.no.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.no.trimmer=e.trimmerSupport.generateTrimmer(e.no.wordCharacters),e.Pipeline.registerFunction(e.no.trimmer,"trimmer-no"),e.no.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(){var e,r=w.cursor+3;if(a=w.limit,0<=r||r<=w.limit){for(s=r;;){if(e=w.cursor,w.in_grouping(d,97,248)){w.cursor=e;break}if(e>=w.limit)return;w.cursor=e+1}for(;!w.out_grouping(d,97,248);){if(w.cursor>=w.limit)return;w.cursor++}a=w.cursor,a=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(m,29),w.limit_backward=r,e))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:n=w.limit-w.cursor,w.in_grouping_b(c,98,122)?w.slice_del():(w.cursor=w.limit-n,w.eq_s_b(1,"k")&&w.out_grouping_b(d,97,248)&&w.slice_del());break;case 3:w.slice_from("er")}}function t(){var e,r=w.limit-w.cursor;w.cursor>=a&&(e=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,w.find_among_b(u,2)?(w.bra=w.cursor,w.limit_backward=e,w.cursor=w.limit-r,w.cursor>w.limit_backward&&(w.cursor--,w.bra=w.cursor,w.slice_del())):w.limit_backward=e)}function o(){var e,r;w.cursor>=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(l,11),e?(w.bra=w.cursor,w.limit_backward=r,1==e&&w.slice_del()):w.limit_backward=r)}var s,a,m=[new r("a",-1,1),new r("e",-1,1),new r("ede",1,1),new r("ande",1,1),new r("ende",1,1),new r("ane",1,1),new r("ene",1,1),new r("hetene",6,1),new r("erte",1,3),new r("en",-1,1),new r("heten",9,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",12,1),new r("s",-1,2),new r("as",14,1),new r("es",14,1),new r("edes",16,1),new r("endes",16,1),new r("enes",16,1),new r("hetenes",19,1),new r("ens",14,1),new r("hetens",21,1),new r("ers",14,1),new r("ets",14,1),new r("et",-1,1),new r("het",25,1),new r("ert",-1,3),new r("ast",-1,1)],u=[new r("dt",-1,-1),new r("vt",-1,-1)],l=[new r("leg",-1,1),new r("eleg",0,1),new r("ig",-1,1),new r("eig",2,1),new r("lig",2,1),new r("elig",4,1),new r("els",-1,1),new r("lov",-1,1),new r("elov",7,1),new r("slov",7,1),new r("hetslov",9,1)],d=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],c=[119,125,149,1],w=new n;this.setCurrent=function(e){w.setCurrent(e)},this.getCurrent=function(){return w.getCurrent()},this.stem=function(){var r=w.cursor;return e(),w.limit_backward=r,w.cursor=w.limit,i(),w.cursor=w.limit,t(),w.cursor=w.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.no.stemmer,"stemmer-no"),e.no.stopWordFilter=e.generateStopWordFilter("alle at av bare begge ble blei bli blir blitt både båe da de deg dei deim deira deires dem den denne der dere deres det dette di din disse ditt du dykk dykkar då eg ein eit eitt eller elles en enn er et ett etter for fordi fra før ha hadde han hans har hennar henne hennes her hjå ho hoe honom hoss hossen hun hva hvem hver hvilke hvilken hvis hvor hvordan hvorfor i ikke ikkje ikkje ingen ingi inkje inn inni ja jeg kan kom korleis korso kun kunne kva kvar kvarhelst kven kvi kvifor man mange me med medan meg meget mellom men mi min mine mitt mot mykje ned no noe noen noka noko nokon nokor nokre nå når og også om opp oss over på samme seg selv si si sia sidan siden sin sine sitt sjøl skal skulle slik so som som somme somt så sånn til um upp ut uten var vart varte ved vere verte vi vil ville vore vors vort vår være være vært å".split(" ")),e.Pipeline.registerFunction(e.no.stopWordFilter,"stopWordFilter-no")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.pt.min.js b/assets/javascripts/lunr/min/lunr.pt.min.js new file mode 100644 index 000000000..6c16996d6 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.pt.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Portuguese` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.pt=function(){this.pipeline.reset(),this.pipeline.add(e.pt.trimmer,e.pt.stopWordFilter,e.pt.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.pt.stemmer))},e.pt.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.pt.trimmer=e.trimmerSupport.generateTrimmer(e.pt.wordCharacters),e.Pipeline.registerFunction(e.pt.trimmer,"trimmer-pt"),e.pt.stemmer=function(){var r=e.stemmerSupport.Among,s=e.stemmerSupport.SnowballProgram,n=new function(){function e(){for(var e;;){if(z.bra=z.cursor,e=z.find_among(k,3))switch(z.ket=z.cursor,e){case 1:z.slice_from("a~");continue;case 2:z.slice_from("o~");continue;case 3:if(z.cursor>=z.limit)break;z.cursor++;continue}break}}function n(){if(z.out_grouping(y,97,250)){for(;!z.in_grouping(y,97,250);){if(z.cursor>=z.limit)return!0;z.cursor++}return!1}return!0}function i(){if(z.in_grouping(y,97,250))for(;!z.out_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}return g=z.cursor,!0}function o(){var e,r,s=z.cursor;if(z.in_grouping(y,97,250))if(e=z.cursor,n()){if(z.cursor=e,i())return}else g=z.cursor;if(z.cursor=s,z.out_grouping(y,97,250)){if(r=z.cursor,n()){if(z.cursor=r,!z.in_grouping(y,97,250)||z.cursor>=z.limit)return;z.cursor++}g=z.cursor}}function t(){for(;!z.in_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}for(;!z.out_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}return!0}function a(){var e=z.cursor;g=z.limit,b=g,h=g,o(),z.cursor=e,t()&&(b=z.cursor,t()&&(h=z.cursor))}function u(){for(var e;;){if(z.bra=z.cursor,e=z.find_among(q,3))switch(z.ket=z.cursor,e){case 1:z.slice_from("ã");continue;case 2:z.slice_from("õ");continue;case 3:if(z.cursor>=z.limit)break;z.cursor++;continue}break}}function w(){return g<=z.cursor}function m(){return b<=z.cursor}function c(){return h<=z.cursor}function l(){var e;if(z.ket=z.cursor,!(e=z.find_among_b(F,45)))return!1;switch(z.bra=z.cursor,e){case 1:if(!c())return!1;z.slice_del();break;case 2:if(!c())return!1;z.slice_from("log");break;case 3:if(!c())return!1;z.slice_from("u");break;case 4:if(!c())return!1;z.slice_from("ente");break;case 5:if(!m())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(j,4),e&&(z.bra=z.cursor,c()&&(z.slice_del(),1==e&&(z.ket=z.cursor,z.eq_s_b(2,"at")&&(z.bra=z.cursor,c()&&z.slice_del()))));break;case 6:if(!c())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(C,3),e&&(z.bra=z.cursor,1==e&&c()&&z.slice_del());break;case 7:if(!c())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(P,3),e&&(z.bra=z.cursor,1==e&&c()&&z.slice_del());break;case 8:if(!c())return!1;z.slice_del(),z.ket=z.cursor,z.eq_s_b(2,"at")&&(z.bra=z.cursor,c()&&z.slice_del());break;case 9:if(!w()||!z.eq_s_b(1,"e"))return!1;z.slice_from("ir")}return!0}function f(){var e,r;if(z.cursor>=g){if(r=z.limit_backward,z.limit_backward=g,z.ket=z.cursor,e=z.find_among_b(S,120))return z.bra=z.cursor,1==e&&z.slice_del(),z.limit_backward=r,!0;z.limit_backward=r}return!1}function d(){var e;z.ket=z.cursor,(e=z.find_among_b(W,7))&&(z.bra=z.cursor,1==e&&w()&&z.slice_del())}function v(e,r){if(z.eq_s_b(1,e)){z.bra=z.cursor;var s=z.limit-z.cursor;if(z.eq_s_b(1,r))return z.cursor=z.limit-s,w()&&z.slice_del(),!1}return!0}function p(){var e;if(z.ket=z.cursor,e=z.find_among_b(L,4))switch(z.bra=z.cursor,e){case 1:w()&&(z.slice_del(),z.ket=z.cursor,z.limit-z.cursor,v("u","g")&&v("i","c"));break;case 2:z.slice_from("c")}}function _(){if(!l()&&(z.cursor=z.limit,!f()))return z.cursor=z.limit,void d();z.cursor=z.limit,z.ket=z.cursor,z.eq_s_b(1,"i")&&(z.bra=z.cursor,z.eq_s_b(1,"c")&&(z.cursor=z.limit,w()&&z.slice_del()))}var h,b,g,k=[new r("",-1,3),new r("ã",0,1),new r("õ",0,2)],q=[new r("",-1,3),new r("a~",0,1),new r("o~",0,2)],j=[new r("ic",-1,-1),new r("ad",-1,-1),new r("os",-1,-1),new r("iv",-1,1)],C=[new r("ante",-1,1),new r("avel",-1,1),new r("ível",-1,1)],P=[new r("ic",-1,1),new r("abil",-1,1),new r("iv",-1,1)],F=[new r("ica",-1,1),new r("ância",-1,1),new r("ência",-1,4),new r("ira",-1,9),new r("adora",-1,1),new r("osa",-1,1),new r("ista",-1,1),new r("iva",-1,8),new r("eza",-1,1),new r("logía",-1,2),new r("idade",-1,7),new r("ante",-1,1),new r("mente",-1,6),new r("amente",12,5),new r("ável",-1,1),new r("ível",-1,1),new r("ución",-1,3),new r("ico",-1,1),new r("ismo",-1,1),new r("oso",-1,1),new r("amento",-1,1),new r("imento",-1,1),new r("ivo",-1,8),new r("aça~o",-1,1),new r("ador",-1,1),new r("icas",-1,1),new r("ências",-1,4),new r("iras",-1,9),new r("adoras",-1,1),new r("osas",-1,1),new r("istas",-1,1),new r("ivas",-1,8),new r("ezas",-1,1),new r("logías",-1,2),new r("idades",-1,7),new r("uciones",-1,3),new r("adores",-1,1),new r("antes",-1,1),new r("aço~es",-1,1),new r("icos",-1,1),new r("ismos",-1,1),new r("osos",-1,1),new r("amentos",-1,1),new r("imentos",-1,1),new r("ivos",-1,8)],S=[new r("ada",-1,1),new r("ida",-1,1),new r("ia",-1,1),new r("aria",2,1),new r("eria",2,1),new r("iria",2,1),new r("ara",-1,1),new r("era",-1,1),new r("ira",-1,1),new r("ava",-1,1),new r("asse",-1,1),new r("esse",-1,1),new r("isse",-1,1),new r("aste",-1,1),new r("este",-1,1),new r("iste",-1,1),new r("ei",-1,1),new r("arei",16,1),new r("erei",16,1),new r("irei",16,1),new r("am",-1,1),new r("iam",20,1),new r("ariam",21,1),new r("eriam",21,1),new r("iriam",21,1),new r("aram",20,1),new r("eram",20,1),new r("iram",20,1),new r("avam",20,1),new r("em",-1,1),new r("arem",29,1),new r("erem",29,1),new r("irem",29,1),new r("assem",29,1),new r("essem",29,1),new r("issem",29,1),new r("ado",-1,1),new r("ido",-1,1),new r("ando",-1,1),new r("endo",-1,1),new r("indo",-1,1),new r("ara~o",-1,1),new r("era~o",-1,1),new r("ira~o",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("ir",-1,1),new r("as",-1,1),new r("adas",47,1),new r("idas",47,1),new r("ias",47,1),new r("arias",50,1),new r("erias",50,1),new r("irias",50,1),new r("aras",47,1),new r("eras",47,1),new r("iras",47,1),new r("avas",47,1),new r("es",-1,1),new r("ardes",58,1),new r("erdes",58,1),new r("irdes",58,1),new r("ares",58,1),new r("eres",58,1),new r("ires",58,1),new r("asses",58,1),new r("esses",58,1),new r("isses",58,1),new r("astes",58,1),new r("estes",58,1),new r("istes",58,1),new r("is",-1,1),new r("ais",71,1),new r("eis",71,1),new r("areis",73,1),new r("ereis",73,1),new r("ireis",73,1),new r("áreis",73,1),new r("éreis",73,1),new r("íreis",73,1),new r("ásseis",73,1),new r("ésseis",73,1),new r("ísseis",73,1),new r("áveis",73,1),new r("íeis",73,1),new r("aríeis",84,1),new r("eríeis",84,1),new r("iríeis",84,1),new r("ados",-1,1),new r("idos",-1,1),new r("amos",-1,1),new r("áramos",90,1),new r("éramos",90,1),new r("íramos",90,1),new r("ávamos",90,1),new r("íamos",90,1),new r("aríamos",95,1),new r("eríamos",95,1),new r("iríamos",95,1),new r("emos",-1,1),new r("aremos",99,1),new r("eremos",99,1),new r("iremos",99,1),new r("ássemos",99,1),new r("êssemos",99,1),new r("íssemos",99,1),new r("imos",-1,1),new r("armos",-1,1),new r("ermos",-1,1),new r("irmos",-1,1),new r("ámos",-1,1),new r("arás",-1,1),new r("erás",-1,1),new r("irás",-1,1),new r("eu",-1,1),new r("iu",-1,1),new r("ou",-1,1),new r("ará",-1,1),new r("erá",-1,1),new r("irá",-1,1)],W=[new r("a",-1,1),new r("i",-1,1),new r("o",-1,1),new r("os",-1,1),new r("á",-1,1),new r("í",-1,1),new r("ó",-1,1)],L=[new r("e",-1,1),new r("ç",-1,2),new r("é",-1,1),new r("ê",-1,1)],y=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,3,19,12,2],z=new s;this.setCurrent=function(e){z.setCurrent(e)},this.getCurrent=function(){return z.getCurrent()},this.stem=function(){var r=z.cursor;return e(),z.cursor=r,a(),z.limit_backward=r,z.cursor=z.limit,_(),z.cursor=z.limit,p(),z.cursor=z.limit_backward,u(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.pt.stemmer,"stemmer-pt"),e.pt.stopWordFilter=e.generateStopWordFilter("a ao aos aquela aquelas aquele aqueles aquilo as até com como da das de dela delas dele deles depois do dos e ela elas ele eles em entre era eram essa essas esse esses esta estamos estas estava estavam este esteja estejam estejamos estes esteve estive estivemos estiver estivera estiveram estiverem estivermos estivesse estivessem estivéramos estivéssemos estou está estávamos estão eu foi fomos for fora foram forem formos fosse fossem fui fôramos fôssemos haja hajam hajamos havemos hei houve houvemos houver houvera houveram houverei houverem houveremos houveria houveriam houvermos houverá houverão houveríamos houvesse houvessem houvéramos houvéssemos há hão isso isto já lhe lhes mais mas me mesmo meu meus minha minhas muito na nas nem no nos nossa nossas nosso nossos num numa não nós o os ou para pela pelas pelo pelos por qual quando que quem se seja sejam sejamos sem serei seremos seria seriam será serão seríamos seu seus somos sou sua suas são só também te tem temos tenha tenham tenhamos tenho terei teremos teria teriam terá terão teríamos teu teus teve tinha tinham tive tivemos tiver tivera tiveram tiverem tivermos tivesse tivessem tivéramos tivéssemos tu tua tuas tém tínhamos um uma você vocês vos à às éramos".split(" ")),e.Pipeline.registerFunction(e.pt.stopWordFilter,"stopWordFilter-pt")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.ro.min.js b/assets/javascripts/lunr/min/lunr.ro.min.js new file mode 100644 index 000000000..727714018 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.ro.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Romanian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ro=function(){this.pipeline.reset(),this.pipeline.add(e.ro.trimmer,e.ro.stopWordFilter,e.ro.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ro.stemmer))},e.ro.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.ro.trimmer=e.trimmerSupport.generateTrimmer(e.ro.wordCharacters),e.Pipeline.registerFunction(e.ro.trimmer,"trimmer-ro"),e.ro.stemmer=function(){var i=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,n=new function(){function e(e,i){L.eq_s(1,e)&&(L.ket=L.cursor,L.in_grouping(W,97,259)&&L.slice_from(i))}function n(){for(var i,r;;){if(i=L.cursor,L.in_grouping(W,97,259)&&(r=L.cursor,L.bra=r,e("u","U"),L.cursor=r,e("i","I")),L.cursor=i,L.cursor>=L.limit)break;L.cursor++}}function t(){if(L.out_grouping(W,97,259)){for(;!L.in_grouping(W,97,259);){if(L.cursor>=L.limit)return!0;L.cursor++}return!1}return!0}function a(){if(L.in_grouping(W,97,259))for(;!L.out_grouping(W,97,259);){if(L.cursor>=L.limit)return!0;L.cursor++}return!1}function o(){var e,i,r=L.cursor;if(L.in_grouping(W,97,259)){if(e=L.cursor,!t())return void(h=L.cursor);if(L.cursor=e,!a())return void(h=L.cursor)}L.cursor=r,L.out_grouping(W,97,259)&&(i=L.cursor,t()&&(L.cursor=i,L.in_grouping(W,97,259)&&L.cursor=L.limit)return!1;L.cursor++}for(;!L.out_grouping(W,97,259);){if(L.cursor>=L.limit)return!1;L.cursor++}return!0}function c(){var e=L.cursor;h=L.limit,k=h,g=h,o(),L.cursor=e,u()&&(k=L.cursor,u()&&(g=L.cursor))}function s(){for(var e;;){if(L.bra=L.cursor,e=L.find_among(z,3))switch(L.ket=L.cursor,e){case 1:L.slice_from("i");continue;case 2:L.slice_from("u");continue;case 3:if(L.cursor>=L.limit)break;L.cursor++;continue}break}}function w(){return h<=L.cursor}function m(){return k<=L.cursor}function l(){return g<=L.cursor}function f(){var e,i;if(L.ket=L.cursor,(e=L.find_among_b(C,16))&&(L.bra=L.cursor,m()))switch(e){case 1:L.slice_del();break;case 2:L.slice_from("a");break;case 3:L.slice_from("e");break;case 4:L.slice_from("i");break;case 5:i=L.limit-L.cursor,L.eq_s_b(2,"ab")||(L.cursor=L.limit-i,L.slice_from("i"));break;case 6:L.slice_from("at");break;case 7:L.slice_from("aţi")}}function p(){var e,i=L.limit-L.cursor;if(L.ket=L.cursor,(e=L.find_among_b(P,46))&&(L.bra=L.cursor,m())){switch(e){case 1:L.slice_from("abil");break;case 2:L.slice_from("ibil");break;case 3:L.slice_from("iv");break;case 4:L.slice_from("ic");break;case 5:L.slice_from("at");break;case 6:L.slice_from("it")}return _=!0,L.cursor=L.limit-i,!0}return!1}function d(){var e,i;for(_=!1;;)if(i=L.limit-L.cursor,!p()){L.cursor=L.limit-i;break}if(L.ket=L.cursor,(e=L.find_among_b(F,62))&&(L.bra=L.cursor,l())){switch(e){case 1:L.slice_del();break;case 2:L.eq_s_b(1,"ţ")&&(L.bra=L.cursor,L.slice_from("t"));break;case 3:L.slice_from("ist")}_=!0}}function b(){var e,i,r;if(L.cursor>=h){if(i=L.limit_backward,L.limit_backward=h,L.ket=L.cursor,e=L.find_among_b(q,94))switch(L.bra=L.cursor,e){case 1:if(r=L.limit-L.cursor,!L.out_grouping_b(W,97,259)&&(L.cursor=L.limit-r,!L.eq_s_b(1,"u")))break;case 2:L.slice_del()}L.limit_backward=i}}function v(){var e;L.ket=L.cursor,(e=L.find_among_b(S,5))&&(L.bra=L.cursor,w()&&1==e&&L.slice_del())}var _,g,k,h,z=[new i("",-1,3),new i("I",0,1),new i("U",0,2)],C=[new i("ea",-1,3),new i("aţia",-1,7),new i("aua",-1,2),new i("iua",-1,4),new i("aţie",-1,7),new i("ele",-1,3),new i("ile",-1,5),new i("iile",6,4),new i("iei",-1,4),new i("atei",-1,6),new i("ii",-1,4),new i("ului",-1,1),new i("ul",-1,1),new i("elor",-1,3),new i("ilor",-1,4),new i("iilor",14,4)],P=[new i("icala",-1,4),new i("iciva",-1,4),new i("ativa",-1,5),new i("itiva",-1,6),new i("icale",-1,4),new i("aţiune",-1,5),new i("iţiune",-1,6),new i("atoare",-1,5),new i("itoare",-1,6),new i("ătoare",-1,5),new i("icitate",-1,4),new i("abilitate",-1,1),new i("ibilitate",-1,2),new i("ivitate",-1,3),new i("icive",-1,4),new i("ative",-1,5),new i("itive",-1,6),new i("icali",-1,4),new i("atori",-1,5),new i("icatori",18,4),new i("itori",-1,6),new i("ători",-1,5),new i("icitati",-1,4),new i("abilitati",-1,1),new i("ivitati",-1,3),new i("icivi",-1,4),new i("ativi",-1,5),new i("itivi",-1,6),new i("icităi",-1,4),new i("abilităi",-1,1),new i("ivităi",-1,3),new i("icităţi",-1,4),new i("abilităţi",-1,1),new i("ivităţi",-1,3),new i("ical",-1,4),new i("ator",-1,5),new i("icator",35,4),new i("itor",-1,6),new i("ător",-1,5),new i("iciv",-1,4),new i("ativ",-1,5),new i("itiv",-1,6),new i("icală",-1,4),new i("icivă",-1,4),new i("ativă",-1,5),new i("itivă",-1,6)],F=[new i("ica",-1,1),new i("abila",-1,1),new i("ibila",-1,1),new i("oasa",-1,1),new i("ata",-1,1),new i("ita",-1,1),new i("anta",-1,1),new i("ista",-1,3),new i("uta",-1,1),new i("iva",-1,1),new i("ic",-1,1),new i("ice",-1,1),new i("abile",-1,1),new i("ibile",-1,1),new i("isme",-1,3),new i("iune",-1,2),new i("oase",-1,1),new i("ate",-1,1),new i("itate",17,1),new i("ite",-1,1),new i("ante",-1,1),new i("iste",-1,3),new i("ute",-1,1),new i("ive",-1,1),new i("ici",-1,1),new i("abili",-1,1),new i("ibili",-1,1),new i("iuni",-1,2),new i("atori",-1,1),new i("osi",-1,1),new i("ati",-1,1),new i("itati",30,1),new i("iti",-1,1),new i("anti",-1,1),new i("isti",-1,3),new i("uti",-1,1),new i("işti",-1,3),new i("ivi",-1,1),new i("ităi",-1,1),new i("oşi",-1,1),new i("ităţi",-1,1),new i("abil",-1,1),new i("ibil",-1,1),new i("ism",-1,3),new i("ator",-1,1),new i("os",-1,1),new i("at",-1,1),new i("it",-1,1),new i("ant",-1,1),new i("ist",-1,3),new i("ut",-1,1),new i("iv",-1,1),new i("ică",-1,1),new i("abilă",-1,1),new i("ibilă",-1,1),new i("oasă",-1,1),new i("ată",-1,1),new i("ită",-1,1),new i("antă",-1,1),new i("istă",-1,3),new i("ută",-1,1),new i("ivă",-1,1)],q=[new i("ea",-1,1),new i("ia",-1,1),new i("esc",-1,1),new i("ăsc",-1,1),new i("ind",-1,1),new i("ând",-1,1),new i("are",-1,1),new i("ere",-1,1),new i("ire",-1,1),new i("âre",-1,1),new i("se",-1,2),new i("ase",10,1),new i("sese",10,2),new i("ise",10,1),new i("use",10,1),new i("âse",10,1),new i("eşte",-1,1),new i("ăşte",-1,1),new i("eze",-1,1),new i("ai",-1,1),new i("eai",19,1),new i("iai",19,1),new i("sei",-1,2),new i("eşti",-1,1),new i("ăşti",-1,1),new i("ui",-1,1),new i("ezi",-1,1),new i("âi",-1,1),new i("aşi",-1,1),new i("seşi",-1,2),new i("aseşi",29,1),new i("seseşi",29,2),new i("iseşi",29,1),new i("useşi",29,1),new i("âseşi",29,1),new i("işi",-1,1),new i("uşi",-1,1),new i("âşi",-1,1),new i("aţi",-1,2),new i("eaţi",38,1),new i("iaţi",38,1),new i("eţi",-1,2),new i("iţi",-1,2),new i("âţi",-1,2),new i("arăţi",-1,1),new i("serăţi",-1,2),new i("aserăţi",45,1),new i("seserăţi",45,2),new i("iserăţi",45,1),new i("userăţi",45,1),new i("âserăţi",45,1),new i("irăţi",-1,1),new i("urăţi",-1,1),new i("ârăţi",-1,1),new i("am",-1,1),new i("eam",54,1),new i("iam",54,1),new i("em",-1,2),new i("asem",57,1),new i("sesem",57,2),new i("isem",57,1),new i("usem",57,1),new i("âsem",57,1),new i("im",-1,2),new i("âm",-1,2),new i("ăm",-1,2),new i("arăm",65,1),new i("serăm",65,2),new i("aserăm",67,1),new i("seserăm",67,2),new i("iserăm",67,1),new i("userăm",67,1),new i("âserăm",67,1),new i("irăm",65,1),new i("urăm",65,1),new i("ârăm",65,1),new i("au",-1,1),new i("eau",76,1),new i("iau",76,1),new i("indu",-1,1),new i("ându",-1,1),new i("ez",-1,1),new i("ească",-1,1),new i("ară",-1,1),new i("seră",-1,2),new i("aseră",84,1),new i("seseră",84,2),new i("iseră",84,1),new i("useră",84,1),new i("âseră",84,1),new i("iră",-1,1),new i("ură",-1,1),new i("âră",-1,1),new i("ează",-1,1)],S=[new i("a",-1,1),new i("e",-1,1),new i("ie",1,1),new i("i",-1,1),new i("ă",-1,1)],W=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,2,32,0,0,4],L=new r;this.setCurrent=function(e){L.setCurrent(e)},this.getCurrent=function(){return L.getCurrent()},this.stem=function(){var e=L.cursor;return n(),L.cursor=e,c(),L.limit_backward=e,L.cursor=L.limit,f(),L.cursor=L.limit,d(),L.cursor=L.limit,_||(L.cursor=L.limit,b(),L.cursor=L.limit),v(),L.cursor=L.limit_backward,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.ro.stemmer,"stemmer-ro"),e.ro.stopWordFilter=e.generateStopWordFilter("acea aceasta această aceea acei aceia acel acela acele acelea acest acesta aceste acestea aceşti aceştia acolo acord acum ai aia aibă aici al ale alea altceva altcineva am ar are asemenea asta astea astăzi asupra au avea avem aveţi azi aş aşadar aţi bine bucur bună ca care caut ce cel ceva chiar cinci cine cineva contra cu cum cumva curând curînd când cât câte câtva câţi cînd cît cîte cîtva cîţi că căci cărei căror cărui către da dacă dar datorită dată dau de deci deja deoarece departe deşi din dinaintea dintr- dintre doi doilea două drept după dă ea ei el ele eram este eu eşti face fata fi fie fiecare fii fim fiu fiţi frumos fără graţie halbă iar ieri la le li lor lui lângă lîngă mai mea mei mele mereu meu mi mie mine mult multă mulţi mulţumesc mâine mîine mă ne nevoie nici nicăieri nimeni nimeri nimic nişte noastre noastră noi noroc nostru nouă noştri nu opt ori oricare orice oricine oricum oricând oricât oricînd oricît oriunde patra patru patrulea pe pentru peste pic poate pot prea prima primul prin puţin puţina puţină până pînă rog sa sale sau se spate spre sub sunt suntem sunteţi sută sînt sîntem sînteţi să săi său ta tale te timp tine toate toată tot totuşi toţi trei treia treilea tu tăi tău un una unde undeva unei uneia unele uneori unii unor unora unu unui unuia unul vi voastre voastră voi vostru vouă voştri vreme vreo vreun vă zece zero zi zice îi îl îmi împotriva în înainte înaintea încotro încât încît între întrucât întrucît îţi ăla ălea ăsta ăstea ăştia şapte şase şi ştiu ţi ţie".split(" ")),e.Pipeline.registerFunction(e.ro.stopWordFilter,"stopWordFilter-ro")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.ru.min.js b/assets/javascripts/lunr/min/lunr.ru.min.js new file mode 100644 index 000000000..186cc485c --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.ru.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Russian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ru=function(){this.pipeline.reset(),this.pipeline.add(e.ru.trimmer,e.ru.stopWordFilter,e.ru.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ru.stemmer))},e.ru.wordCharacters="Ѐ-҄҇-ԯᴫᵸⷠ-ⷿꙀ-ꚟ︮︯",e.ru.trimmer=e.trimmerSupport.generateTrimmer(e.ru.wordCharacters),e.Pipeline.registerFunction(e.ru.trimmer,"trimmer-ru"),e.ru.stemmer=function(){var n=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,t=new function(){function e(){for(;!W.in_grouping(S,1072,1103);){if(W.cursor>=W.limit)return!1;W.cursor++}return!0}function t(){for(;!W.out_grouping(S,1072,1103);){if(W.cursor>=W.limit)return!1;W.cursor++}return!0}function w(){b=W.limit,_=b,e()&&(b=W.cursor,t()&&e()&&t()&&(_=W.cursor))}function i(){return _<=W.cursor}function u(e,n){var r,t;if(W.ket=W.cursor,r=W.find_among_b(e,n)){switch(W.bra=W.cursor,r){case 1:if(t=W.limit-W.cursor,!W.eq_s_b(1,"а")&&(W.cursor=W.limit-t,!W.eq_s_b(1,"я")))return!1;case 2:W.slice_del()}return!0}return!1}function o(){return u(h,9)}function s(e,n){var r;return W.ket=W.cursor,!!(r=W.find_among_b(e,n))&&(W.bra=W.cursor,1==r&&W.slice_del(),!0)}function c(){return s(g,26)}function m(){return!!c()&&(u(C,8),!0)}function f(){return s(k,2)}function l(){return u(P,46)}function a(){s(v,36)}function p(){var e;W.ket=W.cursor,(e=W.find_among_b(F,2))&&(W.bra=W.cursor,i()&&1==e&&W.slice_del())}function d(){var e;if(W.ket=W.cursor,e=W.find_among_b(q,4))switch(W.bra=W.cursor,e){case 1:if(W.slice_del(),W.ket=W.cursor,!W.eq_s_b(1,"н"))break;W.bra=W.cursor;case 2:if(!W.eq_s_b(1,"н"))break;case 3:W.slice_del()}}var _,b,h=[new n("в",-1,1),new n("ив",0,2),new n("ыв",0,2),new n("вши",-1,1),new n("ивши",3,2),new n("ывши",3,2),new n("вшись",-1,1),new n("ившись",6,2),new n("ывшись",6,2)],g=[new n("ее",-1,1),new n("ие",-1,1),new n("ое",-1,1),new n("ые",-1,1),new n("ими",-1,1),new n("ыми",-1,1),new n("ей",-1,1),new n("ий",-1,1),new n("ой",-1,1),new n("ый",-1,1),new n("ем",-1,1),new n("им",-1,1),new n("ом",-1,1),new n("ым",-1,1),new n("его",-1,1),new n("ого",-1,1),new n("ему",-1,1),new n("ому",-1,1),new n("их",-1,1),new n("ых",-1,1),new n("ею",-1,1),new n("ою",-1,1),new n("ую",-1,1),new n("юю",-1,1),new n("ая",-1,1),new n("яя",-1,1)],C=[new n("ем",-1,1),new n("нн",-1,1),new n("вш",-1,1),new n("ивш",2,2),new n("ывш",2,2),new n("щ",-1,1),new n("ющ",5,1),new n("ующ",6,2)],k=[new n("сь",-1,1),new n("ся",-1,1)],P=[new n("ла",-1,1),new n("ила",0,2),new n("ыла",0,2),new n("на",-1,1),new n("ена",3,2),new n("ете",-1,1),new n("ите",-1,2),new n("йте",-1,1),new n("ейте",7,2),new n("уйте",7,2),new n("ли",-1,1),new n("или",10,2),new n("ыли",10,2),new n("й",-1,1),new n("ей",13,2),new n("уй",13,2),new n("л",-1,1),new n("ил",16,2),new n("ыл",16,2),new n("ем",-1,1),new n("им",-1,2),new n("ым",-1,2),new n("н",-1,1),new n("ен",22,2),new n("ло",-1,1),new n("ило",24,2),new n("ыло",24,2),new n("но",-1,1),new n("ено",27,2),new n("нно",27,1),new n("ет",-1,1),new n("ует",30,2),new n("ит",-1,2),new n("ыт",-1,2),new n("ют",-1,1),new n("уют",34,2),new n("ят",-1,2),new n("ны",-1,1),new n("ены",37,2),new n("ть",-1,1),new n("ить",39,2),new n("ыть",39,2),new n("ешь",-1,1),new n("ишь",-1,2),new n("ю",-1,2),new n("ую",44,2)],v=[new n("а",-1,1),new n("ев",-1,1),new n("ов",-1,1),new n("е",-1,1),new n("ие",3,1),new n("ье",3,1),new n("и",-1,1),new n("еи",6,1),new n("ии",6,1),new n("ами",6,1),new n("ями",6,1),new n("иями",10,1),new n("й",-1,1),new n("ей",12,1),new n("ией",13,1),new n("ий",12,1),new n("ой",12,1),new n("ам",-1,1),new n("ем",-1,1),new n("ием",18,1),new n("ом",-1,1),new n("ям",-1,1),new n("иям",21,1),new n("о",-1,1),new n("у",-1,1),new n("ах",-1,1),new n("ях",-1,1),new n("иях",26,1),new n("ы",-1,1),new n("ь",-1,1),new n("ю",-1,1),new n("ию",30,1),new n("ью",30,1),new n("я",-1,1),new n("ия",33,1),new n("ья",33,1)],F=[new n("ост",-1,1),new n("ость",-1,1)],q=[new n("ейше",-1,1),new n("н",-1,2),new n("ейш",-1,1),new n("ь",-1,3)],S=[33,65,8,232],W=new r;this.setCurrent=function(e){W.setCurrent(e)},this.getCurrent=function(){return W.getCurrent()},this.stem=function(){return w(),W.cursor=W.limit,!(W.cursor=i&&(e-=i,t[e>>3]&1<<(7&e)))return this.cursor++,!0}return!1},in_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e<=s&&e>=i&&(e-=i,t[e>>3]&1<<(7&e)))return this.cursor--,!0}return!1},out_grouping:function(t,i,s){if(this.cursors||e>3]&1<<(7&e)))return this.cursor++,!0}return!1},out_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e>s||e>3]&1<<(7&e)))return this.cursor--,!0}return!1},eq_s:function(t,i){if(this.limit-this.cursor>1),f=0,l=o0||e==s||c)break;c=!0}}for(;;){var _=t[s];if(o>=_.s_size){if(this.cursor=n+_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n+_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},find_among_b:function(t,i){for(var s=0,e=i,n=this.cursor,u=this.limit_backward,o=0,h=0,c=!1;;){for(var a=s+(e-s>>1),f=0,l=o=0;m--){if(n-l==u){f=-1;break}if(f=r.charCodeAt(n-1-l)-_.s[m])break;l++}if(f<0?(e=a,h=l):(s=a,o=l),e-s<=1){if(s>0||e==s||c)break;c=!0}}for(;;){var _=t[s];if(o>=_.s_size){if(this.cursor=n-_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n-_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},replace_s:function(t,i,s){var e=s.length-(i-t),n=r.substring(0,t),u=r.substring(i);return r=n+s+u,this.limit+=e,this.cursor>=i?this.cursor+=e:this.cursor>t&&(this.cursor=t),e},slice_check:function(){if(this.bra<0||this.bra>this.ket||this.ket>this.limit||this.limit>r.length)throw"faulty slice operation"},slice_from:function(r){this.slice_check(),this.replace_s(this.bra,this.ket,r)},slice_del:function(){this.slice_from("")},insert:function(r,t,i){var s=this.replace_s(r,t,i);r<=this.bra&&(this.bra+=s),r<=this.ket&&(this.ket+=s)},slice_to:function(){return this.slice_check(),r.substring(this.bra,this.ket)},eq_v_b:function(r){return this.eq_s_b(r.length,r)}}}},r.trimmerSupport={generateTrimmer:function(r){var t=new RegExp("^[^"+r+"]+"),i=new RegExp("[^"+r+"]+$");return function(r){return"function"==typeof r.update?r.update(function(r){return r.replace(t,"").replace(i,"")}):r.replace(t,"").replace(i,"")}}}}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.sv.min.js b/assets/javascripts/lunr/min/lunr.sv.min.js new file mode 100644 index 000000000..3e5eb6400 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.sv.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Swedish` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.sv=function(){this.pipeline.reset(),this.pipeline.add(e.sv.trimmer,e.sv.stopWordFilter,e.sv.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.sv.stemmer))},e.sv.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.sv.trimmer=e.trimmerSupport.generateTrimmer(e.sv.wordCharacters),e.Pipeline.registerFunction(e.sv.trimmer,"trimmer-sv"),e.sv.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,t=new function(){function e(){var e,r=w.cursor+3;if(o=w.limit,0<=r||r<=w.limit){for(a=r;;){if(e=w.cursor,w.in_grouping(l,97,246)){w.cursor=e;break}if(w.cursor=e,w.cursor>=w.limit)return;w.cursor++}for(;!w.out_grouping(l,97,246);){if(w.cursor>=w.limit)return;w.cursor++}o=w.cursor,o=o&&(w.limit_backward=o,w.cursor=w.limit,w.ket=w.cursor,e=w.find_among_b(u,37),w.limit_backward=r,e))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:w.in_grouping_b(d,98,121)&&w.slice_del()}}function i(){var e=w.limit_backward;w.cursor>=o&&(w.limit_backward=o,w.cursor=w.limit,w.find_among_b(c,7)&&(w.cursor=w.limit,w.ket=w.cursor,w.cursor>w.limit_backward&&(w.bra=--w.cursor,w.slice_del())),w.limit_backward=e)}function s(){var e,r;if(w.cursor>=o){if(r=w.limit_backward,w.limit_backward=o,w.cursor=w.limit,w.ket=w.cursor,e=w.find_among_b(m,5))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:w.slice_from("lös");break;case 3:w.slice_from("full")}w.limit_backward=r}}var a,o,u=[new r("a",-1,1),new r("arna",0,1),new r("erna",0,1),new r("heterna",2,1),new r("orna",0,1),new r("ad",-1,1),new r("e",-1,1),new r("ade",6,1),new r("ande",6,1),new r("arne",6,1),new r("are",6,1),new r("aste",6,1),new r("en",-1,1),new r("anden",12,1),new r("aren",12,1),new r("heten",12,1),new r("ern",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",18,1),new r("or",-1,1),new r("s",-1,2),new r("as",21,1),new r("arnas",22,1),new r("ernas",22,1),new r("ornas",22,1),new r("es",21,1),new r("ades",26,1),new r("andes",26,1),new r("ens",21,1),new r("arens",29,1),new r("hetens",29,1),new r("erns",21,1),new r("at",-1,1),new r("andet",-1,1),new r("het",-1,1),new r("ast",-1,1)],c=[new r("dd",-1,-1),new r("gd",-1,-1),new r("nn",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1),new r("tt",-1,-1)],m=[new r("ig",-1,1),new r("lig",0,1),new r("els",-1,1),new r("fullt",-1,3),new r("löst",-1,2)],l=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,24,0,32],d=[119,127,149],w=new n;this.setCurrent=function(e){w.setCurrent(e)},this.getCurrent=function(){return w.getCurrent()},this.stem=function(){var r=w.cursor;return e(),w.limit_backward=r,w.cursor=w.limit,t(),w.cursor=w.limit,i(),w.cursor=w.limit,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return t.setCurrent(e),t.stem(),t.getCurrent()}):(t.setCurrent(e),t.stem(),t.getCurrent())}}(),e.Pipeline.registerFunction(e.sv.stemmer,"stemmer-sv"),e.sv.stopWordFilter=e.generateStopWordFilter("alla allt att av blev bli blir blivit de dem den denna deras dess dessa det detta dig din dina ditt du där då efter ej eller en er era ert ett från för ha hade han hans har henne hennes hon honom hur här i icke ingen inom inte jag ju kan kunde man med mellan men mig min mina mitt mot mycket ni nu när någon något några och om oss på samma sedan sig sin sina sitta själv skulle som så sådan sådana sådant till under upp ut utan vad var vara varför varit varje vars vart vem vi vid vilka vilkas vilken vilket vår våra vårt än är åt över".split(" ")),e.Pipeline.registerFunction(e.sv.stopWordFilter,"stopWordFilter-sv")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.th.min.js b/assets/javascripts/lunr/min/lunr.th.min.js new file mode 100644 index 000000000..dee3aac6e --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.th.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.th=function(){this.pipeline.reset(),this.pipeline.add(e.th.trimmer),r?this.tokenizer=e.th.tokenizer:(e.tokenizer&&(e.tokenizer=e.th.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.th.tokenizer))},e.th.wordCharacters="[฀-๿]",e.th.trimmer=e.trimmerSupport.generateTrimmer(e.th.wordCharacters),e.Pipeline.registerFunction(e.th.trimmer,"trimmer-th");var t=e.wordcut;t.init(),e.th.tokenizer=function(i){if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(t){return r?new e.Token(t):t});var n=i.toString().replace(/^\s+/,"");return t.cut(n).split("|")}}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.tr.min.js b/assets/javascripts/lunr/min/lunr.tr.min.js new file mode 100644 index 000000000..563f6ec1f --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.tr.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Turkish` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(r,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(r.lunr)}(this,function(){return function(r){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");r.tr=function(){this.pipeline.reset(),this.pipeline.add(r.tr.trimmer,r.tr.stopWordFilter,r.tr.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(r.tr.stemmer))},r.tr.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",r.tr.trimmer=r.trimmerSupport.generateTrimmer(r.tr.wordCharacters),r.Pipeline.registerFunction(r.tr.trimmer,"trimmer-tr"),r.tr.stemmer=function(){var i=r.stemmerSupport.Among,e=r.stemmerSupport.SnowballProgram,n=new function(){function r(r,i,e){for(;;){var n=Dr.limit-Dr.cursor;if(Dr.in_grouping_b(r,i,e)){Dr.cursor=Dr.limit-n;break}if(Dr.cursor=Dr.limit-n,Dr.cursor<=Dr.limit_backward)return!1;Dr.cursor--}return!0}function n(){var i,e;i=Dr.limit-Dr.cursor,r(Wr,97,305);for(var n=0;nDr.limit_backward&&(Dr.cursor--,e=Dr.limit-Dr.cursor,i()))?(Dr.cursor=Dr.limit-e,!0):(Dr.cursor=Dr.limit-n,r()?(Dr.cursor=Dr.limit-n,!1):(Dr.cursor=Dr.limit-n,!(Dr.cursor<=Dr.limit_backward)&&(Dr.cursor--,!!i()&&(Dr.cursor=Dr.limit-n,!0))))}function u(r){return t(r,function(){return Dr.in_grouping_b(Wr,97,305)})}function o(){return u(function(){return Dr.eq_s_b(1,"n")})}function s(){return u(function(){return Dr.eq_s_b(1,"s")})}function c(){return u(function(){return Dr.eq_s_b(1,"y")})}function l(){return t(function(){return Dr.in_grouping_b(Lr,105,305)},function(){return Dr.out_grouping_b(Wr,97,305)})}function a(){return Dr.find_among_b(ur,10)&&l()}function m(){return n()&&Dr.in_grouping_b(Lr,105,305)&&s()}function d(){return Dr.find_among_b(or,2)}function f(){return n()&&Dr.in_grouping_b(Lr,105,305)&&c()}function b(){return n()&&Dr.find_among_b(sr,4)}function w(){return n()&&Dr.find_among_b(cr,4)&&o()}function _(){return n()&&Dr.find_among_b(lr,2)&&c()}function k(){return n()&&Dr.find_among_b(ar,2)}function p(){return n()&&Dr.find_among_b(mr,4)}function g(){return n()&&Dr.find_among_b(dr,2)}function y(){return n()&&Dr.find_among_b(fr,4)}function z(){return n()&&Dr.find_among_b(br,2)}function v(){return n()&&Dr.find_among_b(wr,2)&&c()}function h(){return Dr.eq_s_b(2,"ki")}function q(){return n()&&Dr.find_among_b(_r,2)&&o()}function C(){return n()&&Dr.find_among_b(kr,4)&&c()}function P(){return n()&&Dr.find_among_b(pr,4)}function F(){return n()&&Dr.find_among_b(gr,4)&&c()}function S(){return Dr.find_among_b(yr,4)}function W(){return n()&&Dr.find_among_b(zr,2)}function L(){return n()&&Dr.find_among_b(vr,4)}function x(){return n()&&Dr.find_among_b(hr,8)}function A(){return Dr.find_among_b(qr,2)}function E(){return n()&&Dr.find_among_b(Cr,32)&&c()}function j(){return Dr.find_among_b(Pr,8)&&c()}function T(){return n()&&Dr.find_among_b(Fr,4)&&c()}function Z(){return Dr.eq_s_b(3,"ken")&&c()}function B(){var r=Dr.limit-Dr.cursor;return!(T()||(Dr.cursor=Dr.limit-r,E()||(Dr.cursor=Dr.limit-r,j()||(Dr.cursor=Dr.limit-r,Z()))))}function D(){if(A()){var r=Dr.limit-Dr.cursor;if(S()||(Dr.cursor=Dr.limit-r,W()||(Dr.cursor=Dr.limit-r,C()||(Dr.cursor=Dr.limit-r,P()||(Dr.cursor=Dr.limit-r,F()||(Dr.cursor=Dr.limit-r))))),T())return!1}return!0}function G(){if(W()){Dr.bra=Dr.cursor,Dr.slice_del();var r=Dr.limit-Dr.cursor;return Dr.ket=Dr.cursor,x()||(Dr.cursor=Dr.limit-r,E()||(Dr.cursor=Dr.limit-r,j()||(Dr.cursor=Dr.limit-r,T()||(Dr.cursor=Dr.limit-r)))),nr=!1,!1}return!0}function H(){if(!L())return!0;var r=Dr.limit-Dr.cursor;return!E()&&(Dr.cursor=Dr.limit-r,!j())}function I(){var r,i=Dr.limit-Dr.cursor;return!(S()||(Dr.cursor=Dr.limit-i,F()||(Dr.cursor=Dr.limit-i,P()||(Dr.cursor=Dr.limit-i,C()))))||(Dr.bra=Dr.cursor,Dr.slice_del(),r=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,T()||(Dr.cursor=Dr.limit-r),!1)}function J(){var r,i=Dr.limit-Dr.cursor;if(Dr.ket=Dr.cursor,nr=!0,B()&&(Dr.cursor=Dr.limit-i,D()&&(Dr.cursor=Dr.limit-i,G()&&(Dr.cursor=Dr.limit-i,H()&&(Dr.cursor=Dr.limit-i,I()))))){if(Dr.cursor=Dr.limit-i,!x())return;Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,r=Dr.limit-Dr.cursor,S()||(Dr.cursor=Dr.limit-r,W()||(Dr.cursor=Dr.limit-r,C()||(Dr.cursor=Dr.limit-r,P()||(Dr.cursor=Dr.limit-r,F()||(Dr.cursor=Dr.limit-r))))),T()||(Dr.cursor=Dr.limit-r)}Dr.bra=Dr.cursor,Dr.slice_del()}function K(){var r,i,e,n;if(Dr.ket=Dr.cursor,h()){if(r=Dr.limit-Dr.cursor,p())return Dr.bra=Dr.cursor,Dr.slice_del(),i=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,W()?(Dr.bra=Dr.cursor,Dr.slice_del(),K()):(Dr.cursor=Dr.limit-i,a()&&(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()))),!0;if(Dr.cursor=Dr.limit-r,w()){if(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,e=Dr.limit-Dr.cursor,d())Dr.bra=Dr.cursor,Dr.slice_del();else{if(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,!a()&&(Dr.cursor=Dr.limit-e,!m()&&(Dr.cursor=Dr.limit-e,!K())))return!0;Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K())}return!0}if(Dr.cursor=Dr.limit-r,g()){if(n=Dr.limit-Dr.cursor,d())Dr.bra=Dr.cursor,Dr.slice_del();else if(Dr.cursor=Dr.limit-n,m())Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K());else if(Dr.cursor=Dr.limit-n,!K())return!1;return!0}}return!1}function M(r){if(Dr.ket=Dr.cursor,!g()&&(Dr.cursor=Dr.limit-r,!k()))return!1;var i=Dr.limit-Dr.cursor;if(d())Dr.bra=Dr.cursor,Dr.slice_del();else if(Dr.cursor=Dr.limit-i,m())Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K());else if(Dr.cursor=Dr.limit-i,!K())return!1;return!0}function N(r){if(Dr.ket=Dr.cursor,!z()&&(Dr.cursor=Dr.limit-r,!b()))return!1;var i=Dr.limit-Dr.cursor;return!(!m()&&(Dr.cursor=Dr.limit-i,!d()))&&(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()),!0)}function O(){var r,i=Dr.limit-Dr.cursor;return Dr.ket=Dr.cursor,!(!w()&&(Dr.cursor=Dr.limit-i,!v()))&&(Dr.bra=Dr.cursor,Dr.slice_del(),r=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,!(!W()||(Dr.bra=Dr.cursor,Dr.slice_del(),!K()))||(Dr.cursor=Dr.limit-r,Dr.ket=Dr.cursor,!(a()||(Dr.cursor=Dr.limit-r,m()||(Dr.cursor=Dr.limit-r,K())))||(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()),!0)))}function Q(){var r,i,e=Dr.limit-Dr.cursor;if(Dr.ket=Dr.cursor,!p()&&(Dr.cursor=Dr.limit-e,!f()&&(Dr.cursor=Dr.limit-e,!_())))return!1;if(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,r=Dr.limit-Dr.cursor,a())Dr.bra=Dr.cursor,Dr.slice_del(),i=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,W()||(Dr.cursor=Dr.limit-i);else if(Dr.cursor=Dr.limit-r,!W())return!0;return Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,K(),!0}function R(){var r,i,e=Dr.limit-Dr.cursor;if(Dr.ket=Dr.cursor,W())return Dr.bra=Dr.cursor,Dr.slice_del(),void K();if(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,q())if(Dr.bra=Dr.cursor,Dr.slice_del(),r=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,d())Dr.bra=Dr.cursor,Dr.slice_del();else{if(Dr.cursor=Dr.limit-r,Dr.ket=Dr.cursor,!a()&&(Dr.cursor=Dr.limit-r,!m())){if(Dr.cursor=Dr.limit-r,Dr.ket=Dr.cursor,!W())return;if(Dr.bra=Dr.cursor,Dr.slice_del(),!K())return}Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K())}else if(Dr.cursor=Dr.limit-e,!M(e)&&(Dr.cursor=Dr.limit-e,!N(e))){if(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,y())return Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,i=Dr.limit-Dr.cursor,void(a()?(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K())):(Dr.cursor=Dr.limit-i,W()?(Dr.bra=Dr.cursor,Dr.slice_del(),K()):(Dr.cursor=Dr.limit-i,K())));if(Dr.cursor=Dr.limit-e,!O()){if(Dr.cursor=Dr.limit-e,d())return Dr.bra=Dr.cursor,void Dr.slice_del();Dr.cursor=Dr.limit-e,K()||(Dr.cursor=Dr.limit-e,Q()||(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,(a()||(Dr.cursor=Dr.limit-e,m()))&&(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()))))}}}function U(){var r;if(Dr.ket=Dr.cursor,r=Dr.find_among_b(Sr,4))switch(Dr.bra=Dr.cursor,r){case 1:Dr.slice_from("p");break;case 2:Dr.slice_from("ç");break;case 3:Dr.slice_from("t");break;case 4:Dr.slice_from("k")}}function V(){for(;;){var r=Dr.limit-Dr.cursor;if(Dr.in_grouping_b(Wr,97,305)){Dr.cursor=Dr.limit-r;break}if(Dr.cursor=Dr.limit-r,Dr.cursor<=Dr.limit_backward)return!1;Dr.cursor--}return!0}function X(r,i,e){if(Dr.cursor=Dr.limit-r,V()){var n=Dr.limit-Dr.cursor;if(!Dr.eq_s_b(1,i)&&(Dr.cursor=Dr.limit-n,!Dr.eq_s_b(1,e)))return!0;Dr.cursor=Dr.limit-r;var t=Dr.cursor;return Dr.insert(Dr.cursor,Dr.cursor,e),Dr.cursor=t,!1}return!0}function Y(){var r=Dr.limit-Dr.cursor;(Dr.eq_s_b(1,"d")||(Dr.cursor=Dr.limit-r,Dr.eq_s_b(1,"g")))&&X(r,"a","ı")&&X(r,"e","i")&&X(r,"o","u")&&X(r,"ö","ü")}function $(){for(var r,i=Dr.cursor,e=2;;){for(r=Dr.cursor;!Dr.in_grouping(Wr,97,305);){if(Dr.cursor>=Dr.limit)return Dr.cursor=r,!(e>0)&&(Dr.cursor=i,!0);Dr.cursor++}e--}}function rr(r,i,e){for(;!Dr.eq_s(i,e);){if(Dr.cursor>=Dr.limit)return!0;Dr.cursor++}return(tr=i)!=Dr.limit||(Dr.cursor=r,!1)}function ir(){var r=Dr.cursor;return!rr(r,2,"ad")||(Dr.cursor=r,!rr(r,5,"soyad"))}function er(){var r=Dr.cursor;return!ir()&&(Dr.limit_backward=r,Dr.cursor=Dr.limit,Y(),Dr.cursor=Dr.limit,U(),!0)}var nr,tr,ur=[new i("m",-1,-1),new i("n",-1,-1),new i("miz",-1,-1),new i("niz",-1,-1),new i("muz",-1,-1),new i("nuz",-1,-1),new i("müz",-1,-1),new i("nüz",-1,-1),new i("mız",-1,-1),new i("nız",-1,-1)],or=[new i("leri",-1,-1),new i("ları",-1,-1)],sr=[new i("ni",-1,-1),new i("nu",-1,-1),new i("nü",-1,-1),new i("nı",-1,-1)],cr=[new i("in",-1,-1),new i("un",-1,-1),new i("ün",-1,-1),new i("ın",-1,-1)],lr=[new i("a",-1,-1),new i("e",-1,-1)],ar=[new i("na",-1,-1),new i("ne",-1,-1)],mr=[new i("da",-1,-1),new i("ta",-1,-1),new i("de",-1,-1),new i("te",-1,-1)],dr=[new i("nda",-1,-1),new i("nde",-1,-1)],fr=[new i("dan",-1,-1),new i("tan",-1,-1),new i("den",-1,-1),new i("ten",-1,-1)],br=[new i("ndan",-1,-1),new i("nden",-1,-1)],wr=[new i("la",-1,-1),new i("le",-1,-1)],_r=[new i("ca",-1,-1),new i("ce",-1,-1)],kr=[new i("im",-1,-1),new i("um",-1,-1),new i("üm",-1,-1),new i("ım",-1,-1)],pr=[new i("sin",-1,-1),new i("sun",-1,-1),new i("sün",-1,-1),new i("sın",-1,-1)],gr=[new i("iz",-1,-1),new i("uz",-1,-1),new i("üz",-1,-1),new i("ız",-1,-1)],yr=[new i("siniz",-1,-1),new i("sunuz",-1,-1),new i("sünüz",-1,-1),new i("sınız",-1,-1)],zr=[new i("lar",-1,-1),new i("ler",-1,-1)],vr=[new i("niz",-1,-1),new i("nuz",-1,-1),new i("nüz",-1,-1),new i("nız",-1,-1)],hr=[new i("dir",-1,-1),new i("tir",-1,-1),new i("dur",-1,-1),new i("tur",-1,-1),new i("dür",-1,-1),new i("tür",-1,-1),new i("dır",-1,-1),new i("tır",-1,-1)],qr=[new i("casına",-1,-1),new i("cesine",-1,-1)],Cr=[new i("di",-1,-1),new i("ti",-1,-1),new i("dik",-1,-1),new i("tik",-1,-1),new i("duk",-1,-1),new i("tuk",-1,-1),new i("dük",-1,-1),new i("tük",-1,-1),new i("dık",-1,-1),new i("tık",-1,-1),new i("dim",-1,-1),new i("tim",-1,-1),new i("dum",-1,-1),new i("tum",-1,-1),new i("düm",-1,-1),new i("tüm",-1,-1),new i("dım",-1,-1),new i("tım",-1,-1),new i("din",-1,-1),new i("tin",-1,-1),new i("dun",-1,-1),new i("tun",-1,-1),new i("dün",-1,-1),new i("tün",-1,-1),new i("dın",-1,-1),new i("tın",-1,-1),new i("du",-1,-1),new i("tu",-1,-1),new i("dü",-1,-1),new i("tü",-1,-1),new i("dı",-1,-1),new i("tı",-1,-1)],Pr=[new i("sa",-1,-1),new i("se",-1,-1),new i("sak",-1,-1),new i("sek",-1,-1),new i("sam",-1,-1),new i("sem",-1,-1),new i("san",-1,-1),new i("sen",-1,-1)],Fr=[new i("miş",-1,-1),new i("muş",-1,-1),new i("müş",-1,-1),new i("mış",-1,-1)],Sr=[new i("b",-1,1),new i("c",-1,2),new i("d",-1,3),new i("ğ",-1,4)],Wr=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,8,0,0,0,0,0,0,1],Lr=[1,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,1],xr=[1,64,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],Ar=[17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,130],Er=[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],jr=[17],Tr=[65],Zr=[65],Br=[["a",xr,97,305],["e",Ar,101,252],["ı",Er,97,305],["i",jr,101,105],["o",Tr,111,117],["ö",Zr,246,252],["u",Tr,111,117]],Dr=new e;this.setCurrent=function(r){Dr.setCurrent(r)},this.getCurrent=function(){return Dr.getCurrent()},this.stem=function(){return!!($()&&(Dr.limit_backward=Dr.cursor,Dr.cursor=Dr.limit,J(),Dr.cursor=Dr.limit,nr&&(R(),Dr.cursor=Dr.limit_backward,er())))}};return function(r){return"function"==typeof r.update?r.update(function(r){return n.setCurrent(r),n.stem(),n.getCurrent()}):(n.setCurrent(r),n.stem(),n.getCurrent())}}(),r.Pipeline.registerFunction(r.tr.stemmer,"stemmer-tr"),r.tr.stopWordFilter=r.generateStopWordFilter("acaba altmış altı ama ancak arada aslında ayrıca bana bazı belki ben benden beni benim beri beş bile bin bir biri birkaç birkez birçok birşey birşeyi biz bizden bize bizi bizim bu buna bunda bundan bunlar bunları bunların bunu bunun burada böyle böylece da daha dahi de defa değil diye diğer doksan dokuz dolayı dolayısıyla dört edecek eden ederek edilecek ediliyor edilmesi ediyor elli en etmesi etti ettiği ettiğini eğer gibi göre halen hangi hatta hem henüz hep hepsi her herhangi herkesin hiç hiçbir iki ile ilgili ise itibaren itibariyle için işte kadar karşın katrilyon kendi kendilerine kendini kendisi kendisine kendisini kez ki kim kimden kime kimi kimse kırk milyar milyon mu mü mı nasıl ne neden nedenle nerde nerede nereye niye niçin o olan olarak oldu olduklarını olduğu olduğunu olmadı olmadığı olmak olması olmayan olmaz olsa olsun olup olur olursa oluyor on ona ondan onlar onlardan onları onların onu onun otuz oysa pek rağmen sadece sanki sekiz seksen sen senden seni senin siz sizden sizi sizin tarafından trilyon tüm var vardı ve veya ya yani yapacak yapmak yaptı yaptıkları yaptığı yaptığını yapılan yapılması yapıyor yedi yerine yetmiş yine yirmi yoksa yüz zaten çok çünkü öyle üzere üç şey şeyden şeyi şeyler şu şuna şunda şundan şunları şunu şöyle".split(" ")),r.Pipeline.registerFunction(r.tr.stopWordFilter,"stopWordFilter-tr")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.vi.min.js b/assets/javascripts/lunr/min/lunr.vi.min.js new file mode 100644 index 000000000..22aed28c4 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.vi.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.vi=function(){this.pipeline.reset(),this.pipeline.add(e.vi.stopWordFilter,e.vi.trimmer)},e.vi.wordCharacters="[A-Za-ẓ̀͐́͑̉̃̓ÂâÊêÔôĂ-ăĐ-đƠ-ơƯ-ư]",e.vi.trimmer=e.trimmerSupport.generateTrimmer(e.vi.wordCharacters),e.Pipeline.registerFunction(e.vi.trimmer,"trimmer-vi"),e.vi.stopWordFilter=e.generateStopWordFilter("là cái nhưng mà".split(" "))}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.zh.min.js b/assets/javascripts/lunr/min/lunr.zh.min.js new file mode 100644 index 000000000..7727bbe24 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.zh.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r(require("nodejieba")):r()(e.lunr)}(this,function(e){return function(r,t){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var i="2"==r.version[0];r.zh=function(){this.pipeline.reset(),this.pipeline.add(r.zh.trimmer,r.zh.stopWordFilter,r.zh.stemmer),i?this.tokenizer=r.zh.tokenizer:(r.tokenizer&&(r.tokenizer=r.zh.tokenizer),this.tokenizerFn&&(this.tokenizerFn=r.zh.tokenizer))},r.zh.tokenizer=function(n){if(!arguments.length||null==n||void 0==n)return[];if(Array.isArray(n))return n.map(function(e){return i?new r.Token(e.toLowerCase()):e.toLowerCase()});t&&e.load(t);var o=n.toString().trim().toLowerCase(),s=[];e.cut(o,!0).forEach(function(e){s=s.concat(e.split(" "))}),s=s.filter(function(e){return!!e});var u=0;return s.map(function(e,t){if(i){var n=o.indexOf(e,u),s={};return s.position=[n,e.length],s.index=t,u=n,new r.Token(e,s)}return e})},r.zh.wordCharacters="\\w一-龥",r.zh.trimmer=r.trimmerSupport.generateTrimmer(r.zh.wordCharacters),r.Pipeline.registerFunction(r.zh.trimmer,"trimmer-zh"),r.zh.stemmer=function(){return function(e){return e}}(),r.Pipeline.registerFunction(r.zh.stemmer,"stemmer-zh"),r.zh.stopWordFilter=r.generateStopWordFilter("的 一 不 在 人 有 是 为 以 于 上 他 而 后 之 来 及 了 因 下 可 到 由 这 与 也 此 但 并 个 其 已 无 小 我 们 起 最 再 今 去 好 只 又 或 很 亦 某 把 那 你 乃 它 吧 被 比 别 趁 当 从 到 得 打 凡 儿 尔 该 各 给 跟 和 何 还 即 几 既 看 据 距 靠 啦 了 另 么 每 们 嘛 拿 哪 那 您 凭 且 却 让 仍 啥 如 若 使 谁 虽 随 同 所 她 哇 嗡 往 哪 些 向 沿 哟 用 于 咱 则 怎 曾 至 致 着 诸 自".split(" ")),r.Pipeline.registerFunction(r.zh.stopWordFilter,"stopWordFilter-zh")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/tinyseg.js b/assets/javascripts/lunr/tinyseg.js new file mode 100644 index 000000000..167fa6dd6 --- /dev/null +++ b/assets/javascripts/lunr/tinyseg.js @@ -0,0 +1,206 @@ +/** + * export the module via AMD, CommonJS or as a browser global + * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js + */ +;(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory) + } else if (typeof exports === 'object') { + /** + * Node. Does not work with strict CommonJS, but + * only CommonJS-like environments that support module.exports, + * like Node. + */ + module.exports = factory() + } else { + // Browser globals (root is window) + factory()(root.lunr); + } +}(this, function () { + /** + * Just return a value to define the module export. + * This example returns an object, but the module + * can return a function as the exported value. + */ + + return function(lunr) { + // TinySegmenter 0.1 -- Super compact Japanese tokenizer in Javascript + // (c) 2008 Taku Kudo + // TinySegmenter is freely distributable under the terms of a new BSD licence. + // For details, see http://chasen.org/~taku/software/TinySegmenter/LICENCE.txt + + function TinySegmenter() { + var patterns = { + "[一二三四五六七八九十百千万億兆]":"M", + "[一-龠々〆ヵヶ]":"H", + "[ぁ-ん]":"I", + "[ァ-ヴーア-ン゙ー]":"K", + "[a-zA-Za-zA-Z]":"A", + "[0-90-9]":"N" + } + this.chartype_ = []; + for (var i in patterns) { + var regexp = new RegExp(i); + this.chartype_.push([regexp, patterns[i]]); + } + + this.BIAS__ = -332 + this.BC1__ = {"HH":6,"II":2461,"KH":406,"OH":-1378}; + this.BC2__ = {"AA":-3267,"AI":2744,"AN":-878,"HH":-4070,"HM":-1711,"HN":4012,"HO":3761,"IA":1327,"IH":-1184,"II":-1332,"IK":1721,"IO":5492,"KI":3831,"KK":-8741,"MH":-3132,"MK":3334,"OO":-2920}; + this.BC3__ = {"HH":996,"HI":626,"HK":-721,"HN":-1307,"HO":-836,"IH":-301,"KK":2762,"MK":1079,"MM":4034,"OA":-1652,"OH":266}; + this.BP1__ = {"BB":295,"OB":304,"OO":-125,"UB":352}; + this.BP2__ = {"BO":60,"OO":-1762}; + this.BQ1__ = {"BHH":1150,"BHM":1521,"BII":-1158,"BIM":886,"BMH":1208,"BNH":449,"BOH":-91,"BOO":-2597,"OHI":451,"OIH":-296,"OKA":1851,"OKH":-1020,"OKK":904,"OOO":2965}; + this.BQ2__ = {"BHH":118,"BHI":-1159,"BHM":466,"BIH":-919,"BKK":-1720,"BKO":864,"OHH":-1139,"OHM":-181,"OIH":153,"UHI":-1146}; + this.BQ3__ = {"BHH":-792,"BHI":2664,"BII":-299,"BKI":419,"BMH":937,"BMM":8335,"BNN":998,"BOH":775,"OHH":2174,"OHM":439,"OII":280,"OKH":1798,"OKI":-793,"OKO":-2242,"OMH":-2402,"OOO":11699}; + this.BQ4__ = {"BHH":-3895,"BIH":3761,"BII":-4654,"BIK":1348,"BKK":-1806,"BMI":-3385,"BOO":-12396,"OAH":926,"OHH":266,"OHK":-2036,"ONN":-973}; + this.BW1__ = {",と":660,",同":727,"B1あ":1404,"B1同":542,"、と":660,"、同":727,"」と":1682,"あっ":1505,"いう":1743,"いっ":-2055,"いる":672,"うし":-4817,"うん":665,"から":3472,"がら":600,"こう":-790,"こと":2083,"こん":-1262,"さら":-4143,"さん":4573,"した":2641,"して":1104,"すで":-3399,"そこ":1977,"それ":-871,"たち":1122,"ため":601,"った":3463,"つい":-802,"てい":805,"てき":1249,"でき":1127,"です":3445,"では":844,"とい":-4915,"とみ":1922,"どこ":3887,"ない":5713,"なっ":3015,"など":7379,"なん":-1113,"にし":2468,"には":1498,"にも":1671,"に対":-912,"の一":-501,"の中":741,"ませ":2448,"まで":1711,"まま":2600,"まる":-2155,"やむ":-1947,"よっ":-2565,"れた":2369,"れで":-913,"をし":1860,"を見":731,"亡く":-1886,"京都":2558,"取り":-2784,"大き":-2604,"大阪":1497,"平方":-2314,"引き":-1336,"日本":-195,"本当":-2423,"毎日":-2113,"目指":-724,"B1あ":1404,"B1同":542,"」と":1682}; + this.BW2__ = {"..":-11822,"11":-669,"――":-5730,"−−":-13175,"いう":-1609,"うか":2490,"かし":-1350,"かも":-602,"から":-7194,"かれ":4612,"がい":853,"がら":-3198,"きた":1941,"くな":-1597,"こと":-8392,"この":-4193,"させ":4533,"され":13168,"さん":-3977,"しい":-1819,"しか":-545,"した":5078,"して":972,"しな":939,"その":-3744,"たい":-1253,"たた":-662,"ただ":-3857,"たち":-786,"たと":1224,"たは":-939,"った":4589,"って":1647,"っと":-2094,"てい":6144,"てき":3640,"てく":2551,"ては":-3110,"ても":-3065,"でい":2666,"でき":-1528,"でし":-3828,"です":-4761,"でも":-4203,"とい":1890,"とこ":-1746,"とと":-2279,"との":720,"とみ":5168,"とも":-3941,"ない":-2488,"なが":-1313,"など":-6509,"なの":2614,"なん":3099,"にお":-1615,"にし":2748,"にな":2454,"によ":-7236,"に対":-14943,"に従":-4688,"に関":-11388,"のか":2093,"ので":-7059,"のに":-6041,"のの":-6125,"はい":1073,"はが":-1033,"はず":-2532,"ばれ":1813,"まし":-1316,"まで":-6621,"まれ":5409,"めて":-3153,"もい":2230,"もの":-10713,"らか":-944,"らし":-1611,"らに":-1897,"りし":651,"りま":1620,"れた":4270,"れて":849,"れば":4114,"ろう":6067,"われ":7901,"を通":-11877,"んだ":728,"んな":-4115,"一人":602,"一方":-1375,"一日":970,"一部":-1051,"上が":-4479,"会社":-1116,"出て":2163,"分の":-7758,"同党":970,"同日":-913,"大阪":-2471,"委員":-1250,"少な":-1050,"年度":-8669,"年間":-1626,"府県":-2363,"手権":-1982,"新聞":-4066,"日新":-722,"日本":-7068,"日米":3372,"曜日":-601,"朝鮮":-2355,"本人":-2697,"東京":-1543,"然と":-1384,"社会":-1276,"立て":-990,"第に":-1612,"米国":-4268,"11":-669}; + this.BW3__ = {"あた":-2194,"あり":719,"ある":3846,"い.":-1185,"い。":-1185,"いい":5308,"いえ":2079,"いく":3029,"いた":2056,"いっ":1883,"いる":5600,"いわ":1527,"うち":1117,"うと":4798,"えと":1454,"か.":2857,"か。":2857,"かけ":-743,"かっ":-4098,"かに":-669,"から":6520,"かり":-2670,"が,":1816,"が、":1816,"がき":-4855,"がけ":-1127,"がっ":-913,"がら":-4977,"がり":-2064,"きた":1645,"けど":1374,"こと":7397,"この":1542,"ころ":-2757,"さい":-714,"さを":976,"し,":1557,"し、":1557,"しい":-3714,"した":3562,"して":1449,"しな":2608,"しま":1200,"す.":-1310,"す。":-1310,"する":6521,"ず,":3426,"ず、":3426,"ずに":841,"そう":428,"た.":8875,"た。":8875,"たい":-594,"たの":812,"たり":-1183,"たる":-853,"だ.":4098,"だ。":4098,"だっ":1004,"った":-4748,"って":300,"てい":6240,"てお":855,"ても":302,"です":1437,"でに":-1482,"では":2295,"とう":-1387,"とし":2266,"との":541,"とも":-3543,"どう":4664,"ない":1796,"なく":-903,"など":2135,"に,":-1021,"に、":-1021,"にし":1771,"にな":1906,"には":2644,"の,":-724,"の、":-724,"の子":-1000,"は,":1337,"は、":1337,"べき":2181,"まし":1113,"ます":6943,"まっ":-1549,"まで":6154,"まれ":-793,"らし":1479,"られ":6820,"るる":3818,"れ,":854,"れ、":854,"れた":1850,"れて":1375,"れば":-3246,"れる":1091,"われ":-605,"んだ":606,"んで":798,"カ月":990,"会議":860,"入り":1232,"大会":2217,"始め":1681,"市":965,"新聞":-5055,"日,":974,"日、":974,"社会":2024,"カ月":990}; + this.TC1__ = {"AAA":1093,"HHH":1029,"HHM":580,"HII":998,"HOH":-390,"HOM":-331,"IHI":1169,"IOH":-142,"IOI":-1015,"IOM":467,"MMH":187,"OOI":-1832}; + this.TC2__ = {"HHO":2088,"HII":-1023,"HMM":-1154,"IHI":-1965,"KKH":703,"OII":-2649}; + this.TC3__ = {"AAA":-294,"HHH":346,"HHI":-341,"HII":-1088,"HIK":731,"HOH":-1486,"IHH":128,"IHI":-3041,"IHO":-1935,"IIH":-825,"IIM":-1035,"IOI":-542,"KHH":-1216,"KKA":491,"KKH":-1217,"KOK":-1009,"MHH":-2694,"MHM":-457,"MHO":123,"MMH":-471,"NNH":-1689,"NNO":662,"OHO":-3393}; + this.TC4__ = {"HHH":-203,"HHI":1344,"HHK":365,"HHM":-122,"HHN":182,"HHO":669,"HIH":804,"HII":679,"HOH":446,"IHH":695,"IHO":-2324,"IIH":321,"III":1497,"IIO":656,"IOO":54,"KAK":4845,"KKA":3386,"KKK":3065,"MHH":-405,"MHI":201,"MMH":-241,"MMM":661,"MOM":841}; + this.TQ1__ = {"BHHH":-227,"BHHI":316,"BHIH":-132,"BIHH":60,"BIII":1595,"BNHH":-744,"BOHH":225,"BOOO":-908,"OAKK":482,"OHHH":281,"OHIH":249,"OIHI":200,"OIIH":-68}; + this.TQ2__ = {"BIHH":-1401,"BIII":-1033,"BKAK":-543,"BOOO":-5591}; + this.TQ3__ = {"BHHH":478,"BHHM":-1073,"BHIH":222,"BHII":-504,"BIIH":-116,"BIII":-105,"BMHI":-863,"BMHM":-464,"BOMH":620,"OHHH":346,"OHHI":1729,"OHII":997,"OHMH":481,"OIHH":623,"OIIH":1344,"OKAK":2792,"OKHH":587,"OKKA":679,"OOHH":110,"OOII":-685}; + this.TQ4__ = {"BHHH":-721,"BHHM":-3604,"BHII":-966,"BIIH":-607,"BIII":-2181,"OAAA":-2763,"OAKK":180,"OHHH":-294,"OHHI":2446,"OHHO":480,"OHIH":-1573,"OIHH":1935,"OIHI":-493,"OIIH":626,"OIII":-4007,"OKAK":-8156}; + this.TW1__ = {"につい":-4681,"東京都":2026}; + this.TW2__ = {"ある程":-2049,"いった":-1256,"ころが":-2434,"しょう":3873,"その後":-4430,"だって":-1049,"ていた":1833,"として":-4657,"ともに":-4517,"もので":1882,"一気に":-792,"初めて":-1512,"同時に":-8097,"大きな":-1255,"対して":-2721,"社会党":-3216}; + this.TW3__ = {"いただ":-1734,"してい":1314,"として":-4314,"につい":-5483,"にとっ":-5989,"に当た":-6247,"ので,":-727,"ので、":-727,"のもの":-600,"れから":-3752,"十二月":-2287}; + this.TW4__ = {"いう.":8576,"いう。":8576,"からな":-2348,"してい":2958,"たが,":1516,"たが、":1516,"ている":1538,"という":1349,"ました":5543,"ません":1097,"ようと":-4258,"よると":5865}; + this.UC1__ = {"A":484,"K":93,"M":645,"O":-505}; + this.UC2__ = {"A":819,"H":1059,"I":409,"M":3987,"N":5775,"O":646}; + this.UC3__ = {"A":-1370,"I":2311}; + this.UC4__ = {"A":-2643,"H":1809,"I":-1032,"K":-3450,"M":3565,"N":3876,"O":6646}; + this.UC5__ = {"H":313,"I":-1238,"K":-799,"M":539,"O":-831}; + this.UC6__ = {"H":-506,"I":-253,"K":87,"M":247,"O":-387}; + this.UP1__ = {"O":-214}; + this.UP2__ = {"B":69,"O":935}; + this.UP3__ = {"B":189}; + this.UQ1__ = {"BH":21,"BI":-12,"BK":-99,"BN":142,"BO":-56,"OH":-95,"OI":477,"OK":410,"OO":-2422}; + this.UQ2__ = {"BH":216,"BI":113,"OK":1759}; + this.UQ3__ = {"BA":-479,"BH":42,"BI":1913,"BK":-7198,"BM":3160,"BN":6427,"BO":14761,"OI":-827,"ON":-3212}; + this.UW1__ = {",":156,"、":156,"「":-463,"あ":-941,"う":-127,"が":-553,"き":121,"こ":505,"で":-201,"と":-547,"ど":-123,"に":-789,"の":-185,"は":-847,"も":-466,"や":-470,"よ":182,"ら":-292,"り":208,"れ":169,"を":-446,"ん":-137,"・":-135,"主":-402,"京":-268,"区":-912,"午":871,"国":-460,"大":561,"委":729,"市":-411,"日":-141,"理":361,"生":-408,"県":-386,"都":-718,"「":-463,"・":-135}; + this.UW2__ = {",":-829,"、":-829,"〇":892,"「":-645,"」":3145,"あ":-538,"い":505,"う":134,"お":-502,"か":1454,"が":-856,"く":-412,"こ":1141,"さ":878,"ざ":540,"し":1529,"す":-675,"せ":300,"そ":-1011,"た":188,"だ":1837,"つ":-949,"て":-291,"で":-268,"と":-981,"ど":1273,"な":1063,"に":-1764,"の":130,"は":-409,"ひ":-1273,"べ":1261,"ま":600,"も":-1263,"や":-402,"よ":1639,"り":-579,"る":-694,"れ":571,"を":-2516,"ん":2095,"ア":-587,"カ":306,"キ":568,"ッ":831,"三":-758,"不":-2150,"世":-302,"中":-968,"主":-861,"事":492,"人":-123,"会":978,"保":362,"入":548,"初":-3025,"副":-1566,"北":-3414,"区":-422,"大":-1769,"天":-865,"太":-483,"子":-1519,"学":760,"実":1023,"小":-2009,"市":-813,"年":-1060,"強":1067,"手":-1519,"揺":-1033,"政":1522,"文":-1355,"新":-1682,"日":-1815,"明":-1462,"最":-630,"朝":-1843,"本":-1650,"東":-931,"果":-665,"次":-2378,"民":-180,"気":-1740,"理":752,"発":529,"目":-1584,"相":-242,"県":-1165,"立":-763,"第":810,"米":509,"自":-1353,"行":838,"西":-744,"見":-3874,"調":1010,"議":1198,"込":3041,"開":1758,"間":-1257,"「":-645,"」":3145,"ッ":831,"ア":-587,"カ":306,"キ":568}; + this.UW3__ = {",":4889,"1":-800,"−":-1723,"、":4889,"々":-2311,"〇":5827,"」":2670,"〓":-3573,"あ":-2696,"い":1006,"う":2342,"え":1983,"お":-4864,"か":-1163,"が":3271,"く":1004,"け":388,"げ":401,"こ":-3552,"ご":-3116,"さ":-1058,"し":-395,"す":584,"せ":3685,"そ":-5228,"た":842,"ち":-521,"っ":-1444,"つ":-1081,"て":6167,"で":2318,"と":1691,"ど":-899,"な":-2788,"に":2745,"の":4056,"は":4555,"ひ":-2171,"ふ":-1798,"へ":1199,"ほ":-5516,"ま":-4384,"み":-120,"め":1205,"も":2323,"や":-788,"よ":-202,"ら":727,"り":649,"る":5905,"れ":2773,"わ":-1207,"を":6620,"ん":-518,"ア":551,"グ":1319,"ス":874,"ッ":-1350,"ト":521,"ム":1109,"ル":1591,"ロ":2201,"ン":278,"・":-3794,"一":-1619,"下":-1759,"世":-2087,"両":3815,"中":653,"主":-758,"予":-1193,"二":974,"人":2742,"今":792,"他":1889,"以":-1368,"低":811,"何":4265,"作":-361,"保":-2439,"元":4858,"党":3593,"全":1574,"公":-3030,"六":755,"共":-1880,"円":5807,"再":3095,"分":457,"初":2475,"別":1129,"前":2286,"副":4437,"力":365,"動":-949,"務":-1872,"化":1327,"北":-1038,"区":4646,"千":-2309,"午":-783,"協":-1006,"口":483,"右":1233,"各":3588,"合":-241,"同":3906,"和":-837,"員":4513,"国":642,"型":1389,"場":1219,"外":-241,"妻":2016,"学":-1356,"安":-423,"実":-1008,"家":1078,"小":-513,"少":-3102,"州":1155,"市":3197,"平":-1804,"年":2416,"広":-1030,"府":1605,"度":1452,"建":-2352,"当":-3885,"得":1905,"思":-1291,"性":1822,"戸":-488,"指":-3973,"政":-2013,"教":-1479,"数":3222,"文":-1489,"新":1764,"日":2099,"旧":5792,"昨":-661,"時":-1248,"曜":-951,"最":-937,"月":4125,"期":360,"李":3094,"村":364,"東":-805,"核":5156,"森":2438,"業":484,"氏":2613,"民":-1694,"決":-1073,"法":1868,"海":-495,"無":979,"物":461,"特":-3850,"生":-273,"用":914,"町":1215,"的":7313,"直":-1835,"省":792,"県":6293,"知":-1528,"私":4231,"税":401,"立":-960,"第":1201,"米":7767,"系":3066,"約":3663,"級":1384,"統":-4229,"総":1163,"線":1255,"者":6457,"能":725,"自":-2869,"英":785,"見":1044,"調":-562,"財":-733,"費":1777,"車":1835,"軍":1375,"込":-1504,"通":-1136,"選":-681,"郎":1026,"郡":4404,"部":1200,"金":2163,"長":421,"開":-1432,"間":1302,"関":-1282,"雨":2009,"電":-1045,"非":2066,"駅":1620,"1":-800,"」":2670,"・":-3794,"ッ":-1350,"ア":551,"グ":1319,"ス":874,"ト":521,"ム":1109,"ル":1591,"ロ":2201,"ン":278}; + this.UW4__ = {",":3930,".":3508,"―":-4841,"、":3930,"。":3508,"〇":4999,"「":1895,"」":3798,"〓":-5156,"あ":4752,"い":-3435,"う":-640,"え":-2514,"お":2405,"か":530,"が":6006,"き":-4482,"ぎ":-3821,"く":-3788,"け":-4376,"げ":-4734,"こ":2255,"ご":1979,"さ":2864,"し":-843,"じ":-2506,"す":-731,"ず":1251,"せ":181,"そ":4091,"た":5034,"だ":5408,"ち":-3654,"っ":-5882,"つ":-1659,"て":3994,"で":7410,"と":4547,"な":5433,"に":6499,"ぬ":1853,"ね":1413,"の":7396,"は":8578,"ば":1940,"ひ":4249,"び":-4134,"ふ":1345,"へ":6665,"べ":-744,"ほ":1464,"ま":1051,"み":-2082,"む":-882,"め":-5046,"も":4169,"ゃ":-2666,"や":2795,"ょ":-1544,"よ":3351,"ら":-2922,"り":-9726,"る":-14896,"れ":-2613,"ろ":-4570,"わ":-1783,"を":13150,"ん":-2352,"カ":2145,"コ":1789,"セ":1287,"ッ":-724,"ト":-403,"メ":-1635,"ラ":-881,"リ":-541,"ル":-856,"ン":-3637,"・":-4371,"ー":-11870,"一":-2069,"中":2210,"予":782,"事":-190,"井":-1768,"人":1036,"以":544,"会":950,"体":-1286,"作":530,"側":4292,"先":601,"党":-2006,"共":-1212,"内":584,"円":788,"初":1347,"前":1623,"副":3879,"力":-302,"動":-740,"務":-2715,"化":776,"区":4517,"協":1013,"参":1555,"合":-1834,"和":-681,"員":-910,"器":-851,"回":1500,"国":-619,"園":-1200,"地":866,"場":-1410,"塁":-2094,"士":-1413,"多":1067,"大":571,"子":-4802,"学":-1397,"定":-1057,"寺":-809,"小":1910,"屋":-1328,"山":-1500,"島":-2056,"川":-2667,"市":2771,"年":374,"庁":-4556,"後":456,"性":553,"感":916,"所":-1566,"支":856,"改":787,"政":2182,"教":704,"文":522,"方":-856,"日":1798,"時":1829,"最":845,"月":-9066,"木":-485,"来":-442,"校":-360,"業":-1043,"氏":5388,"民":-2716,"気":-910,"沢":-939,"済":-543,"物":-735,"率":672,"球":-1267,"生":-1286,"産":-1101,"田":-2900,"町":1826,"的":2586,"目":922,"省":-3485,"県":2997,"空":-867,"立":-2112,"第":788,"米":2937,"系":786,"約":2171,"経":1146,"統":-1169,"総":940,"線":-994,"署":749,"者":2145,"能":-730,"般":-852,"行":-792,"規":792,"警":-1184,"議":-244,"谷":-1000,"賞":730,"車":-1481,"軍":1158,"輪":-1433,"込":-3370,"近":929,"道":-1291,"選":2596,"郎":-4866,"都":1192,"野":-1100,"銀":-2213,"長":357,"間":-2344,"院":-2297,"際":-2604,"電":-878,"領":-1659,"題":-792,"館":-1984,"首":1749,"高":2120,"「":1895,"」":3798,"・":-4371,"ッ":-724,"ー":-11870,"カ":2145,"コ":1789,"セ":1287,"ト":-403,"メ":-1635,"ラ":-881,"リ":-541,"ル":-856,"ン":-3637}; + this.UW5__ = {",":465,".":-299,"1":-514,"E2":-32768,"]":-2762,"、":465,"。":-299,"「":363,"あ":1655,"い":331,"う":-503,"え":1199,"お":527,"か":647,"が":-421,"き":1624,"ぎ":1971,"く":312,"げ":-983,"さ":-1537,"し":-1371,"す":-852,"だ":-1186,"ち":1093,"っ":52,"つ":921,"て":-18,"で":-850,"と":-127,"ど":1682,"な":-787,"に":-1224,"の":-635,"は":-578,"べ":1001,"み":502,"め":865,"ゃ":3350,"ょ":854,"り":-208,"る":429,"れ":504,"わ":419,"を":-1264,"ん":327,"イ":241,"ル":451,"ン":-343,"中":-871,"京":722,"会":-1153,"党":-654,"務":3519,"区":-901,"告":848,"員":2104,"大":-1296,"学":-548,"定":1785,"嵐":-1304,"市":-2991,"席":921,"年":1763,"思":872,"所":-814,"挙":1618,"新":-1682,"日":218,"月":-4353,"査":932,"格":1356,"機":-1508,"氏":-1347,"田":240,"町":-3912,"的":-3149,"相":1319,"省":-1052,"県":-4003,"研":-997,"社":-278,"空":-813,"統":1955,"者":-2233,"表":663,"語":-1073,"議":1219,"選":-1018,"郎":-368,"長":786,"間":1191,"題":2368,"館":-689,"1":-514,"E2":-32768,"「":363,"イ":241,"ル":451,"ン":-343}; + this.UW6__ = {",":227,".":808,"1":-270,"E1":306,"、":227,"。":808,"あ":-307,"う":189,"か":241,"が":-73,"く":-121,"こ":-200,"じ":1782,"す":383,"た":-428,"っ":573,"て":-1014,"で":101,"と":-105,"な":-253,"に":-149,"の":-417,"は":-236,"も":-206,"り":187,"る":-135,"を":195,"ル":-673,"ン":-496,"一":-277,"中":201,"件":-800,"会":624,"前":302,"区":1792,"員":-1212,"委":798,"学":-960,"市":887,"広":-695,"後":535,"業":-697,"相":753,"社":-507,"福":974,"空":-822,"者":1811,"連":463,"郎":1082,"1":-270,"E1":306,"ル":-673,"ン":-496}; + + return this; + } + TinySegmenter.prototype.ctype_ = function(str) { + for (var i in this.chartype_) { + if (str.match(this.chartype_[i][0])) { + return this.chartype_[i][1]; + } + } + return "O"; + } + + TinySegmenter.prototype.ts_ = function(v) { + if (v) { return v; } + return 0; + } + + TinySegmenter.prototype.segment = function(input) { + if (input == null || input == undefined || input == "") { + return []; + } + var result = []; + var seg = ["B3","B2","B1"]; + var ctype = ["O","O","O"]; + var o = input.split(""); + for (i = 0; i < o.length; ++i) { + seg.push(o[i]); + ctype.push(this.ctype_(o[i])) + } + seg.push("E1"); + seg.push("E2"); + seg.push("E3"); + ctype.push("O"); + ctype.push("O"); + ctype.push("O"); + var word = seg[3]; + var p1 = "U"; + var p2 = "U"; + var p3 = "U"; + for (var i = 4; i < seg.length - 3; ++i) { + var score = this.BIAS__; + var w1 = seg[i-3]; + var w2 = seg[i-2]; + var w3 = seg[i-1]; + var w4 = seg[i]; + var w5 = seg[i+1]; + var w6 = seg[i+2]; + var c1 = ctype[i-3]; + var c2 = ctype[i-2]; + var c3 = ctype[i-1]; + var c4 = ctype[i]; + var c5 = ctype[i+1]; + var c6 = ctype[i+2]; + score += this.ts_(this.UP1__[p1]); + score += this.ts_(this.UP2__[p2]); + score += this.ts_(this.UP3__[p3]); + score += this.ts_(this.BP1__[p1 + p2]); + score += this.ts_(this.BP2__[p2 + p3]); + score += this.ts_(this.UW1__[w1]); + score += this.ts_(this.UW2__[w2]); + score += this.ts_(this.UW3__[w3]); + score += this.ts_(this.UW4__[w4]); + score += this.ts_(this.UW5__[w5]); + score += this.ts_(this.UW6__[w6]); + score += this.ts_(this.BW1__[w2 + w3]); + score += this.ts_(this.BW2__[w3 + w4]); + score += this.ts_(this.BW3__[w4 + w5]); + score += this.ts_(this.TW1__[w1 + w2 + w3]); + score += this.ts_(this.TW2__[w2 + w3 + w4]); + score += this.ts_(this.TW3__[w3 + w4 + w5]); + score += this.ts_(this.TW4__[w4 + w5 + w6]); + score += this.ts_(this.UC1__[c1]); + score += this.ts_(this.UC2__[c2]); + score += this.ts_(this.UC3__[c3]); + score += this.ts_(this.UC4__[c4]); + score += this.ts_(this.UC5__[c5]); + score += this.ts_(this.UC6__[c6]); + score += this.ts_(this.BC1__[c2 + c3]); + score += this.ts_(this.BC2__[c3 + c4]); + score += this.ts_(this.BC3__[c4 + c5]); + score += this.ts_(this.TC1__[c1 + c2 + c3]); + score += this.ts_(this.TC2__[c2 + c3 + c4]); + score += this.ts_(this.TC3__[c3 + c4 + c5]); + score += this.ts_(this.TC4__[c4 + c5 + c6]); + // score += this.ts_(this.TC5__[c4 + c5 + c6]); + score += this.ts_(this.UQ1__[p1 + c1]); + score += this.ts_(this.UQ2__[p2 + c2]); + score += this.ts_(this.UQ3__[p3 + c3]); + score += this.ts_(this.BQ1__[p2 + c2 + c3]); + score += this.ts_(this.BQ2__[p2 + c3 + c4]); + score += this.ts_(this.BQ3__[p3 + c2 + c3]); + score += this.ts_(this.BQ4__[p3 + c3 + c4]); + score += this.ts_(this.TQ1__[p2 + c1 + c2 + c3]); + score += this.ts_(this.TQ2__[p2 + c2 + c3 + c4]); + score += this.ts_(this.TQ3__[p3 + c1 + c2 + c3]); + score += this.ts_(this.TQ4__[p3 + c2 + c3 + c4]); + var p = "O"; + if (score > 0) { + result.push(word); + word = ""; + p = "B"; + } + p1 = p2; + p2 = p3; + p3 = p; + word += seg[i]; + } + result.push(word); + + return result; + } + + lunr.TinySegmenter = TinySegmenter; + }; + +})); \ No newline at end of file diff --git a/assets/javascripts/lunr/wordcut.js b/assets/javascripts/lunr/wordcut.js new file mode 100644 index 000000000..146f4b44b --- /dev/null +++ b/assets/javascripts/lunr/wordcut.js @@ -0,0 +1,6708 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}(g.lunr || (g.lunr = {})).wordcut = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 1; + }) + this.addWords(words, false) + } + if(finalize){ + this.finalizeDict(); + } + }, + + dictSeek: function (l, r, ch, strOffset, pos) { + var ans = null; + while (l <= r) { + var m = Math.floor((l + r) / 2), + dict_item = this.dict[m], + len = dict_item.length; + if (len <= strOffset) { + l = m + 1; + } else { + var ch_ = dict_item[strOffset]; + if (ch_ < ch) { + l = m + 1; + } else if (ch_ > ch) { + r = m - 1; + } else { + ans = m; + if (pos == LEFT) { + r = m - 1; + } else { + l = m + 1; + } + } + } + } + return ans; + }, + + isFinal: function (acceptor) { + return this.dict[acceptor.l].length == acceptor.strOffset; + }, + + createAcceptor: function () { + return { + l: 0, + r: this.dict.length - 1, + strOffset: 0, + isFinal: false, + dict: this, + transit: function (ch) { + return this.dict.transit(this, ch); + }, + isError: false, + tag: "DICT", + w: 1, + type: "DICT" + }; + }, + + transit: function (acceptor, ch) { + var l = this.dictSeek(acceptor.l, + acceptor.r, + ch, + acceptor.strOffset, + LEFT); + if (l !== null) { + var r = this.dictSeek(l, + acceptor.r, + ch, + acceptor.strOffset, + RIGHT); + acceptor.l = l; + acceptor.r = r; + acceptor.strOffset++; + acceptor.isFinal = this.isFinal(acceptor); + } else { + acceptor.isError = true; + } + return acceptor; + }, + + sortuniq: function(a){ + return a.sort().filter(function(item, pos, arr){ + return !pos || item != arr[pos - 1]; + }) + }, + + flatten: function(a){ + //[[1,2],[3]] -> [1,2,3] + return [].concat.apply([], a); + } +}; +module.exports = WordcutDict; + +}).call(this,"/dist/tmp") +},{"glob":16,"path":22}],3:[function(require,module,exports){ +var WordRule = { + createAcceptor: function(tag) { + if (tag["WORD_RULE"]) + return null; + + return {strOffset: 0, + isFinal: false, + transit: function(ch) { + var lch = ch.toLowerCase(); + if (lch >= "a" && lch <= "z") { + this.isFinal = true; + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: "WORD_RULE", + type: "WORD_RULE", + w: 1}; + } +}; + +var NumberRule = { + createAcceptor: function(tag) { + if (tag["NUMBER_RULE"]) + return null; + + return {strOffset: 0, + isFinal: false, + transit: function(ch) { + if (ch >= "0" && ch <= "9") { + this.isFinal = true; + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: "NUMBER_RULE", + type: "NUMBER_RULE", + w: 1}; + } +}; + +var SpaceRule = { + tag: "SPACE_RULE", + createAcceptor: function(tag) { + + if (tag["SPACE_RULE"]) + return null; + + return {strOffset: 0, + isFinal: false, + transit: function(ch) { + if (ch == " " || ch == "\t" || ch == "\r" || ch == "\n" || + ch == "\u00A0" || ch=="\u2003"//nbsp and emsp + ) { + this.isFinal = true; + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: SpaceRule.tag, + w: 1, + type: "SPACE_RULE"}; + } +} + +var SingleSymbolRule = { + tag: "SINSYM", + createAcceptor: function(tag) { + return {strOffset: 0, + isFinal: false, + transit: function(ch) { + if (this.strOffset == 0 && ch.match(/^[\@\(\)\/\,\-\."`]$/)) { + this.isFinal = true; + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: "SINSYM", + w: 1, + type: "SINSYM"}; + } +} + + +var LatinRules = [WordRule, SpaceRule, SingleSymbolRule, NumberRule]; + +module.exports = LatinRules; + +},{}],4:[function(require,module,exports){ +var _ = require("underscore") + , WordcutCore = require("./wordcut_core"); +var PathInfoBuilder = { + + /* + buildByPartAcceptors: function(path, acceptors, i) { + var + var genInfos = partAcceptors.reduce(function(genInfos, acceptor) { + + }, []); + + return genInfos; + } + */ + + buildByAcceptors: function(path, finalAcceptors, i) { + var self = this; + var infos = finalAcceptors.map(function(acceptor) { + var p = i - acceptor.strOffset + 1 + , _info = path[p]; + + var info = {p: p, + mw: _info.mw + (acceptor.mw === undefined ? 0 : acceptor.mw), + w: acceptor.w + _info.w, + unk: (acceptor.unk ? acceptor.unk : 0) + _info.unk, + type: acceptor.type}; + + if (acceptor.type == "PART") { + for(var j = p + 1; j <= i; j++) { + path[j].merge = p; + } + info.merge = p; + } + + return info; + }); + return infos.filter(function(info) { return info; }); + }, + + fallback: function(path, leftBoundary, text, i) { + var _info = path[leftBoundary]; + if (text[i].match(/[\u0E48-\u0E4E]/)) { + if (leftBoundary != 0) + leftBoundary = path[leftBoundary].p; + return {p: leftBoundary, + mw: 0, + w: 1 + _info.w, + unk: 1 + _info.unk, + type: "UNK"}; +/* } else if(leftBoundary > 0 && path[leftBoundary].type !== "UNK") { + leftBoundary = path[leftBoundary].p; + return {p: leftBoundary, + w: 1 + _info.w, + unk: 1 + _info.unk, + type: "UNK"}; */ + } else { + return {p: leftBoundary, + mw: _info.mw, + w: 1 + _info.w, + unk: 1 + _info.unk, + type: "UNK"}; + } + }, + + build: function(path, finalAcceptors, i, leftBoundary, text) { + var basicPathInfos = this.buildByAcceptors(path, finalAcceptors, i); + if (basicPathInfos.length > 0) { + return basicPathInfos; + } else { + return [this.fallback(path, leftBoundary, text, i)]; + } + } +}; + +module.exports = function() { + return _.clone(PathInfoBuilder); +} + +},{"./wordcut_core":8,"underscore":25}],5:[function(require,module,exports){ +var _ = require("underscore"); + + +var PathSelector = { + selectPath: function(paths) { + var path = paths.reduce(function(selectedPath, path) { + if (selectedPath == null) { + return path; + } else { + if (path.unk < selectedPath.unk) + return path; + if (path.unk == selectedPath.unk) { + if (path.mw < selectedPath.mw) + return path + if (path.mw == selectedPath.mw) { + if (path.w < selectedPath.w) + return path; + } + } + return selectedPath; + } + }, null); + return path; + }, + + createPath: function() { + return [{p:null, w:0, unk:0, type: "INIT", mw:0}]; + } +}; + +module.exports = function() { + return _.clone(PathSelector); +}; + +},{"underscore":25}],6:[function(require,module,exports){ +function isMatch(pat, offset, ch) { + if (pat.length <= offset) + return false; + var _ch = pat[offset]; + return _ch == ch || + (_ch.match(/[กข]/) && ch.match(/[ก-ฮ]/)) || + (_ch.match(/[มบ]/) && ch.match(/[ก-ฮ]/)) || + (_ch.match(/\u0E49/) && ch.match(/[\u0E48-\u0E4B]/)); +} + +var Rule0 = { + pat: "เหก็ม", + createAcceptor: function(tag) { + return {strOffset: 0, + isFinal: false, + transit: function(ch) { + if (isMatch(Rule0.pat, this.strOffset,ch)) { + this.isFinal = (this.strOffset + 1 == Rule0.pat.length); + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: "THAI_RULE", + type: "THAI_RULE", + w: 1}; + } +}; + +var PartRule = { + createAcceptor: function(tag) { + return {strOffset: 0, + patterns: [ + "แก", "เก", "ก้", "กก์", "กา", "กี", "กิ", "กืก" + ], + isFinal: false, + transit: function(ch) { + var offset = this.strOffset; + this.patterns = this.patterns.filter(function(pat) { + return isMatch(pat, offset, ch); + }); + + if (this.patterns.length > 0) { + var len = 1 + offset; + this.isFinal = this.patterns.some(function(pat) { + return pat.length == len; + }); + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: "PART", + type: "PART", + unk: 1, + w: 1}; + } +}; + +var ThaiRules = [Rule0, PartRule]; + +module.exports = ThaiRules; + +},{}],7:[function(require,module,exports){ +var sys = require("sys") + , WordcutDict = require("./dict") + , WordcutCore = require("./wordcut_core") + , PathInfoBuilder = require("./path_info_builder") + , PathSelector = require("./path_selector") + , Acceptors = require("./acceptors") + , latinRules = require("./latin_rules") + , thaiRules = require("./thai_rules") + , _ = require("underscore"); + + +var Wordcut = Object.create(WordcutCore); +Wordcut.defaultPathInfoBuilder = PathInfoBuilder; +Wordcut.defaultPathSelector = PathSelector; +Wordcut.defaultAcceptors = Acceptors; +Wordcut.defaultLatinRules = latinRules; +Wordcut.defaultThaiRules = thaiRules; +Wordcut.defaultDict = WordcutDict; + + +Wordcut.initNoDict = function(dict_path) { + var self = this; + self.pathInfoBuilder = new self.defaultPathInfoBuilder; + self.pathSelector = new self.defaultPathSelector; + self.acceptors = new self.defaultAcceptors; + self.defaultLatinRules.forEach(function(rule) { + self.acceptors.creators.push(rule); + }); + self.defaultThaiRules.forEach(function(rule) { + self.acceptors.creators.push(rule); + }); +}; + +Wordcut.init = function(dict_path, withDefault, additionalWords) { + withDefault = withDefault || false; + this.initNoDict(); + var dict = _.clone(this.defaultDict); + dict.init(dict_path, withDefault, additionalWords); + this.acceptors.creators.push(dict); +}; + +module.exports = Wordcut; + +},{"./acceptors":1,"./dict":2,"./latin_rules":3,"./path_info_builder":4,"./path_selector":5,"./thai_rules":6,"./wordcut_core":8,"sys":28,"underscore":25}],8:[function(require,module,exports){ +var WordcutCore = { + + buildPath: function(text) { + var self = this + , path = self.pathSelector.createPath() + , leftBoundary = 0; + self.acceptors.reset(); + for (var i = 0; i < text.length; i++) { + var ch = text[i]; + self.acceptors.transit(ch); + + var possiblePathInfos = self + .pathInfoBuilder + .build(path, + self.acceptors.getFinalAcceptors(), + i, + leftBoundary, + text); + var selectedPath = self.pathSelector.selectPath(possiblePathInfos) + + path.push(selectedPath); + if (selectedPath.type !== "UNK") { + leftBoundary = i; + } + } + return path; + }, + + pathToRanges: function(path) { + var e = path.length - 1 + , ranges = []; + + while (e > 0) { + var info = path[e] + , s = info.p; + + if (info.merge !== undefined && ranges.length > 0) { + var r = ranges[ranges.length - 1]; + r.s = info.merge; + s = r.s; + } else { + ranges.push({s:s, e:e}); + } + e = s; + } + return ranges.reverse(); + }, + + rangesToText: function(text, ranges, delimiter) { + return ranges.map(function(r) { + return text.substring(r.s, r.e); + }).join(delimiter); + }, + + cut: function(text, delimiter) { + var path = this.buildPath(text) + , ranges = this.pathToRanges(path); + return this + .rangesToText(text, ranges, + (delimiter === undefined ? "|" : delimiter)); + }, + + cutIntoRanges: function(text, noText) { + var path = this.buildPath(text) + , ranges = this.pathToRanges(path); + + if (!noText) { + ranges.forEach(function(r) { + r.text = text.substring(r.s, r.e); + }); + } + return ranges; + }, + + cutIntoArray: function(text) { + var path = this.buildPath(text) + , ranges = this.pathToRanges(path); + + return ranges.map(function(r) { + return text.substring(r.s, r.e) + }); + } +}; + +module.exports = WordcutCore; + +},{}],9:[function(require,module,exports){ +// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 +// +// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! +// +// Originally from narwhal.js (http://narwhaljs.org) +// Copyright (c) 2009 Thomas Robinson <280north.com> +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the 'Software'), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// when used in node, this will actually load the util module we depend on +// versus loading the builtin util module as happens otherwise +// this is a bug in node module loading as far as I am concerned +var util = require('util/'); + +var pSlice = Array.prototype.slice; +var hasOwn = Object.prototype.hasOwnProperty; + +// 1. The assert module provides functions that throw +// AssertionError's when particular conditions are not met. The +// assert module must conform to the following interface. + +var assert = module.exports = ok; + +// 2. The AssertionError is defined in assert. +// new assert.AssertionError({ message: message, +// actual: actual, +// expected: expected }) + +assert.AssertionError = function AssertionError(options) { + this.name = 'AssertionError'; + this.actual = options.actual; + this.expected = options.expected; + this.operator = options.operator; + if (options.message) { + this.message = options.message; + this.generatedMessage = false; + } else { + this.message = getMessage(this); + this.generatedMessage = true; + } + var stackStartFunction = options.stackStartFunction || fail; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, stackStartFunction); + } + else { + // non v8 browsers so we can have a stacktrace + var err = new Error(); + if (err.stack) { + var out = err.stack; + + // try to strip useless frames + var fn_name = stackStartFunction.name; + var idx = out.indexOf('\n' + fn_name); + if (idx >= 0) { + // once we have located the function frame + // we need to strip out everything before it (and its line) + var next_line = out.indexOf('\n', idx + 1); + out = out.substring(next_line + 1); + } + + this.stack = out; + } + } +}; + +// assert.AssertionError instanceof Error +util.inherits(assert.AssertionError, Error); + +function replacer(key, value) { + if (util.isUndefined(value)) { + return '' + value; + } + if (util.isNumber(value) && !isFinite(value)) { + return value.toString(); + } + if (util.isFunction(value) || util.isRegExp(value)) { + return value.toString(); + } + return value; +} + +function truncate(s, n) { + if (util.isString(s)) { + return s.length < n ? s : s.slice(0, n); + } else { + return s; + } +} + +function getMessage(self) { + return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' + + self.operator + ' ' + + truncate(JSON.stringify(self.expected, replacer), 128); +} + +// At present only the three keys mentioned above are used and +// understood by the spec. Implementations or sub modules can pass +// other keys to the AssertionError's constructor - they will be +// ignored. + +// 3. All of the following functions must throw an AssertionError +// when a corresponding condition is not met, with a message that +// may be undefined if not provided. All assertion methods provide +// both the actual and expected values to the assertion error for +// display purposes. + +function fail(actual, expected, message, operator, stackStartFunction) { + throw new assert.AssertionError({ + message: message, + actual: actual, + expected: expected, + operator: operator, + stackStartFunction: stackStartFunction + }); +} + +// EXTENSION! allows for well behaved errors defined elsewhere. +assert.fail = fail; + +// 4. Pure assertion tests whether a value is truthy, as determined +// by !!guard. +// assert.ok(guard, message_opt); +// This statement is equivalent to assert.equal(true, !!guard, +// message_opt);. To test strictly for the value true, use +// assert.strictEqual(true, guard, message_opt);. + +function ok(value, message) { + if (!value) fail(value, true, message, '==', assert.ok); +} +assert.ok = ok; + +// 5. The equality assertion tests shallow, coercive equality with +// ==. +// assert.equal(actual, expected, message_opt); + +assert.equal = function equal(actual, expected, message) { + if (actual != expected) fail(actual, expected, message, '==', assert.equal); +}; + +// 6. The non-equality assertion tests for whether two objects are not equal +// with != assert.notEqual(actual, expected, message_opt); + +assert.notEqual = function notEqual(actual, expected, message) { + if (actual == expected) { + fail(actual, expected, message, '!=', assert.notEqual); + } +}; + +// 7. The equivalence assertion tests a deep equality relation. +// assert.deepEqual(actual, expected, message_opt); + +assert.deepEqual = function deepEqual(actual, expected, message) { + if (!_deepEqual(actual, expected)) { + fail(actual, expected, message, 'deepEqual', assert.deepEqual); + } +}; + +function _deepEqual(actual, expected) { + // 7.1. All identical values are equivalent, as determined by ===. + if (actual === expected) { + return true; + + } else if (util.isBuffer(actual) && util.isBuffer(expected)) { + if (actual.length != expected.length) return false; + + for (var i = 0; i < actual.length; i++) { + if (actual[i] !== expected[i]) return false; + } + + return true; + + // 7.2. If the expected value is a Date object, the actual value is + // equivalent if it is also a Date object that refers to the same time. + } else if (util.isDate(actual) && util.isDate(expected)) { + return actual.getTime() === expected.getTime(); + + // 7.3 If the expected value is a RegExp object, the actual value is + // equivalent if it is also a RegExp object with the same source and + // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). + } else if (util.isRegExp(actual) && util.isRegExp(expected)) { + return actual.source === expected.source && + actual.global === expected.global && + actual.multiline === expected.multiline && + actual.lastIndex === expected.lastIndex && + actual.ignoreCase === expected.ignoreCase; + + // 7.4. Other pairs that do not both pass typeof value == 'object', + // equivalence is determined by ==. + } else if (!util.isObject(actual) && !util.isObject(expected)) { + return actual == expected; + + // 7.5 For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical 'prototype' property. Note: this + // accounts for both named and indexed properties on Arrays. + } else { + return objEquiv(actual, expected); + } +} + +function isArguments(object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; +} + +function objEquiv(a, b) { + if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b)) + return false; + // an identical 'prototype' property. + if (a.prototype !== b.prototype) return false; + // if one is a primitive, the other must be same + if (util.isPrimitive(a) || util.isPrimitive(b)) { + return a === b; + } + var aIsArgs = isArguments(a), + bIsArgs = isArguments(b); + if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs)) + return false; + if (aIsArgs) { + a = pSlice.call(a); + b = pSlice.call(b); + return _deepEqual(a, b); + } + var ka = objectKeys(a), + kb = objectKeys(b), + key, i; + // having the same number of owned properties (keys incorporates + // hasOwnProperty) + if (ka.length != kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!_deepEqual(a[key], b[key])) return false; + } + return true; +} + +// 8. The non-equivalence assertion tests for any deep inequality. +// assert.notDeepEqual(actual, expected, message_opt); + +assert.notDeepEqual = function notDeepEqual(actual, expected, message) { + if (_deepEqual(actual, expected)) { + fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); + } +}; + +// 9. The strict equality assertion tests strict equality, as determined by ===. +// assert.strictEqual(actual, expected, message_opt); + +assert.strictEqual = function strictEqual(actual, expected, message) { + if (actual !== expected) { + fail(actual, expected, message, '===', assert.strictEqual); + } +}; + +// 10. The strict non-equality assertion tests for strict inequality, as +// determined by !==. assert.notStrictEqual(actual, expected, message_opt); + +assert.notStrictEqual = function notStrictEqual(actual, expected, message) { + if (actual === expected) { + fail(actual, expected, message, '!==', assert.notStrictEqual); + } +}; + +function expectedException(actual, expected) { + if (!actual || !expected) { + return false; + } + + if (Object.prototype.toString.call(expected) == '[object RegExp]') { + return expected.test(actual); + } else if (actual instanceof expected) { + return true; + } else if (expected.call({}, actual) === true) { + return true; + } + + return false; +} + +function _throws(shouldThrow, block, expected, message) { + var actual; + + if (util.isString(expected)) { + message = expected; + expected = null; + } + + try { + block(); + } catch (e) { + actual = e; + } + + message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + + (message ? ' ' + message : '.'); + + if (shouldThrow && !actual) { + fail(actual, expected, 'Missing expected exception' + message); + } + + if (!shouldThrow && expectedException(actual, expected)) { + fail(actual, expected, 'Got unwanted exception' + message); + } + + if ((shouldThrow && actual && expected && + !expectedException(actual, expected)) || (!shouldThrow && actual)) { + throw actual; + } +} + +// 11. Expected to throw an error: +// assert.throws(block, Error_opt, message_opt); + +assert.throws = function(block, /*optional*/error, /*optional*/message) { + _throws.apply(this, [true].concat(pSlice.call(arguments))); +}; + +// EXTENSION! This is annoying to write outside this module. +assert.doesNotThrow = function(block, /*optional*/message) { + _throws.apply(this, [false].concat(pSlice.call(arguments))); +}; + +assert.ifError = function(err) { if (err) {throw err;}}; + +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) { + if (hasOwn.call(obj, key)) keys.push(key); + } + return keys; +}; + +},{"util/":28}],10:[function(require,module,exports){ +'use strict'; +module.exports = balanced; +function balanced(a, b, str) { + if (a instanceof RegExp) a = maybeMatch(a, str); + if (b instanceof RegExp) b = maybeMatch(b, str); + + var r = range(a, b, str); + + return r && { + start: r[0], + end: r[1], + pre: str.slice(0, r[0]), + body: str.slice(r[0] + a.length, r[1]), + post: str.slice(r[1] + b.length) + }; +} + +function maybeMatch(reg, str) { + var m = str.match(reg); + return m ? m[0] : null; +} + +balanced.range = range; +function range(a, b, str) { + var begs, beg, left, right, result; + var ai = str.indexOf(a); + var bi = str.indexOf(b, ai + 1); + var i = ai; + + if (ai >= 0 && bi > 0) { + begs = []; + left = str.length; + + while (i >= 0 && !result) { + if (i == ai) { + begs.push(i); + ai = str.indexOf(a, i + 1); + } else if (begs.length == 1) { + result = [ begs.pop(), bi ]; + } else { + beg = begs.pop(); + if (beg < left) { + left = beg; + right = bi; + } + + bi = str.indexOf(b, i + 1); + } + + i = ai < bi && ai >= 0 ? ai : bi; + } + + if (begs.length) { + result = [ left, right ]; + } + } + + return result; +} + +},{}],11:[function(require,module,exports){ +var concatMap = require('concat-map'); +var balanced = require('balanced-match'); + +module.exports = expandTop; + +var escSlash = '\0SLASH'+Math.random()+'\0'; +var escOpen = '\0OPEN'+Math.random()+'\0'; +var escClose = '\0CLOSE'+Math.random()+'\0'; +var escComma = '\0COMMA'+Math.random()+'\0'; +var escPeriod = '\0PERIOD'+Math.random()+'\0'; + +function numeric(str) { + return parseInt(str, 10) == str + ? parseInt(str, 10) + : str.charCodeAt(0); +} + +function escapeBraces(str) { + return str.split('\\\\').join(escSlash) + .split('\\{').join(escOpen) + .split('\\}').join(escClose) + .split('\\,').join(escComma) + .split('\\.').join(escPeriod); +} + +function unescapeBraces(str) { + return str.split(escSlash).join('\\') + .split(escOpen).join('{') + .split(escClose).join('}') + .split(escComma).join(',') + .split(escPeriod).join('.'); +} + + +// Basically just str.split(","), but handling cases +// where we have nested braced sections, which should be +// treated as individual members, like {a,{b,c},d} +function parseCommaParts(str) { + if (!str) + return ['']; + + var parts = []; + var m = balanced('{', '}', str); + + if (!m) + return str.split(','); + + var pre = m.pre; + var body = m.body; + var post = m.post; + var p = pre.split(','); + + p[p.length-1] += '{' + body + '}'; + var postParts = parseCommaParts(post); + if (post.length) { + p[p.length-1] += postParts.shift(); + p.push.apply(p, postParts); + } + + parts.push.apply(parts, p); + + return parts; +} + +function expandTop(str) { + if (!str) + return []; + + // I don't know why Bash 4.3 does this, but it does. + // Anything starting with {} will have the first two bytes preserved + // but *only* at the top level, so {},a}b will not expand to anything, + // but a{},b}c will be expanded to [a}c,abc]. + // One could argue that this is a bug in Bash, but since the goal of + // this module is to match Bash's rules, we escape a leading {} + if (str.substr(0, 2) === '{}') { + str = '\\{\\}' + str.substr(2); + } + + return expand(escapeBraces(str), true).map(unescapeBraces); +} + +function identity(e) { + return e; +} + +function embrace(str) { + return '{' + str + '}'; +} +function isPadded(el) { + return /^-?0\d/.test(el); +} + +function lte(i, y) { + return i <= y; +} +function gte(i, y) { + return i >= y; +} + +function expand(str, isTop) { + var expansions = []; + + var m = balanced('{', '}', str); + if (!m || /\$$/.test(m.pre)) return [str]; + + var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); + var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); + var isSequence = isNumericSequence || isAlphaSequence; + var isOptions = m.body.indexOf(',') >= 0; + if (!isSequence && !isOptions) { + // {a},b} + if (m.post.match(/,.*\}/)) { + str = m.pre + '{' + m.body + escClose + m.post; + return expand(str); + } + return [str]; + } + + var n; + if (isSequence) { + n = m.body.split(/\.\./); + } else { + n = parseCommaParts(m.body); + if (n.length === 1) { + // x{{a,b}}y ==> x{a}y x{b}y + n = expand(n[0], false).map(embrace); + if (n.length === 1) { + var post = m.post.length + ? expand(m.post, false) + : ['']; + return post.map(function(p) { + return m.pre + n[0] + p; + }); + } + } + } + + // at this point, n is the parts, and we know it's not a comma set + // with a single entry. + + // no need to expand pre, since it is guaranteed to be free of brace-sets + var pre = m.pre; + var post = m.post.length + ? expand(m.post, false) + : ['']; + + var N; + + if (isSequence) { + var x = numeric(n[0]); + var y = numeric(n[1]); + var width = Math.max(n[0].length, n[1].length) + var incr = n.length == 3 + ? Math.abs(numeric(n[2])) + : 1; + var test = lte; + var reverse = y < x; + if (reverse) { + incr *= -1; + test = gte; + } + var pad = n.some(isPadded); + + N = []; + + for (var i = x; test(i, y); i += incr) { + var c; + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') + c = ''; + } else { + c = String(i); + if (pad) { + var need = width - c.length; + if (need > 0) { + var z = new Array(need + 1).join('0'); + if (i < 0) + c = '-' + z + c.slice(1); + else + c = z + c; + } + } + } + N.push(c); + } + } else { + N = concatMap(n, function(el) { return expand(el, false) }); + } + + for (var j = 0; j < N.length; j++) { + for (var k = 0; k < post.length; k++) { + var expansion = pre + N[j] + post[k]; + if (!isTop || isSequence || expansion) + expansions.push(expansion); + } + } + + return expansions; +} + + +},{"balanced-match":10,"concat-map":13}],12:[function(require,module,exports){ + +},{}],13:[function(require,module,exports){ +module.exports = function (xs, fn) { + var res = []; + for (var i = 0; i < xs.length; i++) { + var x = fn(xs[i], i); + if (isArray(x)) res.push.apply(res, x); + else res.push(x); + } + return res; +}; + +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; + +},{}],14:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; +} +module.exports = EventEmitter; + +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; + +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; + +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +EventEmitter.defaultMaxListeners = 10; + +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +EventEmitter.prototype.setMaxListeners = function(n) { + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; +}; + +EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; + + if (!this._events) + this._events = {}; + + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } + throw TypeError('Uncaught, unspecified "error" event.'); + } + } + + handler = this._events[type]; + + if (isUndefined(handler)) + return false; + + if (isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + handler.apply(this, args); + } + } else if (isObject(handler)) { + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } + + return true; +}; + +EventEmitter.prototype.addListener = function(type, listener) { + var m; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events) + this._events = {}; + + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); + + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + var m; + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } + + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + if (typeof console.trace === 'function') { + // not supported in IE 10 + console.trace(); + } + } + } + + return this; +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + var fired = false; + + function g() { + this.removeListener(type, g); + + if (!fired) { + fired = true; + listener.apply(this, arguments); + } + } + + g.listener = listener; + this.on(type, g); + + return this; +}; + +// emits a 'removeListener' event iff the listener was removed +EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events || !this._events[type]) + return this; + + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } + + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } + + if (this._events.removeListener) + this.emit('removeListener', type, listener); + } + + return this; +}; + +EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = {}; + return this; + } + + listeners = this._events[type]; + + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; + + return this; +}; + +EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; +}; + +EventEmitter.listenerCount = function(emitter, type) { + var ret; + if (!emitter._events || !emitter._events[type]) + ret = 0; + else if (isFunction(emitter._events[type])) + ret = 1; + else + ret = emitter._events[type].length; + return ret; +}; + +function isFunction(arg) { + return typeof arg === 'function'; +} + +function isNumber(arg) { + return typeof arg === 'number'; +} + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} + +function isUndefined(arg) { + return arg === void 0; +} + +},{}],15:[function(require,module,exports){ +(function (process){ +exports.alphasort = alphasort +exports.alphasorti = alphasorti +exports.setopts = setopts +exports.ownProp = ownProp +exports.makeAbs = makeAbs +exports.finish = finish +exports.mark = mark +exports.isIgnored = isIgnored +exports.childrenIgnored = childrenIgnored + +function ownProp (obj, field) { + return Object.prototype.hasOwnProperty.call(obj, field) +} + +var path = require("path") +var minimatch = require("minimatch") +var isAbsolute = require("path-is-absolute") +var Minimatch = minimatch.Minimatch + +function alphasorti (a, b) { + return a.toLowerCase().localeCompare(b.toLowerCase()) +} + +function alphasort (a, b) { + return a.localeCompare(b) +} + +function setupIgnores (self, options) { + self.ignore = options.ignore || [] + + if (!Array.isArray(self.ignore)) + self.ignore = [self.ignore] + + if (self.ignore.length) { + self.ignore = self.ignore.map(ignoreMap) + } +} + +function ignoreMap (pattern) { + var gmatcher = null + if (pattern.slice(-3) === '/**') { + var gpattern = pattern.replace(/(\/\*\*)+$/, '') + gmatcher = new Minimatch(gpattern) + } + + return { + matcher: new Minimatch(pattern), + gmatcher: gmatcher + } +} + +function setopts (self, pattern, options) { + if (!options) + options = {} + + // base-matching: just use globstar for that. + if (options.matchBase && -1 === pattern.indexOf("/")) { + if (options.noglobstar) { + throw new Error("base matching requires globstar") + } + pattern = "**/" + pattern + } + + self.silent = !!options.silent + self.pattern = pattern + self.strict = options.strict !== false + self.realpath = !!options.realpath + self.realpathCache = options.realpathCache || Object.create(null) + self.follow = !!options.follow + self.dot = !!options.dot + self.mark = !!options.mark + self.nodir = !!options.nodir + if (self.nodir) + self.mark = true + self.sync = !!options.sync + self.nounique = !!options.nounique + self.nonull = !!options.nonull + self.nosort = !!options.nosort + self.nocase = !!options.nocase + self.stat = !!options.stat + self.noprocess = !!options.noprocess + + self.maxLength = options.maxLength || Infinity + self.cache = options.cache || Object.create(null) + self.statCache = options.statCache || Object.create(null) + self.symlinks = options.symlinks || Object.create(null) + + setupIgnores(self, options) + + self.changedCwd = false + var cwd = process.cwd() + if (!ownProp(options, "cwd")) + self.cwd = cwd + else { + self.cwd = options.cwd + self.changedCwd = path.resolve(options.cwd) !== cwd + } + + self.root = options.root || path.resolve(self.cwd, "/") + self.root = path.resolve(self.root) + if (process.platform === "win32") + self.root = self.root.replace(/\\/g, "/") + + self.nomount = !!options.nomount + + // disable comments and negation unless the user explicitly + // passes in false as the option. + options.nonegate = options.nonegate === false ? false : true + options.nocomment = options.nocomment === false ? false : true + deprecationWarning(options) + + self.minimatch = new Minimatch(pattern, options) + self.options = self.minimatch.options +} + +// TODO(isaacs): remove entirely in v6 +// exported to reset in tests +exports.deprecationWarned +function deprecationWarning(options) { + if (!options.nonegate || !options.nocomment) { + if (process.noDeprecation !== true && !exports.deprecationWarned) { + var msg = 'glob WARNING: comments and negation will be disabled in v6' + if (process.throwDeprecation) + throw new Error(msg) + else if (process.traceDeprecation) + console.trace(msg) + else + console.error(msg) + + exports.deprecationWarned = true + } + } +} + +function finish (self) { + var nou = self.nounique + var all = nou ? [] : Object.create(null) + + for (var i = 0, l = self.matches.length; i < l; i ++) { + var matches = self.matches[i] + if (!matches || Object.keys(matches).length === 0) { + if (self.nonull) { + // do like the shell, and spit out the literal glob + var literal = self.minimatch.globSet[i] + if (nou) + all.push(literal) + else + all[literal] = true + } + } else { + // had matches + var m = Object.keys(matches) + if (nou) + all.push.apply(all, m) + else + m.forEach(function (m) { + all[m] = true + }) + } + } + + if (!nou) + all = Object.keys(all) + + if (!self.nosort) + all = all.sort(self.nocase ? alphasorti : alphasort) + + // at *some* point we statted all of these + if (self.mark) { + for (var i = 0; i < all.length; i++) { + all[i] = self._mark(all[i]) + } + if (self.nodir) { + all = all.filter(function (e) { + return !(/\/$/.test(e)) + }) + } + } + + if (self.ignore.length) + all = all.filter(function(m) { + return !isIgnored(self, m) + }) + + self.found = all +} + +function mark (self, p) { + var abs = makeAbs(self, p) + var c = self.cache[abs] + var m = p + if (c) { + var isDir = c === 'DIR' || Array.isArray(c) + var slash = p.slice(-1) === '/' + + if (isDir && !slash) + m += '/' + else if (!isDir && slash) + m = m.slice(0, -1) + + if (m !== p) { + var mabs = makeAbs(self, m) + self.statCache[mabs] = self.statCache[abs] + self.cache[mabs] = self.cache[abs] + } + } + + return m +} + +// lotta situps... +function makeAbs (self, f) { + var abs = f + if (f.charAt(0) === '/') { + abs = path.join(self.root, f) + } else if (isAbsolute(f) || f === '') { + abs = f + } else if (self.changedCwd) { + abs = path.resolve(self.cwd, f) + } else { + abs = path.resolve(f) + } + return abs +} + + +// Return true, if pattern ends with globstar '**', for the accompanying parent directory. +// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents +function isIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) + }) +} + +function childrenIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return !!(item.gmatcher && item.gmatcher.match(path)) + }) +} + +}).call(this,require('_process')) +},{"_process":24,"minimatch":20,"path":22,"path-is-absolute":23}],16:[function(require,module,exports){ +(function (process){ +// Approach: +// +// 1. Get the minimatch set +// 2. For each pattern in the set, PROCESS(pattern, false) +// 3. Store matches per-set, then uniq them +// +// PROCESS(pattern, inGlobStar) +// Get the first [n] items from pattern that are all strings +// Join these together. This is PREFIX. +// If there is no more remaining, then stat(PREFIX) and +// add to matches if it succeeds. END. +// +// If inGlobStar and PREFIX is symlink and points to dir +// set ENTRIES = [] +// else readdir(PREFIX) as ENTRIES +// If fail, END +// +// with ENTRIES +// If pattern[n] is GLOBSTAR +// // handle the case where the globstar match is empty +// // by pruning it out, and testing the resulting pattern +// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) +// // handle other cases. +// for ENTRY in ENTRIES (not dotfiles) +// // attach globstar + tail onto the entry +// // Mark that this entry is a globstar match +// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) +// +// else // not globstar +// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) +// Test ENTRY against pattern[n] +// If fails, continue +// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) +// +// Caveat: +// Cache all stats and readdirs results to minimize syscall. Since all +// we ever care about is existence and directory-ness, we can just keep +// `true` for files, and [children,...] for directories, or `false` for +// things that don't exist. + +module.exports = glob + +var fs = require('fs') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var inherits = require('inherits') +var EE = require('events').EventEmitter +var path = require('path') +var assert = require('assert') +var isAbsolute = require('path-is-absolute') +var globSync = require('./sync.js') +var common = require('./common.js') +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var inflight = require('inflight') +var util = require('util') +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored + +var once = require('once') + +function glob (pattern, options, cb) { + if (typeof options === 'function') cb = options, options = {} + if (!options) options = {} + + if (options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return globSync(pattern, options) + } + + return new Glob(pattern, options, cb) +} + +glob.sync = globSync +var GlobSync = glob.GlobSync = globSync.GlobSync + +// old api surface +glob.glob = glob + +glob.hasMagic = function (pattern, options_) { + var options = util._extend({}, options_) + options.noprocess = true + + var g = new Glob(pattern, options) + var set = g.minimatch.set + if (set.length > 1) + return true + + for (var j = 0; j < set[0].length; j++) { + if (typeof set[0][j] !== 'string') + return true + } + + return false +} + +glob.Glob = Glob +inherits(Glob, EE) +function Glob (pattern, options, cb) { + if (typeof options === 'function') { + cb = options + options = null + } + + if (options && options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return new GlobSync(pattern, options) + } + + if (!(this instanceof Glob)) + return new Glob(pattern, options, cb) + + setopts(this, pattern, options) + this._didRealPath = false + + // process each pattern in the minimatch set + var n = this.minimatch.set.length + + // The matches are stored as {: true,...} so that + // duplicates are automagically pruned. + // Later, we do an Object.keys() on these. + // Keep them as a list so we can fill in when nonull is set. + this.matches = new Array(n) + + if (typeof cb === 'function') { + cb = once(cb) + this.on('error', cb) + this.on('end', function (matches) { + cb(null, matches) + }) + } + + var self = this + var n = this.minimatch.set.length + this._processing = 0 + this.matches = new Array(n) + + this._emitQueue = [] + this._processQueue = [] + this.paused = false + + if (this.noprocess) + return this + + if (n === 0) + return done() + + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false, done) + } + + function done () { + --self._processing + if (self._processing <= 0) + self._finish() + } +} + +Glob.prototype._finish = function () { + assert(this instanceof Glob) + if (this.aborted) + return + + if (this.realpath && !this._didRealpath) + return this._realpath() + + common.finish(this) + this.emit('end', this.found) +} + +Glob.prototype._realpath = function () { + if (this._didRealpath) + return + + this._didRealpath = true + + var n = this.matches.length + if (n === 0) + return this._finish() + + var self = this + for (var i = 0; i < this.matches.length; i++) + this._realpathSet(i, next) + + function next () { + if (--n === 0) + self._finish() + } +} + +Glob.prototype._realpathSet = function (index, cb) { + var matchset = this.matches[index] + if (!matchset) + return cb() + + var found = Object.keys(matchset) + var self = this + var n = found.length + + if (n === 0) + return cb() + + var set = this.matches[index] = Object.create(null) + found.forEach(function (p, i) { + // If there's a problem with the stat, then it means that + // one or more of the links in the realpath couldn't be + // resolved. just return the abs value in that case. + p = self._makeAbs(p) + fs.realpath(p, self.realpathCache, function (er, real) { + if (!er) + set[real] = true + else if (er.syscall === 'stat') + set[p] = true + else + self.emit('error', er) // srsly wtf right here + + if (--n === 0) { + self.matches[index] = set + cb() + } + }) + }) +} + +Glob.prototype._mark = function (p) { + return common.mark(this, p) +} + +Glob.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} + +Glob.prototype.abort = function () { + this.aborted = true + this.emit('abort') +} + +Glob.prototype.pause = function () { + if (!this.paused) { + this.paused = true + this.emit('pause') + } +} + +Glob.prototype.resume = function () { + if (this.paused) { + this.emit('resume') + this.paused = false + if (this._emitQueue.length) { + var eq = this._emitQueue.slice(0) + this._emitQueue.length = 0 + for (var i = 0; i < eq.length; i ++) { + var e = eq[i] + this._emitMatch(e[0], e[1]) + } + } + if (this._processQueue.length) { + var pq = this._processQueue.slice(0) + this._processQueue.length = 0 + for (var i = 0; i < pq.length; i ++) { + var p = pq[i] + this._processing-- + this._process(p[0], p[1], p[2], p[3]) + } + } + } +} + +Glob.prototype._process = function (pattern, index, inGlobStar, cb) { + assert(this instanceof Glob) + assert(typeof cb === 'function') + + if (this.aborted) + return + + this._processing++ + if (this.paused) { + this._processQueue.push([pattern, index, inGlobStar, cb]) + return + } + + //console.error('PROCESS %d', this._processing, pattern) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // see if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index, cb) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip _processing + if (childrenIgnored(this, read)) + return cb() + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) +} + +Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + +Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return cb() + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return cb() + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this._emitMatch(index, e) + } + // This was the last one, and no stats were needed + return cb() + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + this._process([e].concat(remain), index, inGlobStar, cb) + } + cb() +} + +Glob.prototype._emitMatch = function (index, e) { + if (this.aborted) + return + + if (this.matches[index][e]) + return + + if (isIgnored(this, e)) + return + + if (this.paused) { + this._emitQueue.push([index, e]) + return + } + + var abs = this._makeAbs(e) + + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return + } + + if (this.mark) + e = this._mark(e) + + this.matches[index][e] = true + + var st = this.statCache[abs] + if (st) + this.emit('stat', e, st) + + this.emit('match', e) +} + +Glob.prototype._readdirInGlobStar = function (abs, cb) { + if (this.aborted) + return + + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false, cb) + + var lstatkey = 'lstat\0' + abs + var self = this + var lstatcb = inflight(lstatkey, lstatcb_) + + if (lstatcb) + fs.lstat(abs, lstatcb) + + function lstatcb_ (er, lstat) { + if (er) + return cb() + + var isSym = lstat.isSymbolicLink() + self.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && !lstat.isDirectory()) { + self.cache[abs] = 'FILE' + cb() + } else + self._readdir(abs, false, cb) + } +} + +Glob.prototype._readdir = function (abs, inGlobStar, cb) { + if (this.aborted) + return + + cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) + if (!cb) + return + + //console.error('RD %j %j', +inGlobStar, abs) + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs, cb) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return cb() + + if (Array.isArray(c)) + return cb(null, c) + } + + var self = this + fs.readdir(abs, readdirCb(this, abs, cb)) +} + +function readdirCb (self, abs, cb) { + return function (er, entries) { + if (er) + self._readdirError(abs, er, cb) + else + self._readdirEntries(abs, entries, cb) + } +} + +Glob.prototype._readdirEntries = function (abs, entries, cb) { + if (this.aborted) + return + + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + return cb(null, entries) +} + +Glob.prototype._readdirError = function (f, er, cb) { + if (this.aborted) + return + + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + this.cache[this._makeAbs(f)] = 'FILE' + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) { + this.emit('error', er) + // If the error is handled, then we abort + // if not, we threw out of here + this.abort() + } + if (!this.silent) + console.error('glob error', er) + break + } + + return cb() +} + +Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + + +Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + //console.error('pgs2', prefix, remain[0], entries) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return cb() + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false, cb) + + var isSym = this.symlinks[abs] + var len = entries.length + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return cb() + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true, cb) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true, cb) + } + + cb() +} + +Glob.prototype._processSimple = function (prefix, index, cb) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var self = this + this._stat(prefix, function (er, exists) { + self._processSimple2(prefix, index, er, exists, cb) + }) +} +Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { + + //console.error('ps2', prefix, exists) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return cb() + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this._emitMatch(index, prefix) + cb() +} + +// Returns either 'DIR', 'FILE', or false +Glob.prototype._stat = function (f, cb) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return cb() + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return cb(null, c) + + if (needDir && c === 'FILE') + return cb() + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (stat !== undefined) { + if (stat === false) + return cb(null, stat) + else { + var type = stat.isDirectory() ? 'DIR' : 'FILE' + if (needDir && type === 'FILE') + return cb() + else + return cb(null, type, stat) + } + } + + var self = this + var statcb = inflight('stat\0' + abs, lstatcb_) + if (statcb) + fs.lstat(abs, statcb) + + function lstatcb_ (er, lstat) { + if (lstat && lstat.isSymbolicLink()) { + // If it's a symlink, then treat it as the target, unless + // the target does not exist, then treat it as a file. + return fs.stat(abs, function (er, stat) { + if (er) + self._stat2(f, abs, null, lstat, cb) + else + self._stat2(f, abs, er, stat, cb) + }) + } else { + self._stat2(f, abs, er, lstat, cb) + } + } +} + +Glob.prototype._stat2 = function (f, abs, er, stat, cb) { + if (er) { + this.statCache[abs] = false + return cb() + } + + var needDir = f.slice(-1) === '/' + this.statCache[abs] = stat + + if (abs.slice(-1) === '/' && !stat.isDirectory()) + return cb(null, false, stat) + + var c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c !== 'DIR') + return cb() + + return cb(null, c, stat) +} + +}).call(this,require('_process')) +},{"./common.js":15,"./sync.js":17,"_process":24,"assert":9,"events":14,"fs":12,"inflight":18,"inherits":19,"minimatch":20,"once":21,"path":22,"path-is-absolute":23,"util":28}],17:[function(require,module,exports){ +(function (process){ +module.exports = globSync +globSync.GlobSync = GlobSync + +var fs = require('fs') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var Glob = require('./glob.js').Glob +var util = require('util') +var path = require('path') +var assert = require('assert') +var isAbsolute = require('path-is-absolute') +var common = require('./common.js') +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var childrenIgnored = common.childrenIgnored + +function globSync (pattern, options) { + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + return new GlobSync(pattern, options).found +} + +function GlobSync (pattern, options) { + if (!pattern) + throw new Error('must provide pattern') + + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + if (!(this instanceof GlobSync)) + return new GlobSync(pattern, options) + + setopts(this, pattern, options) + + if (this.noprocess) + return this + + var n = this.minimatch.set.length + this.matches = new Array(n) + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false) + } + this._finish() +} + +GlobSync.prototype._finish = function () { + assert(this instanceof GlobSync) + if (this.realpath) { + var self = this + this.matches.forEach(function (matchset, index) { + var set = self.matches[index] = Object.create(null) + for (var p in matchset) { + try { + p = self._makeAbs(p) + var real = fs.realpathSync(p, self.realpathCache) + set[real] = true + } catch (er) { + if (er.syscall === 'stat') + set[self._makeAbs(p)] = true + else + throw er + } + } + }) + } + common.finish(this) +} + + +GlobSync.prototype._process = function (pattern, index, inGlobStar) { + assert(this instanceof GlobSync) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // See if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip processing + if (childrenIgnored(this, read)) + return + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar) +} + + +GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { + var entries = this._readdir(abs, inGlobStar) + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix.slice(-1) !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this.matches[index][e] = true + } + // This was the last one, and no stats were needed + return + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) + newPattern = [prefix, e] + else + newPattern = [e] + this._process(newPattern.concat(remain), index, inGlobStar) + } +} + + +GlobSync.prototype._emitMatch = function (index, e) { + var abs = this._makeAbs(e) + if (this.mark) + e = this._mark(e) + + if (this.matches[index][e]) + return + + if (this.nodir) { + var c = this.cache[this._makeAbs(e)] + if (c === 'DIR' || Array.isArray(c)) + return + } + + this.matches[index][e] = true + if (this.stat) + this._stat(e) +} + + +GlobSync.prototype._readdirInGlobStar = function (abs) { + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false) + + var entries + var lstat + var stat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + // lstat failed, doesn't exist + return null + } + + var isSym = lstat.isSymbolicLink() + this.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && !lstat.isDirectory()) + this.cache[abs] = 'FILE' + else + entries = this._readdir(abs, false) + + return entries +} + +GlobSync.prototype._readdir = function (abs, inGlobStar) { + var entries + + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return null + + if (Array.isArray(c)) + return c + } + + try { + return this._readdirEntries(abs, fs.readdirSync(abs)) + } catch (er) { + this._readdirError(abs, er) + return null + } +} + +GlobSync.prototype._readdirEntries = function (abs, entries) { + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + + // mark and cache dir-ness + return entries +} + +GlobSync.prototype._readdirError = function (f, er) { + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + this.cache[this._makeAbs(f)] = 'FILE' + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) + throw er + if (!this.silent) + console.error('glob error', er) + break + } +} + +GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { + + var entries = this._readdir(abs, inGlobStar) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false) + + var len = entries.length + var isSym = this.symlinks[abs] + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true) + } +} + +GlobSync.prototype._processSimple = function (prefix, index) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var exists = this._stat(prefix) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this.matches[index][prefix] = true +} + +// Returns either 'DIR', 'FILE', or false +GlobSync.prototype._stat = function (f) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return false + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return c + + if (needDir && c === 'FILE') + return false + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (!stat) { + var lstat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + return false + } + + if (lstat.isSymbolicLink()) { + try { + stat = fs.statSync(abs) + } catch (er) { + stat = lstat + } + } else { + stat = lstat + } + } + + this.statCache[abs] = stat + + var c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c !== 'DIR') + return false + + return c +} + +GlobSync.prototype._mark = function (p) { + return common.mark(this, p) +} + +GlobSync.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} + +}).call(this,require('_process')) +},{"./common.js":15,"./glob.js":16,"_process":24,"assert":9,"fs":12,"minimatch":20,"path":22,"path-is-absolute":23,"util":28}],18:[function(require,module,exports){ +(function (process){ +var wrappy = require('wrappy') +var reqs = Object.create(null) +var once = require('once') + +module.exports = wrappy(inflight) + +function inflight (key, cb) { + if (reqs[key]) { + reqs[key].push(cb) + return null + } else { + reqs[key] = [cb] + return makeres(key) + } +} + +function makeres (key) { + return once(function RES () { + var cbs = reqs[key] + var len = cbs.length + var args = slice(arguments) + + // XXX It's somewhat ambiguous whether a new callback added in this + // pass should be queued for later execution if something in the + // list of callbacks throws, or if it should just be discarded. + // However, it's such an edge case that it hardly matters, and either + // choice is likely as surprising as the other. + // As it happens, we do go ahead and schedule it for later execution. + try { + for (var i = 0; i < len; i++) { + cbs[i].apply(null, args) + } + } finally { + if (cbs.length > len) { + // added more in the interim. + // de-zalgo, just in case, but don't call again. + cbs.splice(0, len) + process.nextTick(function () { + RES.apply(null, args) + }) + } else { + delete reqs[key] + } + } + }) +} + +function slice (args) { + var length = args.length + var array = [] + + for (var i = 0; i < length; i++) array[i] = args[i] + return array +} + +}).call(this,require('_process')) +},{"_process":24,"once":21,"wrappy":29}],19:[function(require,module,exports){ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } +} + +},{}],20:[function(require,module,exports){ +module.exports = minimatch +minimatch.Minimatch = Minimatch + +var path = { sep: '/' } +try { + path = require('path') +} catch (er) {} + +var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} +var expand = require('brace-expansion') + +var plTypes = { + '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, + '?': { open: '(?:', close: ')?' }, + '+': { open: '(?:', close: ')+' }, + '*': { open: '(?:', close: ')*' }, + '@': { open: '(?:', close: ')' } +} + +// any single thing other than / +// don't need to escape / when using new RegExp() +var qmark = '[^/]' + +// * => any number of characters +var star = qmark + '*?' + +// ** when dots are allowed. Anything goes, except .. and . +// not (^ or / followed by one or two dots followed by $ or /), +// followed by anything, any number of times. +var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?' + +// not a ^ or / followed by a dot, +// followed by anything, any number of times. +var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?' + +// characters that need to be escaped in RegExp. +var reSpecials = charSet('().*{}+?[]^$\\!') + +// "abc" -> { a:true, b:true, c:true } +function charSet (s) { + return s.split('').reduce(function (set, c) { + set[c] = true + return set + }, {}) +} + +// normalizes slashes. +var slashSplit = /\/+/ + +minimatch.filter = filter +function filter (pattern, options) { + options = options || {} + return function (p, i, list) { + return minimatch(p, pattern, options) + } +} + +function ext (a, b) { + a = a || {} + b = b || {} + var t = {} + Object.keys(b).forEach(function (k) { + t[k] = b[k] + }) + Object.keys(a).forEach(function (k) { + t[k] = a[k] + }) + return t +} + +minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return minimatch + + var orig = minimatch + + var m = function minimatch (p, pattern, options) { + return orig.minimatch(p, pattern, ext(def, options)) + } + + m.Minimatch = function Minimatch (pattern, options) { + return new orig.Minimatch(pattern, ext(def, options)) + } + + return m +} + +Minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return Minimatch + return minimatch.defaults(def).Minimatch +} + +function minimatch (p, pattern, options) { + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required') + } + + if (!options) options = {} + + // shortcut: comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + return false + } + + // "" only matches "" + if (pattern.trim() === '') return p === '' + + return new Minimatch(pattern, options).match(p) +} + +function Minimatch (pattern, options) { + if (!(this instanceof Minimatch)) { + return new Minimatch(pattern, options) + } + + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required') + } + + if (!options) options = {} + pattern = pattern.trim() + + // windows support: need to use /, not \ + if (path.sep !== '/') { + pattern = pattern.split(path.sep).join('/') + } + + this.options = options + this.set = [] + this.pattern = pattern + this.regexp = null + this.negate = false + this.comment = false + this.empty = false + + // make the set of regexps etc. + this.make() +} + +Minimatch.prototype.debug = function () {} + +Minimatch.prototype.make = make +function make () { + // don't do it more than once. + if (this._made) return + + var pattern = this.pattern + var options = this.options + + // empty patterns and comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + this.comment = true + return + } + if (!pattern) { + this.empty = true + return + } + + // step 1: figure out negation, etc. + this.parseNegate() + + // step 2: expand braces + var set = this.globSet = this.braceExpand() + + if (options.debug) this.debug = console.error + + this.debug(this.pattern, set) + + // step 3: now we have a set, so turn each one into a series of path-portion + // matching patterns. + // These will be regexps, except in the case of "**", which is + // set to the GLOBSTAR object for globstar behavior, + // and will not contain any / characters + set = this.globParts = set.map(function (s) { + return s.split(slashSplit) + }) + + this.debug(this.pattern, set) + + // glob --> regexps + set = set.map(function (s, si, set) { + return s.map(this.parse, this) + }, this) + + this.debug(this.pattern, set) + + // filter out everything that didn't compile properly. + set = set.filter(function (s) { + return s.indexOf(false) === -1 + }) + + this.debug(this.pattern, set) + + this.set = set +} + +Minimatch.prototype.parseNegate = parseNegate +function parseNegate () { + var pattern = this.pattern + var negate = false + var options = this.options + var negateOffset = 0 + + if (options.nonegate) return + + for (var i = 0, l = pattern.length + ; i < l && pattern.charAt(i) === '!' + ; i++) { + negate = !negate + negateOffset++ + } + + if (negateOffset) this.pattern = pattern.substr(negateOffset) + this.negate = negate +} + +// Brace expansion: +// a{b,c}d -> abd acd +// a{b,}c -> abc ac +// a{0..3}d -> a0d a1d a2d a3d +// a{b,c{d,e}f}g -> abg acdfg acefg +// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg +// +// Invalid sets are not expanded. +// a{2..}b -> a{2..}b +// a{b}c -> a{b}c +minimatch.braceExpand = function (pattern, options) { + return braceExpand(pattern, options) +} + +Minimatch.prototype.braceExpand = braceExpand + +function braceExpand (pattern, options) { + if (!options) { + if (this instanceof Minimatch) { + options = this.options + } else { + options = {} + } + } + + pattern = typeof pattern === 'undefined' + ? this.pattern : pattern + + if (typeof pattern === 'undefined') { + throw new TypeError('undefined pattern') + } + + if (options.nobrace || + !pattern.match(/\{.*\}/)) { + // shortcut. no need to expand. + return [pattern] + } + + return expand(pattern) +} + +// parse a component of the expanded set. +// At this point, no pattern may contain "/" in it +// so we're going to return a 2d array, where each entry is the full +// pattern, split on '/', and then turned into a regular expression. +// A regexp is made at the end which joins each array with an +// escaped /, and another full one which joins each regexp with |. +// +// Following the lead of Bash 4.1, note that "**" only has special meaning +// when it is the *only* thing in a path portion. Otherwise, any series +// of * is equivalent to a single *. Globstar behavior is enabled by +// default, and can be disabled by setting options.noglobstar. +Minimatch.prototype.parse = parse +var SUBPARSE = {} +function parse (pattern, isSub) { + if (pattern.length > 1024 * 64) { + throw new TypeError('pattern is too long') + } + + var options = this.options + + // shortcuts + if (!options.noglobstar && pattern === '**') return GLOBSTAR + if (pattern === '') return '' + + var re = '' + var hasMagic = !!options.nocase + var escaping = false + // ? => one single character + var patternListStack = [] + var negativeLists = [] + var stateChar + var inClass = false + var reClassStart = -1 + var classStart = -1 + // . and .. never match anything that doesn't start with ., + // even when options.dot is set. + var patternStart = pattern.charAt(0) === '.' ? '' // anything + // not (start or / followed by . or .. followed by / or end) + : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' + : '(?!\\.)' + var self = this + + function clearStateChar () { + if (stateChar) { + // we had some state-tracking character + // that wasn't consumed by this pass. + switch (stateChar) { + case '*': + re += star + hasMagic = true + break + case '?': + re += qmark + hasMagic = true + break + default: + re += '\\' + stateChar + break + } + self.debug('clearStateChar %j %j', stateChar, re) + stateChar = false + } + } + + for (var i = 0, len = pattern.length, c + ; (i < len) && (c = pattern.charAt(i)) + ; i++) { + this.debug('%s\t%s %s %j', pattern, i, re, c) + + // skip over any that are escaped. + if (escaping && reSpecials[c]) { + re += '\\' + c + escaping = false + continue + } + + switch (c) { + case '/': + // completely not allowed, even escaped. + // Should already be path-split by now. + return false + + case '\\': + clearStateChar() + escaping = true + continue + + // the various stateChar values + // for the "extglob" stuff. + case '?': + case '*': + case '+': + case '@': + case '!': + this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c) + + // all of those are literals inside a class, except that + // the glob [!a] means [^a] in regexp + if (inClass) { + this.debug(' in class') + if (c === '!' && i === classStart + 1) c = '^' + re += c + continue + } + + // if we already have a stateChar, then it means + // that there was something like ** or +? in there. + // Handle the stateChar, then proceed with this one. + self.debug('call clearStateChar %j', stateChar) + clearStateChar() + stateChar = c + // if extglob is disabled, then +(asdf|foo) isn't a thing. + // just clear the statechar *now*, rather than even diving into + // the patternList stuff. + if (options.noext) clearStateChar() + continue + + case '(': + if (inClass) { + re += '(' + continue + } + + if (!stateChar) { + re += '\\(' + continue + } + + patternListStack.push({ + type: stateChar, + start: i - 1, + reStart: re.length, + open: plTypes[stateChar].open, + close: plTypes[stateChar].close + }) + // negation is (?:(?!js)[^/]*) + re += stateChar === '!' ? '(?:(?!(?:' : '(?:' + this.debug('plType %j %j', stateChar, re) + stateChar = false + continue + + case ')': + if (inClass || !patternListStack.length) { + re += '\\)' + continue + } + + clearStateChar() + hasMagic = true + var pl = patternListStack.pop() + // negation is (?:(?!js)[^/]*) + // The others are (?:) + re += pl.close + if (pl.type === '!') { + negativeLists.push(pl) + } + pl.reEnd = re.length + continue + + case '|': + if (inClass || !patternListStack.length || escaping) { + re += '\\|' + escaping = false + continue + } + + clearStateChar() + re += '|' + continue + + // these are mostly the same in regexp and glob + case '[': + // swallow any state-tracking char before the [ + clearStateChar() + + if (inClass) { + re += '\\' + c + continue + } + + inClass = true + classStart = i + reClassStart = re.length + re += c + continue + + case ']': + // a right bracket shall lose its special + // meaning and represent itself in + // a bracket expression if it occurs + // first in the list. -- POSIX.2 2.8.3.2 + if (i === classStart + 1 || !inClass) { + re += '\\' + c + escaping = false + continue + } + + // handle the case where we left a class open. + // "[z-a]" is valid, equivalent to "\[z-a\]" + if (inClass) { + // split where the last [ was, make sure we don't have + // an invalid re. if so, re-walk the contents of the + // would-be class to re-translate any characters that + // were passed through as-is + // TODO: It would probably be faster to determine this + // without a try/catch and a new RegExp, but it's tricky + // to do safely. For now, this is safe and works. + var cs = pattern.substring(classStart + 1, i) + try { + RegExp('[' + cs + ']') + } catch (er) { + // not a valid class! + var sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' + hasMagic = hasMagic || sp[1] + inClass = false + continue + } + } + + // finish up the class. + hasMagic = true + inClass = false + re += c + continue + + default: + // swallow any state char that wasn't consumed + clearStateChar() + + if (escaping) { + // no need + escaping = false + } else if (reSpecials[c] + && !(c === '^' && inClass)) { + re += '\\' + } + + re += c + + } // switch + } // for + + // handle the case where we left a class open. + // "[abc" is valid, equivalent to "\[abc" + if (inClass) { + // split where the last [ was, and escape it + // this is a huge pita. We now have to re-walk + // the contents of the would-be class to re-translate + // any characters that were passed through as-is + cs = pattern.substr(classStart + 1) + sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + hasMagic = hasMagic || sp[1] + } + + // handle the case where we had a +( thing at the *end* + // of the pattern. + // each pattern list stack adds 3 chars, and we need to go through + // and escape any | chars that were passed through as-is for the regexp. + // Go through and escape them, taking care not to double-escape any + // | chars that were already escaped. + for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { + var tail = re.slice(pl.reStart + pl.open.length) + this.debug('setting tail', re, pl) + // maybe some even number of \, then maybe 1 \, followed by a | + tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { + if (!$2) { + // the | isn't already escaped, so escape it. + $2 = '\\' + } + + // need to escape all those slashes *again*, without escaping the + // one that we need for escaping the | character. As it works out, + // escaping an even number of slashes can be done by simply repeating + // it exactly after itself. That's why this trick works. + // + // I am sorry that you have to see this. + return $1 + $1 + $2 + '|' + }) + + this.debug('tail=%j\n %s', tail, tail, pl, re) + var t = pl.type === '*' ? star + : pl.type === '?' ? qmark + : '\\' + pl.type + + hasMagic = true + re = re.slice(0, pl.reStart) + t + '\\(' + tail + } + + // handle trailing things that only matter at the very end. + clearStateChar() + if (escaping) { + // trailing \\ + re += '\\\\' + } + + // only need to apply the nodot start if the re starts with + // something that could conceivably capture a dot + var addPatternStart = false + switch (re.charAt(0)) { + case '.': + case '[': + case '(': addPatternStart = true + } + + // Hack to work around lack of negative lookbehind in JS + // A pattern like: *.!(x).!(y|z) needs to ensure that a name + // like 'a.xyz.yz' doesn't match. So, the first negative + // lookahead, has to look ALL the way ahead, to the end of + // the pattern. + for (var n = negativeLists.length - 1; n > -1; n--) { + var nl = negativeLists[n] + + var nlBefore = re.slice(0, nl.reStart) + var nlFirst = re.slice(nl.reStart, nl.reEnd - 8) + var nlLast = re.slice(nl.reEnd - 8, nl.reEnd) + var nlAfter = re.slice(nl.reEnd) + + nlLast += nlAfter + + // Handle nested stuff like *(*.js|!(*.json)), where open parens + // mean that we should *not* include the ) in the bit that is considered + // "after" the negated section. + var openParensBefore = nlBefore.split('(').length - 1 + var cleanAfter = nlAfter + for (i = 0; i < openParensBefore; i++) { + cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') + } + nlAfter = cleanAfter + + var dollar = '' + if (nlAfter === '' && isSub !== SUBPARSE) { + dollar = '$' + } + var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast + re = newRe + } + + // if the re is not "" at this point, then we need to make sure + // it doesn't match against an empty path part. + // Otherwise a/* will match a/, which it should not. + if (re !== '' && hasMagic) { + re = '(?=.)' + re + } + + if (addPatternStart) { + re = patternStart + re + } + + // parsing just a piece of a larger pattern. + if (isSub === SUBPARSE) { + return [re, hasMagic] + } + + // skip the regexp for non-magical patterns + // unescape anything in it, though, so that it'll be + // an exact match against a file etc. + if (!hasMagic) { + return globUnescape(pattern) + } + + var flags = options.nocase ? 'i' : '' + try { + var regExp = new RegExp('^' + re + '$', flags) + } catch (er) { + // If it was an invalid regular expression, then it can't match + // anything. This trick looks for a character after the end of + // the string, which is of course impossible, except in multi-line + // mode, but it's not a /m regex. + return new RegExp('$.') + } + + regExp._glob = pattern + regExp._src = re + + return regExp +} + +minimatch.makeRe = function (pattern, options) { + return new Minimatch(pattern, options || {}).makeRe() +} + +Minimatch.prototype.makeRe = makeRe +function makeRe () { + if (this.regexp || this.regexp === false) return this.regexp + + // at this point, this.set is a 2d array of partial + // pattern strings, or "**". + // + // It's better to use .match(). This function shouldn't + // be used, really, but it's pretty convenient sometimes, + // when you just want to work with a regex. + var set = this.set + + if (!set.length) { + this.regexp = false + return this.regexp + } + var options = this.options + + var twoStar = options.noglobstar ? star + : options.dot ? twoStarDot + : twoStarNoDot + var flags = options.nocase ? 'i' : '' + + var re = set.map(function (pattern) { + return pattern.map(function (p) { + return (p === GLOBSTAR) ? twoStar + : (typeof p === 'string') ? regExpEscape(p) + : p._src + }).join('\\\/') + }).join('|') + + // must match entire pattern + // ending in a * or ** will make it less strict. + re = '^(?:' + re + ')$' + + // can match anything, as long as it's not this. + if (this.negate) re = '^(?!' + re + ').*$' + + try { + this.regexp = new RegExp(re, flags) + } catch (ex) { + this.regexp = false + } + return this.regexp +} + +minimatch.match = function (list, pattern, options) { + options = options || {} + var mm = new Minimatch(pattern, options) + list = list.filter(function (f) { + return mm.match(f) + }) + if (mm.options.nonull && !list.length) { + list.push(pattern) + } + return list +} + +Minimatch.prototype.match = match +function match (f, partial) { + this.debug('match', f, this.pattern) + // short-circuit in the case of busted things. + // comments, etc. + if (this.comment) return false + if (this.empty) return f === '' + + if (f === '/' && partial) return true + + var options = this.options + + // windows: need to use /, not \ + if (path.sep !== '/') { + f = f.split(path.sep).join('/') + } + + // treat the test path as a set of pathparts. + f = f.split(slashSplit) + this.debug(this.pattern, 'split', f) + + // just ONE of the pattern sets in this.set needs to match + // in order for it to be valid. If negating, then just one + // match means that we have failed. + // Either way, return on the first hit. + + var set = this.set + this.debug(this.pattern, 'set', set) + + // Find the basename of the path by looking for the last non-empty segment + var filename + var i + for (i = f.length - 1; i >= 0; i--) { + filename = f[i] + if (filename) break + } + + for (i = 0; i < set.length; i++) { + var pattern = set[i] + var file = f + if (options.matchBase && pattern.length === 1) { + file = [filename] + } + var hit = this.matchOne(file, pattern, partial) + if (hit) { + if (options.flipNegate) return true + return !this.negate + } + } + + // didn't get any hits. this is success if it's a negative + // pattern, failure otherwise. + if (options.flipNegate) return false + return this.negate +} + +// set partial to true to test if, for example, +// "/a/b" matches the start of "/*/b/*/d" +// Partial means, if you run out of file before you run +// out of pattern, then that's fine, as long as all +// the parts match. +Minimatch.prototype.matchOne = function (file, pattern, partial) { + var options = this.options + + this.debug('matchOne', + { 'this': this, file: file, pattern: pattern }) + + this.debug('matchOne', file.length, pattern.length) + + for (var fi = 0, + pi = 0, + fl = file.length, + pl = pattern.length + ; (fi < fl) && (pi < pl) + ; fi++, pi++) { + this.debug('matchOne loop') + var p = pattern[pi] + var f = file[fi] + + this.debug(pattern, p, f) + + // should be impossible. + // some invalid regexp stuff in the set. + if (p === false) return false + + if (p === GLOBSTAR) { + this.debug('GLOBSTAR', [pattern, p, f]) + + // "**" + // a/**/b/**/c would match the following: + // a/b/x/y/z/c + // a/x/y/z/b/c + // a/b/x/b/x/c + // a/b/c + // To do this, take the rest of the pattern after + // the **, and see if it would match the file remainder. + // If so, return success. + // If not, the ** "swallows" a segment, and try again. + // This is recursively awful. + // + // a/**/b/**/c matching a/b/x/y/z/c + // - a matches a + // - doublestar + // - matchOne(b/x/y/z/c, b/**/c) + // - b matches b + // - doublestar + // - matchOne(x/y/z/c, c) -> no + // - matchOne(y/z/c, c) -> no + // - matchOne(z/c, c) -> no + // - matchOne(c, c) yes, hit + var fr = fi + var pr = pi + 1 + if (pr === pl) { + this.debug('** at the end') + // a ** at the end will just swallow the rest. + // We have found a match. + // however, it will not swallow /.x, unless + // options.dot is set. + // . and .. are *never* matched by **, for explosively + // exponential reasons. + for (; fi < fl; fi++) { + if (file[fi] === '.' || file[fi] === '..' || + (!options.dot && file[fi].charAt(0) === '.')) return false + } + return true + } + + // ok, let's see if we can swallow whatever we can. + while (fr < fl) { + var swallowee = file[fr] + + this.debug('\nglobstar while', file, fr, pattern, pr, swallowee) + + // XXX remove this slice. Just pass the start index. + if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { + this.debug('globstar found match!', fr, fl, swallowee) + // found a match. + return true + } else { + // can't swallow "." or ".." ever. + // can only swallow ".foo" when explicitly asked. + if (swallowee === '.' || swallowee === '..' || + (!options.dot && swallowee.charAt(0) === '.')) { + this.debug('dot detected!', file, fr, pattern, pr) + break + } + + // ** swallows a segment, and continue. + this.debug('globstar swallow a segment, and continue') + fr++ + } + } + + // no match was found. + // However, in partial mode, we can't say this is necessarily over. + // If there's more *pattern* left, then + if (partial) { + // ran out of file + this.debug('\n>>> no match, partial?', file, fr, pattern, pr) + if (fr === fl) return true + } + return false + } + + // something other than ** + // non-magic patterns just have to match exactly + // patterns with magic have been turned into regexps. + var hit + if (typeof p === 'string') { + if (options.nocase) { + hit = f.toLowerCase() === p.toLowerCase() + } else { + hit = f === p + } + this.debug('string match', p, f, hit) + } else { + hit = f.match(p) + this.debug('pattern match', p, f, hit) + } + + if (!hit) return false + } + + // Note: ending in / means that we'll get a final "" + // at the end of the pattern. This can only match a + // corresponding "" at the end of the file. + // If the file ends in /, then it can only match a + // a pattern that ends in /, unless the pattern just + // doesn't have any more for it. But, a/b/ should *not* + // match "a/b/*", even though "" matches against the + // [^/]*? pattern, except in partial mode, where it might + // simply not be reached yet. + // However, a/b/ should still satisfy a/* + + // now either we fell off the end of the pattern, or we're done. + if (fi === fl && pi === pl) { + // ran out of pattern and filename at the same time. + // an exact hit! + return true + } else if (fi === fl) { + // ran out of file, but still had pattern left. + // this is ok if we're doing the match as part of + // a glob fs traversal. + return partial + } else if (pi === pl) { + // ran out of pattern, still have file left. + // this is only acceptable if we're on the very last + // empty segment of a file with a trailing slash. + // a/* should match a/b/ + var emptyFileEnd = (fi === fl - 1) && (file[fi] === '') + return emptyFileEnd + } + + // should be unreachable. + throw new Error('wtf?') +} + +// replace stuff like \* with * +function globUnescape (s) { + return s.replace(/\\(.)/g, '$1') +} + +function regExpEscape (s) { + return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') +} + +},{"brace-expansion":11,"path":22}],21:[function(require,module,exports){ +var wrappy = require('wrappy') +module.exports = wrappy(once) +module.exports.strict = wrappy(onceStrict) + +once.proto = once(function () { + Object.defineProperty(Function.prototype, 'once', { + value: function () { + return once(this) + }, + configurable: true + }) + + Object.defineProperty(Function.prototype, 'onceStrict', { + value: function () { + return onceStrict(this) + }, + configurable: true + }) +}) + +function once (fn) { + var f = function () { + if (f.called) return f.value + f.called = true + return f.value = fn.apply(this, arguments) + } + f.called = false + return f +} + +function onceStrict (fn) { + var f = function () { + if (f.called) + throw new Error(f.onceError) + f.called = true + return f.value = fn.apply(this, arguments) + } + var name = fn.name || 'Function wrapped with `once`' + f.onceError = name + " shouldn't be called more than once" + f.called = false + return f +} + +},{"wrappy":29}],22:[function(require,module,exports){ +(function (process){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// resolves . and .. elements in a path array with directory names there +// must be no slashes, empty elements, or device names (c:\) in the array +// (so also no leading and trailing slashes - it does not distinguish +// relative and absolute paths) +function normalizeArray(parts, allowAboveRoot) { + // if the path tries to go above the root, `up` ends up > 0 + var up = 0; + for (var i = parts.length - 1; i >= 0; i--) { + var last = parts[i]; + if (last === '.') { + parts.splice(i, 1); + } else if (last === '..') { + parts.splice(i, 1); + up++; + } else if (up) { + parts.splice(i, 1); + up--; + } + } + + // if the path is allowed to go above the root, restore leading ..s + if (allowAboveRoot) { + for (; up--; up) { + parts.unshift('..'); + } + } + + return parts; +} + +// Split a filename into [root, dir, basename, ext], unix version +// 'root' is just a slash, or nothing. +var splitPathRe = + /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; +var splitPath = function(filename) { + return splitPathRe.exec(filename).slice(1); +}; + +// path.resolve([from ...], to) +// posix version +exports.resolve = function() { + var resolvedPath = '', + resolvedAbsolute = false; + + for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { + var path = (i >= 0) ? arguments[i] : process.cwd(); + + // Skip empty and invalid entries + if (typeof path !== 'string') { + throw new TypeError('Arguments to path.resolve must be strings'); + } else if (!path) { + continue; + } + + resolvedPath = path + '/' + resolvedPath; + resolvedAbsolute = path.charAt(0) === '/'; + } + + // At this point the path should be resolved to a full absolute path, but + // handle relative paths to be safe (might happen when process.cwd() fails) + + // Normalize the path + resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { + return !!p; + }), !resolvedAbsolute).join('/'); + + return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; +}; + +// path.normalize(path) +// posix version +exports.normalize = function(path) { + var isAbsolute = exports.isAbsolute(path), + trailingSlash = substr(path, -1) === '/'; + + // Normalize the path + path = normalizeArray(filter(path.split('/'), function(p) { + return !!p; + }), !isAbsolute).join('/'); + + if (!path && !isAbsolute) { + path = '.'; + } + if (path && trailingSlash) { + path += '/'; + } + + return (isAbsolute ? '/' : '') + path; +}; + +// posix version +exports.isAbsolute = function(path) { + return path.charAt(0) === '/'; +}; + +// posix version +exports.join = function() { + var paths = Array.prototype.slice.call(arguments, 0); + return exports.normalize(filter(paths, function(p, index) { + if (typeof p !== 'string') { + throw new TypeError('Arguments to path.join must be strings'); + } + return p; + }).join('/')); +}; + + +// path.relative(from, to) +// posix version +exports.relative = function(from, to) { + from = exports.resolve(from).substr(1); + to = exports.resolve(to).substr(1); + + function trim(arr) { + var start = 0; + for (; start < arr.length; start++) { + if (arr[start] !== '') break; + } + + var end = arr.length - 1; + for (; end >= 0; end--) { + if (arr[end] !== '') break; + } + + if (start > end) return []; + return arr.slice(start, end - start + 1); + } + + var fromParts = trim(from.split('/')); + var toParts = trim(to.split('/')); + + var length = Math.min(fromParts.length, toParts.length); + var samePartsLength = length; + for (var i = 0; i < length; i++) { + if (fromParts[i] !== toParts[i]) { + samePartsLength = i; + break; + } + } + + var outputParts = []; + for (var i = samePartsLength; i < fromParts.length; i++) { + outputParts.push('..'); + } + + outputParts = outputParts.concat(toParts.slice(samePartsLength)); + + return outputParts.join('/'); +}; + +exports.sep = '/'; +exports.delimiter = ':'; + +exports.dirname = function(path) { + var result = splitPath(path), + root = result[0], + dir = result[1]; + + if (!root && !dir) { + // No dirname whatsoever + return '.'; + } + + if (dir) { + // It has a dirname, strip trailing slash + dir = dir.substr(0, dir.length - 1); + } + + return root + dir; +}; + + +exports.basename = function(path, ext) { + var f = splitPath(path)[2]; + // TODO: make this comparison case-insensitive on windows? + if (ext && f.substr(-1 * ext.length) === ext) { + f = f.substr(0, f.length - ext.length); + } + return f; +}; + + +exports.extname = function(path) { + return splitPath(path)[3]; +}; + +function filter (xs, f) { + if (xs.filter) return xs.filter(f); + var res = []; + for (var i = 0; i < xs.length; i++) { + if (f(xs[i], i, xs)) res.push(xs[i]); + } + return res; +} + +// String.prototype.substr - negative index don't work in IE8 +var substr = 'ab'.substr(-1) === 'b' + ? function (str, start, len) { return str.substr(start, len) } + : function (str, start, len) { + if (start < 0) start = str.length + start; + return str.substr(start, len); + } +; + +}).call(this,require('_process')) +},{"_process":24}],23:[function(require,module,exports){ +(function (process){ +'use strict'; + +function posix(path) { + return path.charAt(0) === '/'; +} + +function win32(path) { + // https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56 + var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; + var result = splitDeviceRe.exec(path); + var device = result[1] || ''; + var isUnc = Boolean(device && device.charAt(1) !== ':'); + + // UNC paths are always absolute + return Boolean(result[2] || isUnc); +} + +module.exports = process.platform === 'win32' ? win32 : posix; +module.exports.posix = posix; +module.exports.win32 = win32; + +}).call(this,require('_process')) +},{"_process":24}],24:[function(require,module,exports){ +// shim for using process in browser +var process = module.exports = {}; + +// cached from whatever global is present so that test runners that stub it +// don't break things. But we need to wrap it in a try catch in case it is +// wrapped in strict mode code which doesn't define any globals. It's inside a +// function because try/catches deoptimize in certain engines. + +var cachedSetTimeout; +var cachedClearTimeout; + +function defaultSetTimout() { + throw new Error('setTimeout has not been defined'); +} +function defaultClearTimeout () { + throw new Error('clearTimeout has not been defined'); +} +(function () { + try { + if (typeof setTimeout === 'function') { + cachedSetTimeout = setTimeout; + } else { + cachedSetTimeout = defaultSetTimout; + } + } catch (e) { + cachedSetTimeout = defaultSetTimout; + } + try { + if (typeof clearTimeout === 'function') { + cachedClearTimeout = clearTimeout; + } else { + cachedClearTimeout = defaultClearTimeout; + } + } catch (e) { + cachedClearTimeout = defaultClearTimeout; + } +} ()) +function runTimeout(fun) { + if (cachedSetTimeout === setTimeout) { + //normal enviroments in sane situations + return setTimeout(fun, 0); + } + // if setTimeout wasn't available but was latter defined + if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { + cachedSetTimeout = setTimeout; + return setTimeout(fun, 0); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedSetTimeout(fun, 0); + } catch(e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedSetTimeout.call(null, fun, 0); + } catch(e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error + return cachedSetTimeout.call(this, fun, 0); + } + } + + +} +function runClearTimeout(marker) { + if (cachedClearTimeout === clearTimeout) { + //normal enviroments in sane situations + return clearTimeout(marker); + } + // if clearTimeout wasn't available but was latter defined + if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { + cachedClearTimeout = clearTimeout; + return clearTimeout(marker); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedClearTimeout(marker); + } catch (e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedClearTimeout.call(null, marker); + } catch (e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. + // Some versions of I.E. have different rules for clearTimeout vs setTimeout + return cachedClearTimeout.call(this, marker); + } + } + + + +} +var queue = []; +var draining = false; +var currentQueue; +var queueIndex = -1; + +function cleanUpNextTick() { + if (!draining || !currentQueue) { + return; + } + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } +} + +function drainQueue() { + if (draining) { + return; + } + var timeout = runTimeout(cleanUpNextTick); + draining = true; + + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + if (currentQueue) { + currentQueue[queueIndex].run(); + } + } + queueIndex = -1; + len = queue.length; + } + currentQueue = null; + draining = false; + runClearTimeout(timeout); +} + +process.nextTick = function (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + runTimeout(drainQueue); + } +}; + +// v8 likes predictible objects +function Item(fun, array) { + this.fun = fun; + this.array = array; +} +Item.prototype.run = function () { + this.fun.apply(null, this.array); +}; +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; +process.version = ''; // empty string to avoid regexp issues +process.versions = {}; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; +process.prependListener = noop; +process.prependOnceListener = noop; + +process.listeners = function (name) { return [] } + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +}; + +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; +process.umask = function() { return 0; }; + +},{}],25:[function(require,module,exports){ +// Underscore.js 1.8.3 +// http://underscorejs.org +// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// Underscore may be freely distributed under the MIT license. + +(function() { + + // Baseline setup + // -------------- + + // Establish the root object, `window` in the browser, or `exports` on the server. + var root = this; + + // Save the previous value of the `_` variable. + var previousUnderscore = root._; + + // Save bytes in the minified (but not gzipped) version: + var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; + + // Create quick reference variables for speed access to core prototypes. + var + push = ArrayProto.push, + slice = ArrayProto.slice, + toString = ObjProto.toString, + hasOwnProperty = ObjProto.hasOwnProperty; + + // All **ECMAScript 5** native function implementations that we hope to use + // are declared here. + var + nativeIsArray = Array.isArray, + nativeKeys = Object.keys, + nativeBind = FuncProto.bind, + nativeCreate = Object.create; + + // Naked function reference for surrogate-prototype-swapping. + var Ctor = function(){}; + + // Create a safe reference to the Underscore object for use below. + var _ = function(obj) { + if (obj instanceof _) return obj; + if (!(this instanceof _)) return new _(obj); + this._wrapped = obj; + }; + + // Export the Underscore object for **Node.js**, with + // backwards-compatibility for the old `require()` API. If we're in + // the browser, add `_` as a global object. + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + exports = module.exports = _; + } + exports._ = _; + } else { + root._ = _; + } + + // Current version. + _.VERSION = '1.8.3'; + + // Internal function that returns an efficient (for current engines) version + // of the passed-in callback, to be repeatedly applied in other Underscore + // functions. + var optimizeCb = function(func, context, argCount) { + if (context === void 0) return func; + switch (argCount == null ? 3 : argCount) { + case 1: return function(value) { + return func.call(context, value); + }; + case 2: return function(value, other) { + return func.call(context, value, other); + }; + case 3: return function(value, index, collection) { + return func.call(context, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(context, accumulator, value, index, collection); + }; + } + return function() { + return func.apply(context, arguments); + }; + }; + + // A mostly-internal function to generate callbacks that can be applied + // to each element in a collection, returning the desired result — either + // identity, an arbitrary callback, a property matcher, or a property accessor. + var cb = function(value, context, argCount) { + if (value == null) return _.identity; + if (_.isFunction(value)) return optimizeCb(value, context, argCount); + if (_.isObject(value)) return _.matcher(value); + return _.property(value); + }; + _.iteratee = function(value, context) { + return cb(value, context, Infinity); + }; + + // An internal function for creating assigner functions. + var createAssigner = function(keysFunc, undefinedOnly) { + return function(obj) { + var length = arguments.length; + if (length < 2 || obj == null) return obj; + for (var index = 1; index < length; index++) { + var source = arguments[index], + keys = keysFunc(source), + l = keys.length; + for (var i = 0; i < l; i++) { + var key = keys[i]; + if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key]; + } + } + return obj; + }; + }; + + // An internal function for creating a new object that inherits from another. + var baseCreate = function(prototype) { + if (!_.isObject(prototype)) return {}; + if (nativeCreate) return nativeCreate(prototype); + Ctor.prototype = prototype; + var result = new Ctor; + Ctor.prototype = null; + return result; + }; + + var property = function(key) { + return function(obj) { + return obj == null ? void 0 : obj[key]; + }; + }; + + // Helper for collection methods to determine whether a collection + // should be iterated as an array or as an object + // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength + // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 + var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; + var getLength = property('length'); + var isArrayLike = function(collection) { + var length = getLength(collection); + return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; + }; + + // Collection Functions + // -------------------- + + // The cornerstone, an `each` implementation, aka `forEach`. + // Handles raw objects in addition to array-likes. Treats all + // sparse array-likes as if they were dense. + _.each = _.forEach = function(obj, iteratee, context) { + iteratee = optimizeCb(iteratee, context); + var i, length; + if (isArrayLike(obj)) { + for (i = 0, length = obj.length; i < length; i++) { + iteratee(obj[i], i, obj); + } + } else { + var keys = _.keys(obj); + for (i = 0, length = keys.length; i < length; i++) { + iteratee(obj[keys[i]], keys[i], obj); + } + } + return obj; + }; + + // Return the results of applying the iteratee to each element. + _.map = _.collect = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length, + results = Array(length); + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + results[index] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + }; + + // Create a reducing function iterating left or right. + function createReduce(dir) { + // Optimized iterator function as using arguments.length + // in the main function will deoptimize the, see #1991. + function iterator(obj, iteratee, memo, keys, index, length) { + for (; index >= 0 && index < length; index += dir) { + var currentKey = keys ? keys[index] : index; + memo = iteratee(memo, obj[currentKey], currentKey, obj); + } + return memo; + } + + return function(obj, iteratee, memo, context) { + iteratee = optimizeCb(iteratee, context, 4); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length, + index = dir > 0 ? 0 : length - 1; + // Determine the initial value if none is provided. + if (arguments.length < 3) { + memo = obj[keys ? keys[index] : index]; + index += dir; + } + return iterator(obj, iteratee, memo, keys, index, length); + }; + } + + // **Reduce** builds up a single result from a list of values, aka `inject`, + // or `foldl`. + _.reduce = _.foldl = _.inject = createReduce(1); + + // The right-associative version of reduce, also known as `foldr`. + _.reduceRight = _.foldr = createReduce(-1); + + // Return the first value which passes a truth test. Aliased as `detect`. + _.find = _.detect = function(obj, predicate, context) { + var key; + if (isArrayLike(obj)) { + key = _.findIndex(obj, predicate, context); + } else { + key = _.findKey(obj, predicate, context); + } + if (key !== void 0 && key !== -1) return obj[key]; + }; + + // Return all the elements that pass a truth test. + // Aliased as `select`. + _.filter = _.select = function(obj, predicate, context) { + var results = []; + predicate = cb(predicate, context); + _.each(obj, function(value, index, list) { + if (predicate(value, index, list)) results.push(value); + }); + return results; + }; + + // Return all the elements for which a truth test fails. + _.reject = function(obj, predicate, context) { + return _.filter(obj, _.negate(cb(predicate)), context); + }; + + // Determine whether all of the elements match a truth test. + // Aliased as `all`. + _.every = _.all = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + if (!predicate(obj[currentKey], currentKey, obj)) return false; + } + return true; + }; + + // Determine if at least one element in the object matches a truth test. + // Aliased as `any`. + _.some = _.any = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + if (predicate(obj[currentKey], currentKey, obj)) return true; + } + return false; + }; + + // Determine if the array or object contains a given item (using `===`). + // Aliased as `includes` and `include`. + _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) { + if (!isArrayLike(obj)) obj = _.values(obj); + if (typeof fromIndex != 'number' || guard) fromIndex = 0; + return _.indexOf(obj, item, fromIndex) >= 0; + }; + + // Invoke a method (with arguments) on every item in a collection. + _.invoke = function(obj, method) { + var args = slice.call(arguments, 2); + var isFunc = _.isFunction(method); + return _.map(obj, function(value) { + var func = isFunc ? method : value[method]; + return func == null ? func : func.apply(value, args); + }); + }; + + // Convenience version of a common use case of `map`: fetching a property. + _.pluck = function(obj, key) { + return _.map(obj, _.property(key)); + }; + + // Convenience version of a common use case of `filter`: selecting only objects + // containing specific `key:value` pairs. + _.where = function(obj, attrs) { + return _.filter(obj, _.matcher(attrs)); + }; + + // Convenience version of a common use case of `find`: getting the first object + // containing specific `key:value` pairs. + _.findWhere = function(obj, attrs) { + return _.find(obj, _.matcher(attrs)); + }; + + // Return the maximum element (or element-based computation). + _.max = function(obj, iteratee, context) { + var result = -Infinity, lastComputed = -Infinity, + value, computed; + if (iteratee == null && obj != null) { + obj = isArrayLike(obj) ? obj : _.values(obj); + for (var i = 0, length = obj.length; i < length; i++) { + value = obj[i]; + if (value > result) { + result = value; + } + } + } else { + iteratee = cb(iteratee, context); + _.each(obj, function(value, index, list) { + computed = iteratee(value, index, list); + if (computed > lastComputed || computed === -Infinity && result === -Infinity) { + result = value; + lastComputed = computed; + } + }); + } + return result; + }; + + // Return the minimum element (or element-based computation). + _.min = function(obj, iteratee, context) { + var result = Infinity, lastComputed = Infinity, + value, computed; + if (iteratee == null && obj != null) { + obj = isArrayLike(obj) ? obj : _.values(obj); + for (var i = 0, length = obj.length; i < length; i++) { + value = obj[i]; + if (value < result) { + result = value; + } + } + } else { + iteratee = cb(iteratee, context); + _.each(obj, function(value, index, list) { + computed = iteratee(value, index, list); + if (computed < lastComputed || computed === Infinity && result === Infinity) { + result = value; + lastComputed = computed; + } + }); + } + return result; + }; + + // Shuffle a collection, using the modern version of the + // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). + _.shuffle = function(obj) { + var set = isArrayLike(obj) ? obj : _.values(obj); + var length = set.length; + var shuffled = Array(length); + for (var index = 0, rand; index < length; index++) { + rand = _.random(0, index); + if (rand !== index) shuffled[index] = shuffled[rand]; + shuffled[rand] = set[index]; + } + return shuffled; + }; + + // Sample **n** random values from a collection. + // If **n** is not specified, returns a single random element. + // The internal `guard` argument allows it to work with `map`. + _.sample = function(obj, n, guard) { + if (n == null || guard) { + if (!isArrayLike(obj)) obj = _.values(obj); + return obj[_.random(obj.length - 1)]; + } + return _.shuffle(obj).slice(0, Math.max(0, n)); + }; + + // Sort the object's values by a criterion produced by an iteratee. + _.sortBy = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + return _.pluck(_.map(obj, function(value, index, list) { + return { + value: value, + index: index, + criteria: iteratee(value, index, list) + }; + }).sort(function(left, right) { + var a = left.criteria; + var b = right.criteria; + if (a !== b) { + if (a > b || a === void 0) return 1; + if (a < b || b === void 0) return -1; + } + return left.index - right.index; + }), 'value'); + }; + + // An internal function used for aggregate "group by" operations. + var group = function(behavior) { + return function(obj, iteratee, context) { + var result = {}; + iteratee = cb(iteratee, context); + _.each(obj, function(value, index) { + var key = iteratee(value, index, obj); + behavior(result, value, key); + }); + return result; + }; + }; + + // Groups the object's values by a criterion. Pass either a string attribute + // to group by, or a function that returns the criterion. + _.groupBy = group(function(result, value, key) { + if (_.has(result, key)) result[key].push(value); else result[key] = [value]; + }); + + // Indexes the object's values by a criterion, similar to `groupBy`, but for + // when you know that your index values will be unique. + _.indexBy = group(function(result, value, key) { + result[key] = value; + }); + + // Counts instances of an object that group by a certain criterion. Pass + // either a string attribute to count by, or a function that returns the + // criterion. + _.countBy = group(function(result, value, key) { + if (_.has(result, key)) result[key]++; else result[key] = 1; + }); + + // Safely create a real, live array from anything iterable. + _.toArray = function(obj) { + if (!obj) return []; + if (_.isArray(obj)) return slice.call(obj); + if (isArrayLike(obj)) return _.map(obj, _.identity); + return _.values(obj); + }; + + // Return the number of elements in an object. + _.size = function(obj) { + if (obj == null) return 0; + return isArrayLike(obj) ? obj.length : _.keys(obj).length; + }; + + // Split a collection into two arrays: one whose elements all satisfy the given + // predicate, and one whose elements all do not satisfy the predicate. + _.partition = function(obj, predicate, context) { + predicate = cb(predicate, context); + var pass = [], fail = []; + _.each(obj, function(value, key, obj) { + (predicate(value, key, obj) ? pass : fail).push(value); + }); + return [pass, fail]; + }; + + // Array Functions + // --------------- + + // Get the first element of an array. Passing **n** will return the first N + // values in the array. Aliased as `head` and `take`. The **guard** check + // allows it to work with `_.map`. + _.first = _.head = _.take = function(array, n, guard) { + if (array == null) return void 0; + if (n == null || guard) return array[0]; + return _.initial(array, array.length - n); + }; + + // Returns everything but the last entry of the array. Especially useful on + // the arguments object. Passing **n** will return all the values in + // the array, excluding the last N. + _.initial = function(array, n, guard) { + return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); + }; + + // Get the last element of an array. Passing **n** will return the last N + // values in the array. + _.last = function(array, n, guard) { + if (array == null) return void 0; + if (n == null || guard) return array[array.length - 1]; + return _.rest(array, Math.max(0, array.length - n)); + }; + + // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. + // Especially useful on the arguments object. Passing an **n** will return + // the rest N values in the array. + _.rest = _.tail = _.drop = function(array, n, guard) { + return slice.call(array, n == null || guard ? 1 : n); + }; + + // Trim out all falsy values from an array. + _.compact = function(array) { + return _.filter(array, _.identity); + }; + + // Internal implementation of a recursive `flatten` function. + var flatten = function(input, shallow, strict, startIndex) { + var output = [], idx = 0; + for (var i = startIndex || 0, length = getLength(input); i < length; i++) { + var value = input[i]; + if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { + //flatten current level of array or arguments object + if (!shallow) value = flatten(value, shallow, strict); + var j = 0, len = value.length; + output.length += len; + while (j < len) { + output[idx++] = value[j++]; + } + } else if (!strict) { + output[idx++] = value; + } + } + return output; + }; + + // Flatten out an array, either recursively (by default), or just one level. + _.flatten = function(array, shallow) { + return flatten(array, shallow, false); + }; + + // Return a version of the array that does not contain the specified value(s). + _.without = function(array) { + return _.difference(array, slice.call(arguments, 1)); + }; + + // Produce a duplicate-free version of the array. If the array has already + // been sorted, you have the option of using a faster algorithm. + // Aliased as `unique`. + _.uniq = _.unique = function(array, isSorted, iteratee, context) { + if (!_.isBoolean(isSorted)) { + context = iteratee; + iteratee = isSorted; + isSorted = false; + } + if (iteratee != null) iteratee = cb(iteratee, context); + var result = []; + var seen = []; + for (var i = 0, length = getLength(array); i < length; i++) { + var value = array[i], + computed = iteratee ? iteratee(value, i, array) : value; + if (isSorted) { + if (!i || seen !== computed) result.push(value); + seen = computed; + } else if (iteratee) { + if (!_.contains(seen, computed)) { + seen.push(computed); + result.push(value); + } + } else if (!_.contains(result, value)) { + result.push(value); + } + } + return result; + }; + + // Produce an array that contains the union: each distinct element from all of + // the passed-in arrays. + _.union = function() { + return _.uniq(flatten(arguments, true, true)); + }; + + // Produce an array that contains every item shared between all the + // passed-in arrays. + _.intersection = function(array) { + var result = []; + var argsLength = arguments.length; + for (var i = 0, length = getLength(array); i < length; i++) { + var item = array[i]; + if (_.contains(result, item)) continue; + for (var j = 1; j < argsLength; j++) { + if (!_.contains(arguments[j], item)) break; + } + if (j === argsLength) result.push(item); + } + return result; + }; + + // Take the difference between one array and a number of other arrays. + // Only the elements present in just the first array will remain. + _.difference = function(array) { + var rest = flatten(arguments, true, true, 1); + return _.filter(array, function(value){ + return !_.contains(rest, value); + }); + }; + + // Zip together multiple lists into a single array -- elements that share + // an index go together. + _.zip = function() { + return _.unzip(arguments); + }; + + // Complement of _.zip. Unzip accepts an array of arrays and groups + // each array's elements on shared indices + _.unzip = function(array) { + var length = array && _.max(array, getLength).length || 0; + var result = Array(length); + + for (var index = 0; index < length; index++) { + result[index] = _.pluck(array, index); + } + return result; + }; + + // Converts lists into objects. Pass either a single array of `[key, value]` + // pairs, or two parallel arrays of the same length -- one of keys, and one of + // the corresponding values. + _.object = function(list, values) { + var result = {}; + for (var i = 0, length = getLength(list); i < length; i++) { + if (values) { + result[list[i]] = values[i]; + } else { + result[list[i][0]] = list[i][1]; + } + } + return result; + }; + + // Generator function to create the findIndex and findLastIndex functions + function createPredicateIndexFinder(dir) { + return function(array, predicate, context) { + predicate = cb(predicate, context); + var length = getLength(array); + var index = dir > 0 ? 0 : length - 1; + for (; index >= 0 && index < length; index += dir) { + if (predicate(array[index], index, array)) return index; + } + return -1; + }; + } + + // Returns the first index on an array-like that passes a predicate test + _.findIndex = createPredicateIndexFinder(1); + _.findLastIndex = createPredicateIndexFinder(-1); + + // Use a comparator function to figure out the smallest index at which + // an object should be inserted so as to maintain order. Uses binary search. + _.sortedIndex = function(array, obj, iteratee, context) { + iteratee = cb(iteratee, context, 1); + var value = iteratee(obj); + var low = 0, high = getLength(array); + while (low < high) { + var mid = Math.floor((low + high) / 2); + if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; + } + return low; + }; + + // Generator function to create the indexOf and lastIndexOf functions + function createIndexFinder(dir, predicateFind, sortedIndex) { + return function(array, item, idx) { + var i = 0, length = getLength(array); + if (typeof idx == 'number') { + if (dir > 0) { + i = idx >= 0 ? idx : Math.max(idx + length, i); + } else { + length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; + } + } else if (sortedIndex && idx && length) { + idx = sortedIndex(array, item); + return array[idx] === item ? idx : -1; + } + if (item !== item) { + idx = predicateFind(slice.call(array, i, length), _.isNaN); + return idx >= 0 ? idx + i : -1; + } + for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { + if (array[idx] === item) return idx; + } + return -1; + }; + } + + // Return the position of the first occurrence of an item in an array, + // or -1 if the item is not included in the array. + // If the array is large and already in sort order, pass `true` + // for **isSorted** to use binary search. + _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex); + _.lastIndexOf = createIndexFinder(-1, _.findLastIndex); + + // Generate an integer Array containing an arithmetic progression. A port of + // the native Python `range()` function. See + // [the Python documentation](http://docs.python.org/library/functions.html#range). + _.range = function(start, stop, step) { + if (stop == null) { + stop = start || 0; + start = 0; + } + step = step || 1; + + var length = Math.max(Math.ceil((stop - start) / step), 0); + var range = Array(length); + + for (var idx = 0; idx < length; idx++, start += step) { + range[idx] = start; + } + + return range; + }; + + // Function (ahem) Functions + // ------------------ + + // Determines whether to execute a function as a constructor + // or a normal function with the provided arguments + var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) { + if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); + var self = baseCreate(sourceFunc.prototype); + var result = sourceFunc.apply(self, args); + if (_.isObject(result)) return result; + return self; + }; + + // Create a function bound to a given object (assigning `this`, and arguments, + // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if + // available. + _.bind = function(func, context) { + if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); + if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function'); + var args = slice.call(arguments, 2); + var bound = function() { + return executeBound(func, bound, context, this, args.concat(slice.call(arguments))); + }; + return bound; + }; + + // Partially apply a function by creating a version that has had some of its + // arguments pre-filled, without changing its dynamic `this` context. _ acts + // as a placeholder, allowing any combination of arguments to be pre-filled. + _.partial = function(func) { + var boundArgs = slice.call(arguments, 1); + var bound = function() { + var position = 0, length = boundArgs.length; + var args = Array(length); + for (var i = 0; i < length; i++) { + args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i]; + } + while (position < arguments.length) args.push(arguments[position++]); + return executeBound(func, bound, this, this, args); + }; + return bound; + }; + + // Bind a number of an object's methods to that object. Remaining arguments + // are the method names to be bound. Useful for ensuring that all callbacks + // defined on an object belong to it. + _.bindAll = function(obj) { + var i, length = arguments.length, key; + if (length <= 1) throw new Error('bindAll must be passed function names'); + for (i = 1; i < length; i++) { + key = arguments[i]; + obj[key] = _.bind(obj[key], obj); + } + return obj; + }; + + // Memoize an expensive function by storing its results. + _.memoize = function(func, hasher) { + var memoize = function(key) { + var cache = memoize.cache; + var address = '' + (hasher ? hasher.apply(this, arguments) : key); + if (!_.has(cache, address)) cache[address] = func.apply(this, arguments); + return cache[address]; + }; + memoize.cache = {}; + return memoize; + }; + + // Delays a function for the given number of milliseconds, and then calls + // it with the arguments supplied. + _.delay = function(func, wait) { + var args = slice.call(arguments, 2); + return setTimeout(function(){ + return func.apply(null, args); + }, wait); + }; + + // Defers a function, scheduling it to run after the current call stack has + // cleared. + _.defer = _.partial(_.delay, _, 1); + + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. Normally, the throttled function will run + // as much as it can, without ever going more than once per `wait` duration; + // but if you'd like to disable the execution on the leading edge, pass + // `{leading: false}`. To disable execution on the trailing edge, ditto. + _.throttle = function(func, wait, options) { + var context, args, result; + var timeout = null; + var previous = 0; + if (!options) options = {}; + var later = function() { + previous = options.leading === false ? 0 : _.now(); + timeout = null; + result = func.apply(context, args); + if (!timeout) context = args = null; + }; + return function() { + var now = _.now(); + if (!previous && options.leading === false) previous = now; + var remaining = wait - (now - previous); + context = this; + args = arguments; + if (remaining <= 0 || remaining > wait) { + if (timeout) { + clearTimeout(timeout); + timeout = null; + } + previous = now; + result = func.apply(context, args); + if (!timeout) context = args = null; + } else if (!timeout && options.trailing !== false) { + timeout = setTimeout(later, remaining); + } + return result; + }; + }; + + // Returns a function, that, as long as it continues to be invoked, will not + // be triggered. The function will be called after it stops being called for + // N milliseconds. If `immediate` is passed, trigger the function on the + // leading edge, instead of the trailing. + _.debounce = function(func, wait, immediate) { + var timeout, args, context, timestamp, result; + + var later = function() { + var last = _.now() - timestamp; + + if (last < wait && last >= 0) { + timeout = setTimeout(later, wait - last); + } else { + timeout = null; + if (!immediate) { + result = func.apply(context, args); + if (!timeout) context = args = null; + } + } + }; + + return function() { + context = this; + args = arguments; + timestamp = _.now(); + var callNow = immediate && !timeout; + if (!timeout) timeout = setTimeout(later, wait); + if (callNow) { + result = func.apply(context, args); + context = args = null; + } + + return result; + }; + }; + + // Returns the first function passed as an argument to the second, + // allowing you to adjust arguments, run code before and after, and + // conditionally execute the original function. + _.wrap = function(func, wrapper) { + return _.partial(wrapper, func); + }; + + // Returns a negated version of the passed-in predicate. + _.negate = function(predicate) { + return function() { + return !predicate.apply(this, arguments); + }; + }; + + // Returns a function that is the composition of a list of functions, each + // consuming the return value of the function that follows. + _.compose = function() { + var args = arguments; + var start = args.length - 1; + return function() { + var i = start; + var result = args[start].apply(this, arguments); + while (i--) result = args[i].call(this, result); + return result; + }; + }; + + // Returns a function that will only be executed on and after the Nth call. + _.after = function(times, func) { + return function() { + if (--times < 1) { + return func.apply(this, arguments); + } + }; + }; + + // Returns a function that will only be executed up to (but not including) the Nth call. + _.before = function(times, func) { + var memo; + return function() { + if (--times > 0) { + memo = func.apply(this, arguments); + } + if (times <= 1) func = null; + return memo; + }; + }; + + // Returns a function that will be executed at most one time, no matter how + // often you call it. Useful for lazy initialization. + _.once = _.partial(_.before, 2); + + // Object Functions + // ---------------- + + // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. + var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); + var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', + 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; + + function collectNonEnumProps(obj, keys) { + var nonEnumIdx = nonEnumerableProps.length; + var constructor = obj.constructor; + var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto; + + // Constructor is a special case. + var prop = 'constructor'; + if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop); + + while (nonEnumIdx--) { + prop = nonEnumerableProps[nonEnumIdx]; + if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) { + keys.push(prop); + } + } + } + + // Retrieve the names of an object's own properties. + // Delegates to **ECMAScript 5**'s native `Object.keys` + _.keys = function(obj) { + if (!_.isObject(obj)) return []; + if (nativeKeys) return nativeKeys(obj); + var keys = []; + for (var key in obj) if (_.has(obj, key)) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + }; + + // Retrieve all the property names of an object. + _.allKeys = function(obj) { + if (!_.isObject(obj)) return []; + var keys = []; + for (var key in obj) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + }; + + // Retrieve the values of an object's properties. + _.values = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var values = Array(length); + for (var i = 0; i < length; i++) { + values[i] = obj[keys[i]]; + } + return values; + }; + + // Returns the results of applying the iteratee to each element of the object + // In contrast to _.map it returns an object + _.mapObject = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var keys = _.keys(obj), + length = keys.length, + results = {}, + currentKey; + for (var index = 0; index < length; index++) { + currentKey = keys[index]; + results[currentKey] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + }; + + // Convert an object into a list of `[key, value]` pairs. + _.pairs = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var pairs = Array(length); + for (var i = 0; i < length; i++) { + pairs[i] = [keys[i], obj[keys[i]]]; + } + return pairs; + }; + + // Invert the keys and values of an object. The values must be serializable. + _.invert = function(obj) { + var result = {}; + var keys = _.keys(obj); + for (var i = 0, length = keys.length; i < length; i++) { + result[obj[keys[i]]] = keys[i]; + } + return result; + }; + + // Return a sorted list of the function names available on the object. + // Aliased as `methods` + _.functions = _.methods = function(obj) { + var names = []; + for (var key in obj) { + if (_.isFunction(obj[key])) names.push(key); + } + return names.sort(); + }; + + // Extend a given object with all the properties in passed-in object(s). + _.extend = createAssigner(_.allKeys); + + // Assigns a given object with all the own properties in the passed-in object(s) + // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) + _.extendOwn = _.assign = createAssigner(_.keys); + + // Returns the first key on an object that passes a predicate test + _.findKey = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = _.keys(obj), key; + for (var i = 0, length = keys.length; i < length; i++) { + key = keys[i]; + if (predicate(obj[key], key, obj)) return key; + } + }; + + // Return a copy of the object only containing the whitelisted properties. + _.pick = function(object, oiteratee, context) { + var result = {}, obj = object, iteratee, keys; + if (obj == null) return result; + if (_.isFunction(oiteratee)) { + keys = _.allKeys(obj); + iteratee = optimizeCb(oiteratee, context); + } else { + keys = flatten(arguments, false, false, 1); + iteratee = function(value, key, obj) { return key in obj; }; + obj = Object(obj); + } + for (var i = 0, length = keys.length; i < length; i++) { + var key = keys[i]; + var value = obj[key]; + if (iteratee(value, key, obj)) result[key] = value; + } + return result; + }; + + // Return a copy of the object without the blacklisted properties. + _.omit = function(obj, iteratee, context) { + if (_.isFunction(iteratee)) { + iteratee = _.negate(iteratee); + } else { + var keys = _.map(flatten(arguments, false, false, 1), String); + iteratee = function(value, key) { + return !_.contains(keys, key); + }; + } + return _.pick(obj, iteratee, context); + }; + + // Fill in a given object with default properties. + _.defaults = createAssigner(_.allKeys, true); + + // Creates an object that inherits from the given prototype object. + // If additional properties are provided then they will be added to the + // created object. + _.create = function(prototype, props) { + var result = baseCreate(prototype); + if (props) _.extendOwn(result, props); + return result; + }; + + // Create a (shallow-cloned) duplicate of an object. + _.clone = function(obj) { + if (!_.isObject(obj)) return obj; + return _.isArray(obj) ? obj.slice() : _.extend({}, obj); + }; + + // Invokes interceptor with the obj, and then returns obj. + // The primary purpose of this method is to "tap into" a method chain, in + // order to perform operations on intermediate results within the chain. + _.tap = function(obj, interceptor) { + interceptor(obj); + return obj; + }; + + // Returns whether an object has a given set of `key:value` pairs. + _.isMatch = function(object, attrs) { + var keys = _.keys(attrs), length = keys.length; + if (object == null) return !length; + var obj = Object(object); + for (var i = 0; i < length; i++) { + var key = keys[i]; + if (attrs[key] !== obj[key] || !(key in obj)) return false; + } + return true; + }; + + + // Internal recursive comparison function for `isEqual`. + var eq = function(a, b, aStack, bStack) { + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). + if (a === b) return a !== 0 || 1 / a === 1 / b; + // A strict comparison is necessary because `null == undefined`. + if (a == null || b == null) return a === b; + // Unwrap any wrapped objects. + if (a instanceof _) a = a._wrapped; + if (b instanceof _) b = b._wrapped; + // Compare `[[Class]]` names. + var className = toString.call(a); + if (className !== toString.call(b)) return false; + switch (className) { + // Strings, numbers, regular expressions, dates, and booleans are compared by value. + case '[object RegExp]': + // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return '' + a === '' + b; + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. + // Object(NaN) is equivalent to NaN + if (+a !== +a) return +b !== +b; + // An `egal` comparison is performed for other numeric values. + return +a === 0 ? 1 / +a === 1 / b : +a === +b; + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a === +b; + } + + var areArrays = className === '[object Array]'; + if (!areArrays) { + if (typeof a != 'object' || typeof b != 'object') return false; + + // Objects with different constructors are not equivalent, but `Object`s or `Array`s + // from different frames are. + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && + _.isFunction(bCtor) && bCtor instanceof bCtor) + && ('constructor' in a && 'constructor' in b)) { + return false; + } + } + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + + // Initializing stack of traversed objects. + // It's done here since we only need them for objects and arrays comparison. + aStack = aStack || []; + bStack = bStack || []; + var length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (aStack[length] === a) return bStack[length] === b; + } + + // Add the first object to the stack of traversed objects. + aStack.push(a); + bStack.push(b); + + // Recursively compare objects and arrays. + if (areArrays) { + // Compare array lengths to determine if a deep comparison is necessary. + length = a.length; + if (length !== b.length) return false; + // Deep compare the contents, ignoring non-numeric properties. + while (length--) { + if (!eq(a[length], b[length], aStack, bStack)) return false; + } + } else { + // Deep compare objects. + var keys = _.keys(a), key; + length = keys.length; + // Ensure that both objects contain the same number of properties before comparing deep equality. + if (_.keys(b).length !== length) return false; + while (length--) { + // Deep compare each member + key = keys[length]; + if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; + } + } + // Remove the first object from the stack of traversed objects. + aStack.pop(); + bStack.pop(); + return true; + }; + + // Perform a deep comparison to check if two objects are equal. + _.isEqual = function(a, b) { + return eq(a, b); + }; + + // Is a given array, string, or object empty? + // An "empty" object has no enumerable own-properties. + _.isEmpty = function(obj) { + if (obj == null) return true; + if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; + return _.keys(obj).length === 0; + }; + + // Is a given value a DOM element? + _.isElement = function(obj) { + return !!(obj && obj.nodeType === 1); + }; + + // Is a given value an array? + // Delegates to ECMA5's native Array.isArray + _.isArray = nativeIsArray || function(obj) { + return toString.call(obj) === '[object Array]'; + }; + + // Is a given variable an object? + _.isObject = function(obj) { + var type = typeof obj; + return type === 'function' || type === 'object' && !!obj; + }; + + // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError. + _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) { + _['is' + name] = function(obj) { + return toString.call(obj) === '[object ' + name + ']'; + }; + }); + + // Define a fallback version of the method in browsers (ahem, IE < 9), where + // there isn't any inspectable "Arguments" type. + if (!_.isArguments(arguments)) { + _.isArguments = function(obj) { + return _.has(obj, 'callee'); + }; + } + + // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8, + // IE 11 (#1621), and in Safari 8 (#1929). + if (typeof /./ != 'function' && typeof Int8Array != 'object') { + _.isFunction = function(obj) { + return typeof obj == 'function' || false; + }; + } + + // Is a given object a finite number? + _.isFinite = function(obj) { + return isFinite(obj) && !isNaN(parseFloat(obj)); + }; + + // Is the given value `NaN`? (NaN is the only number which does not equal itself). + _.isNaN = function(obj) { + return _.isNumber(obj) && obj !== +obj; + }; + + // Is a given value a boolean? + _.isBoolean = function(obj) { + return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; + }; + + // Is a given value equal to null? + _.isNull = function(obj) { + return obj === null; + }; + + // Is a given variable undefined? + _.isUndefined = function(obj) { + return obj === void 0; + }; + + // Shortcut function for checking if an object has a given property directly + // on itself (in other words, not on a prototype). + _.has = function(obj, key) { + return obj != null && hasOwnProperty.call(obj, key); + }; + + // Utility Functions + // ----------------- + + // Run Underscore.js in *noConflict* mode, returning the `_` variable to its + // previous owner. Returns a reference to the Underscore object. + _.noConflict = function() { + root._ = previousUnderscore; + return this; + }; + + // Keep the identity function around for default iteratees. + _.identity = function(value) { + return value; + }; + + // Predicate-generating functions. Often useful outside of Underscore. + _.constant = function(value) { + return function() { + return value; + }; + }; + + _.noop = function(){}; + + _.property = property; + + // Generates a function for a given object that returns a given property. + _.propertyOf = function(obj) { + return obj == null ? function(){} : function(key) { + return obj[key]; + }; + }; + + // Returns a predicate for checking whether an object has a given set of + // `key:value` pairs. + _.matcher = _.matches = function(attrs) { + attrs = _.extendOwn({}, attrs); + return function(obj) { + return _.isMatch(obj, attrs); + }; + }; + + // Run a function **n** times. + _.times = function(n, iteratee, context) { + var accum = Array(Math.max(0, n)); + iteratee = optimizeCb(iteratee, context, 1); + for (var i = 0; i < n; i++) accum[i] = iteratee(i); + return accum; + }; + + // Return a random integer between min and max (inclusive). + _.random = function(min, max) { + if (max == null) { + max = min; + min = 0; + } + return min + Math.floor(Math.random() * (max - min + 1)); + }; + + // A (possibly faster) way to get the current timestamp as an integer. + _.now = Date.now || function() { + return new Date().getTime(); + }; + + // List of HTML entities for escaping. + var escapeMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; + var unescapeMap = _.invert(escapeMap); + + // Functions for escaping and unescaping strings to/from HTML interpolation. + var createEscaper = function(map) { + var escaper = function(match) { + return map[match]; + }; + // Regexes for identifying a key that needs to be escaped + var source = '(?:' + _.keys(map).join('|') + ')'; + var testRegexp = RegExp(source); + var replaceRegexp = RegExp(source, 'g'); + return function(string) { + string = string == null ? '' : '' + string; + return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; + }; + }; + _.escape = createEscaper(escapeMap); + _.unescape = createEscaper(unescapeMap); + + // If the value of the named `property` is a function then invoke it with the + // `object` as context; otherwise, return it. + _.result = function(object, property, fallback) { + var value = object == null ? void 0 : object[property]; + if (value === void 0) { + value = fallback; + } + return _.isFunction(value) ? value.call(object) : value; + }; + + // Generate a unique integer id (unique within the entire client session). + // Useful for temporary DOM ids. + var idCounter = 0; + _.uniqueId = function(prefix) { + var id = ++idCounter + ''; + return prefix ? prefix + id : id; + }; + + // By default, Underscore uses ERB-style template delimiters, change the + // following template settings to use alternative delimiters. + _.templateSettings = { + evaluate : /<%([\s\S]+?)%>/g, + interpolate : /<%=([\s\S]+?)%>/g, + escape : /<%-([\s\S]+?)%>/g + }; + + // When customizing `templateSettings`, if you don't want to define an + // interpolation, evaluation or escaping regex, we need one that is + // guaranteed not to match. + var noMatch = /(.)^/; + + // Certain characters need to be escaped so that they can be put into a + // string literal. + var escapes = { + "'": "'", + '\\': '\\', + '\r': 'r', + '\n': 'n', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + var escaper = /\\|'|\r|\n|\u2028|\u2029/g; + + var escapeChar = function(match) { + return '\\' + escapes[match]; + }; + + // JavaScript micro-templating, similar to John Resig's implementation. + // Underscore templating handles arbitrary delimiters, preserves whitespace, + // and correctly escapes quotes within interpolated code. + // NB: `oldSettings` only exists for backwards compatibility. + _.template = function(text, settings, oldSettings) { + if (!settings && oldSettings) settings = oldSettings; + settings = _.defaults({}, settings, _.templateSettings); + + // Combine delimiters into one regular expression via alternation. + var matcher = RegExp([ + (settings.escape || noMatch).source, + (settings.interpolate || noMatch).source, + (settings.evaluate || noMatch).source + ].join('|') + '|$', 'g'); + + // Compile the template source, escaping string literals appropriately. + var index = 0; + var source = "__p+='"; + text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { + source += text.slice(index, offset).replace(escaper, escapeChar); + index = offset + match.length; + + if (escape) { + source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; + } else if (interpolate) { + source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; + } else if (evaluate) { + source += "';\n" + evaluate + "\n__p+='"; + } + + // Adobe VMs need the match returned to produce the correct offest. + return match; + }); + source += "';\n"; + + // If a variable is not specified, place data values in local scope. + if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; + + source = "var __t,__p='',__j=Array.prototype.join," + + "print=function(){__p+=__j.call(arguments,'');};\n" + + source + 'return __p;\n'; + + try { + var render = new Function(settings.variable || 'obj', '_', source); + } catch (e) { + e.source = source; + throw e; + } + + var template = function(data) { + return render.call(this, data, _); + }; + + // Provide the compiled source as a convenience for precompilation. + var argument = settings.variable || 'obj'; + template.source = 'function(' + argument + '){\n' + source + '}'; + + return template; + }; + + // Add a "chain" function. Start chaining a wrapped Underscore object. + _.chain = function(obj) { + var instance = _(obj); + instance._chain = true; + return instance; + }; + + // OOP + // --------------- + // If Underscore is called as a function, it returns a wrapped object that + // can be used OO-style. This wrapper holds altered versions of all the + // underscore functions. Wrapped objects may be chained. + + // Helper function to continue chaining intermediate results. + var result = function(instance, obj) { + return instance._chain ? _(obj).chain() : obj; + }; + + // Add your own custom functions to the Underscore object. + _.mixin = function(obj) { + _.each(_.functions(obj), function(name) { + var func = _[name] = obj[name]; + _.prototype[name] = function() { + var args = [this._wrapped]; + push.apply(args, arguments); + return result(this, func.apply(_, args)); + }; + }); + }; + + // Add all of the Underscore functions to the wrapper object. + _.mixin(_); + + // Add all mutator Array functions to the wrapper. + _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + var obj = this._wrapped; + method.apply(obj, arguments); + if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0]; + return result(this, obj); + }; + }); + + // Add all accessor Array functions to the wrapper. + _.each(['concat', 'join', 'slice'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + return result(this, method.apply(this._wrapped, arguments)); + }; + }); + + // Extracts the result from a wrapped and chained object. + _.prototype.value = function() { + return this._wrapped; + }; + + // Provide unwrapping proxy for some methods used in engine operations + // such as arithmetic and JSON stringification. + _.prototype.valueOf = _.prototype.toJSON = _.prototype.value; + + _.prototype.toString = function() { + return '' + this._wrapped; + }; + + // AMD registration happens at the end for compatibility with AMD loaders + // that may not enforce next-turn semantics on modules. Even though general + // practice for AMD registration is to be anonymous, underscore registers + // as a named module because, like jQuery, it is a base library that is + // popular enough to be bundled in a third party lib, but not be part of + // an AMD load request. Those cases could generate an error when an + // anonymous define() is called outside of a loader request. + if (typeof define === 'function' && define.amd) { + define('underscore', [], function() { + return _; + }); + } +}.call(this)); + +},{}],26:[function(require,module,exports){ +arguments[4][19][0].apply(exports,arguments) +},{"dup":19}],27:[function(require,module,exports){ +module.exports = function isBuffer(arg) { + return arg && typeof arg === 'object' + && typeof arg.copy === 'function' + && typeof arg.fill === 'function' + && typeof arg.readUInt8 === 'function'; +} +},{}],28:[function(require,module,exports){ +(function (process,global){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var formatRegExp = /%[sdj%]/g; +exports.format = function(f) { + if (!isString(f)) { + var objects = []; + for (var i = 0; i < arguments.length; i++) { + objects.push(inspect(arguments[i])); + } + return objects.join(' '); + } + + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function(x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return JSON.stringify(args[i++]); + } catch (_) { + return '[Circular]'; + } + default: + return x; + } + }); + for (var x = args[i]; i < len; x = args[++i]) { + if (isNull(x) || !isObject(x)) { + str += ' ' + x; + } else { + str += ' ' + inspect(x); + } + } + return str; +}; + + +// Mark that a method should not be used. +// Returns a modified function which warns once by default. +// If --no-deprecation is set, then it is a no-op. +exports.deprecate = function(fn, msg) { + // Allow for deprecating things in the process of starting up. + if (isUndefined(global.process)) { + return function() { + return exports.deprecate(fn, msg).apply(this, arguments); + }; + } + + if (process.noDeprecation === true) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (process.throwDeprecation) { + throw new Error(msg); + } else if (process.traceDeprecation) { + console.trace(msg); + } else { + console.error(msg); + } + warned = true; + } + return fn.apply(this, arguments); + } + + return deprecated; +}; + + +var debugs = {}; +var debugEnviron; +exports.debuglog = function(set) { + if (isUndefined(debugEnviron)) + debugEnviron = process.env.NODE_DEBUG || ''; + set = set.toUpperCase(); + if (!debugs[set]) { + if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { + var pid = process.pid; + debugs[set] = function() { + var msg = exports.format.apply(exports, arguments); + console.error('%s %d: %s', set, pid, msg); + }; + } else { + debugs[set] = function() {}; + } + } + return debugs[set]; +}; + + +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + */ +/* legacy: obj, showHidden, depth, colors*/ +function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + exports._extend(ctx, opts); + } + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); +} +exports.inspect = inspect; + + +// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] +}; + +// Don't use 'blue' not visible on cmd.exe +inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' +}; + + +function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; + + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; + } +} + + +function stylizeNoColor(str, styleType) { + return str; +} + + +function arrayToHash(array) { + var hash = {}; + + array.forEach(function(val, idx) { + hash[val] = true; + }); + + return hash; +} + + +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes, ctx); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } + + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // Look up the keys of the object. + var keys = Object.keys(value); + var visibleKeys = arrayToHash(keys); + + if (ctx.showHidden) { + keys = Object.getOwnPropertyNames(value); + } + + // IE doesn't make error fields non-enumerable + // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx + if (isError(value) + && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { + return formatError(value); + } + + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } + + var base = '', array = false, braces = ['{', '}']; + + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); +} + + +function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); +} + + +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} + + +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwnProperty(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} + + +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + if (!hasOwnProperty(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); + } else { + str = formatValue(ctx, desc.value, recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } + + return name + ': ' + str; +} + + +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} + + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return Array.isArray(ar); +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; + +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; + +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; + +exports.isBuffer = require('./support/isBuffer'); + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + + +function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +} + + +var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; + +// 26 Feb 16:19:34 +function timestamp() { + var d = new Date(); + var time = [pad(d.getHours()), + pad(d.getMinutes()), + pad(d.getSeconds())].join(':'); + return [d.getDate(), months[d.getMonth()], time].join(' '); +} + + +// log is just a thin wrapper to console.log that prepends a timestamp +exports.log = function() { + console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +}; + + +/** + * Inherit the prototype methods from one constructor into another. + * + * The Function.prototype.inherits from lang.js rewritten as a standalone + * function (not on Function.prototype). NOTE: If this file is to be loaded + * during bootstrapping this function needs to be rewritten using some native + * functions as prototype setup using normal JavaScript does not work as + * expected during bootstrapping (see mirror.js in r114903). + * + * @param {function} ctor Constructor function which needs to inherit the + * prototype. + * @param {function} superCtor Constructor function to inherit prototype from. + */ +exports.inherits = require('inherits'); + +exports._extend = function(origin, add) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; + + var keys = Object.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; + } + return origin; +}; + +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + +}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./support/isBuffer":27,"_process":24,"inherits":26}],29:[function(require,module,exports){ +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) + + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') + + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) + + return wrapper + + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] + } + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret + } +} + +},{}]},{},[7])(7) +}); \ No newline at end of file diff --git a/assets/javascripts/mathjax.js b/assets/javascripts/mathjax.js new file mode 100644 index 000000000..a80ddbff7 --- /dev/null +++ b/assets/javascripts/mathjax.js @@ -0,0 +1,16 @@ +window.MathJax = { + tex: { + inlineMath: [["\\(", "\\)"]], + displayMath: [["\\[", "\\]"]], + processEscapes: true, + processEnvironments: true + }, + options: { + ignoreHtmlClass: ".*|", + processHtmlClass: "arithmatex" + } +}; + +document$.subscribe(() => { + MathJax.typesetPromise() +}) \ No newline at end of file diff --git a/assets/javascripts/workers/search.ecf98df9.min.js b/assets/javascripts/workers/search.ecf98df9.min.js new file mode 100644 index 000000000..f8c739912 --- /dev/null +++ b/assets/javascripts/workers/search.ecf98df9.min.js @@ -0,0 +1,48 @@ +"use strict";(()=>{var ge=Object.create;var W=Object.defineProperty,ye=Object.defineProperties,me=Object.getOwnPropertyDescriptor,ve=Object.getOwnPropertyDescriptors,xe=Object.getOwnPropertyNames,G=Object.getOwnPropertySymbols,Se=Object.getPrototypeOf,X=Object.prototype.hasOwnProperty,Qe=Object.prototype.propertyIsEnumerable;var J=(t,e,r)=>e in t?W(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,M=(t,e)=>{for(var r in e||(e={}))X.call(e,r)&&J(t,r,e[r]);if(G)for(var r of G(e))Qe.call(e,r)&&J(t,r,e[r]);return t},Z=(t,e)=>ye(t,ve(e));var K=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var be=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of xe(e))!X.call(t,i)&&i!==r&&W(t,i,{get:()=>e[i],enumerable:!(n=me(e,i))||n.enumerable});return t};var H=(t,e,r)=>(r=t!=null?ge(Se(t)):{},be(e||!t||!t.__esModule?W(r,"default",{value:t,enumerable:!0}):r,t));var z=(t,e,r)=>new Promise((n,i)=>{var s=u=>{try{a(r.next(u))}catch(c){i(c)}},o=u=>{try{a(r.throw(u))}catch(c){i(c)}},a=u=>u.done?n(u.value):Promise.resolve(u.value).then(s,o);a((r=r.apply(t,e)).next())});var re=K((ee,te)=>{/** + * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 + * Copyright (C) 2020 Oliver Nightingale + * @license MIT + */(function(){var t=function(e){var r=new t.Builder;return r.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),r.searchPipeline.add(t.stemmer),e.call(r,r),r.build()};t.version="2.3.9";/*! + * lunr.utils + * Copyright (C) 2020 Oliver Nightingale + */t.utils={},t.utils.warn=function(e){return function(r){e.console&&console.warn&&console.warn(r)}}(this),t.utils.asString=function(e){return e==null?"":e.toString()},t.utils.clone=function(e){if(e==null)return e;for(var r=Object.create(null),n=Object.keys(e),i=0;i0){var h=t.utils.clone(r)||{};h.position=[a,c],h.index=s.length,s.push(new t.Token(n.slice(a,o),h))}a=o+1}}return s},t.tokenizer.separator=/[\s\-]+/;/*! + * lunr.Pipeline + * Copyright (C) 2020 Oliver Nightingale + */t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions=Object.create(null),t.Pipeline.registerFunction=function(e,r){r in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+r),e.label=r,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var r=e.label&&e.label in this.registeredFunctions;r||t.utils.warn(`Function is not registered with pipeline. This may cause problems when serialising the index. +`,e)},t.Pipeline.load=function(e){var r=new t.Pipeline;return e.forEach(function(n){var i=t.Pipeline.registeredFunctions[n];if(i)r.add(i);else throw new Error("Cannot load unregistered function: "+n)}),r},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(r){t.Pipeline.warnIfFunctionNotRegistered(r),this._stack.push(r)},this)},t.Pipeline.prototype.after=function(e,r){t.Pipeline.warnIfFunctionNotRegistered(r);var n=this._stack.indexOf(e);if(n==-1)throw new Error("Cannot find existingFn");n=n+1,this._stack.splice(n,0,r)},t.Pipeline.prototype.before=function(e,r){t.Pipeline.warnIfFunctionNotRegistered(r);var n=this._stack.indexOf(e);if(n==-1)throw new Error("Cannot find existingFn");this._stack.splice(n,0,r)},t.Pipeline.prototype.remove=function(e){var r=this._stack.indexOf(e);r!=-1&&this._stack.splice(r,1)},t.Pipeline.prototype.run=function(e){for(var r=this._stack.length,n=0;n1&&(oe&&(n=s),o!=e);)i=n-r,s=r+Math.floor(i/2),o=this.elements[s*2];if(o==e||o>e)return s*2;if(ou?h+=2:a==u&&(r+=n[c+1]*i[h+1],c+=2,h+=2);return r},t.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},t.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),r=1,n=0;r0){var o=s.str.charAt(0),a;o in s.node.edges?a=s.node.edges[o]:(a=new t.TokenSet,s.node.edges[o]=a),s.str.length==1&&(a.final=!0),i.push({node:a,editsRemaining:s.editsRemaining,str:s.str.slice(1)})}if(s.editsRemaining!=0){if("*"in s.node.edges)var u=s.node.edges["*"];else{var u=new t.TokenSet;s.node.edges["*"]=u}if(s.str.length==0&&(u.final=!0),i.push({node:u,editsRemaining:s.editsRemaining-1,str:s.str}),s.str.length>1&&i.push({node:s.node,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)}),s.str.length==1&&(s.node.final=!0),s.str.length>=1){if("*"in s.node.edges)var c=s.node.edges["*"];else{var c=new t.TokenSet;s.node.edges["*"]=c}s.str.length==1&&(c.final=!0),i.push({node:c,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)})}if(s.str.length>1){var h=s.str.charAt(0),y=s.str.charAt(1),g;y in s.node.edges?g=s.node.edges[y]:(g=new t.TokenSet,s.node.edges[y]=g),s.str.length==1&&(g.final=!0),i.push({node:g,editsRemaining:s.editsRemaining-1,str:h+s.str.slice(2)})}}}return n},t.TokenSet.fromString=function(e){for(var r=new t.TokenSet,n=r,i=0,s=e.length;i=e;r--){var n=this.uncheckedNodes[r],i=n.child.toString();i in this.minimizedNodes?n.parent.edges[n.char]=this.minimizedNodes[i]:(n.child._str=i,this.minimizedNodes[i]=n.child),this.uncheckedNodes.pop()}};/*! + * lunr.Index + * Copyright (C) 2020 Oliver Nightingale + */t.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},t.Index.prototype.search=function(e){return this.query(function(r){var n=new t.QueryParser(e,r);n.parse()})},t.Index.prototype.query=function(e){for(var r=new t.Query(this.fields),n=Object.create(null),i=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),u=0;u1?this._b=1:this._b=e},t.Builder.prototype.k1=function(e){this._k1=e},t.Builder.prototype.add=function(e,r){var n=e[this._ref],i=Object.keys(this._fields);this._documents[n]=r||{},this.documentCount+=1;for(var s=0;s=this.length)return t.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},t.QueryLexer.prototype.width=function(){return this.pos-this.start},t.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},t.QueryLexer.prototype.backup=function(){this.pos-=1},t.QueryLexer.prototype.acceptDigitRun=function(){var e,r;do e=this.next(),r=e.charCodeAt(0);while(r>47&&r<58);e!=t.QueryLexer.EOS&&this.backup()},t.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(t.QueryLexer.TERM)),e.ignore(),e.more())return t.QueryLexer.lexText},t.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.EDIT_DISTANCE),t.QueryLexer.lexText},t.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.BOOST),t.QueryLexer.lexText},t.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(t.QueryLexer.TERM)},t.QueryLexer.termSeparator=t.tokenizer.separator,t.QueryLexer.lexText=function(e){for(;;){var r=e.next();if(r==t.QueryLexer.EOS)return t.QueryLexer.lexEOS;if(r.charCodeAt(0)==92){e.escapeCharacter();continue}if(r==":")return t.QueryLexer.lexField;if(r=="~")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexEditDistance;if(r=="^")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexBoost;if(r=="+"&&e.width()===1||r=="-"&&e.width()===1)return e.emit(t.QueryLexer.PRESENCE),t.QueryLexer.lexText;if(r.match(t.QueryLexer.termSeparator))return t.QueryLexer.lexTerm}},t.QueryParser=function(e,r){this.lexer=new t.QueryLexer(e),this.query=r,this.currentClause={},this.lexemeIdx=0},t.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=t.QueryParser.parseClause;e;)e=e(this);return this.query},t.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},t.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},t.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},t.QueryParser.parseClause=function(e){var r=e.peekLexeme();if(r!=null)switch(r.type){case t.QueryLexer.PRESENCE:return t.QueryParser.parsePresence;case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var n="expected either a field or a term, found "+r.type;throw r.str.length>=1&&(n+=" with value '"+r.str+"'"),new t.QueryParseError(n,r.start,r.end)}},t.QueryParser.parsePresence=function(e){var r=e.consumeLexeme();if(r!=null){switch(r.str){case"-":e.currentClause.presence=t.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=t.Query.presence.REQUIRED;break;default:var n="unrecognised presence operator'"+r.str+"'";throw new t.QueryParseError(n,r.start,r.end)}var i=e.peekLexeme();if(i==null){var n="expecting term or field, found nothing";throw new t.QueryParseError(n,r.start,r.end)}switch(i.type){case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var n="expecting term or field, found '"+i.type+"'";throw new t.QueryParseError(n,i.start,i.end)}}},t.QueryParser.parseField=function(e){var r=e.consumeLexeme();if(r!=null){if(e.query.allFields.indexOf(r.str)==-1){var n=e.query.allFields.map(function(o){return"'"+o+"'"}).join(", "),i="unrecognised field '"+r.str+"', possible fields: "+n;throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.fields=[r.str];var s=e.peekLexeme();if(s==null){var i="expecting term, found nothing";throw new t.QueryParseError(i,r.start,r.end)}switch(s.type){case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var i="expecting term, found '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseTerm=function(e){var r=e.consumeLexeme();if(r!=null){e.currentClause.term=r.str.toLowerCase(),r.str.indexOf("*")!=-1&&(e.currentClause.usePipeline=!1);var n=e.peekLexeme();if(n==null){e.nextClause();return}switch(n.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+n.type+"'";throw new t.QueryParseError(i,n.start,n.end)}}},t.QueryParser.parseEditDistance=function(e){var r=e.consumeLexeme();if(r!=null){var n=parseInt(r.str,10);if(isNaN(n)){var i="edit distance must be numeric";throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.editDistance=n;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseBoost=function(e){var r=e.consumeLexeme();if(r!=null){var n=parseInt(r.str,10);if(isNaN(n)){var i="boost must be numeric";throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.boost=n;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},function(e,r){typeof define=="function"&&define.amd?define(r):typeof ee=="object"?te.exports=r():e.lunr=r()}(this,function(){return t})})()});var q=K((Re,ne)=>{"use strict";/*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + */var Le=/["'&<>]/;ne.exports=we;function we(t){var e=""+t,r=Le.exec(e);if(!r)return e;var n,i="",s=0,o=0;for(s=r.index;s=0;r--){let n=t[r];typeof n!="object"?n=document.createTextNode(n):n.parentNode&&n.parentNode.removeChild(n),r?e.insertBefore(this.previousSibling,n):e.replaceChild(n,this)}}}));var ie=H(q());function se(t){let e=new Map,r=new Set;for(let n of t){let[i,s]=n.location.split("#"),o=n.location,a=n.title,u=n.tags,c=(0,ie.default)(n.text).replace(/\s+(?=[,.:;!?])/g,"").replace(/\s+/g," ");if(s){let h=e.get(i);r.has(h)?e.set(o,{location:o,title:a,text:c,parent:h}):(h.title=n.title,h.text=c,r.add(h))}else e.set(o,M({location:o,title:a,text:c},u&&{tags:u}))}return e}var oe=H(q());function ae(t,e){let r=new RegExp(t.separator,"img"),n=(i,s,o)=>`${s}${o}`;return i=>{i=i.replace(/[\s*+\-:~^]+/g," ").trim();let s=new RegExp(`(^|${t.separator})(${i.replace(/[|\\{}()[\]^$+*?.-]/g,"\\$&").replace(r,"|")})`,"img");return o=>(e?(0,oe.default)(o):o).replace(s,n).replace(/<\/mark>(\s+)]*>/img,"$1")}}function ue(t){let e=new lunr.Query(["title","text"]);return new lunr.QueryParser(t,e).parse(),e.clauses}function ce(t,e){var i;let r=new Set(t),n={};for(let s=0;s!n.has(i)))]}var U=class{constructor({config:e,docs:r,options:n}){this.options=n,this.documents=se(r),this.highlight=ae(e,!1),lunr.tokenizer.separator=new RegExp(e.separator),this.index=lunr(function(){e.lang.length===1&&e.lang[0]!=="en"?this.use(lunr[e.lang[0]]):e.lang.length>1&&this.use(lunr.multiLanguage(...e.lang));let i=Ee(["trimmer","stopWordFilter","stemmer"],n.pipeline);for(let s of e.lang.map(o=>o==="en"?lunr:lunr[o]))for(let o of i)this.pipeline.remove(s[o]),this.searchPipeline.remove(s[o]);this.ref("location"),this.field("title",{boost:1e3}),this.field("text"),this.field("tags",{boost:1e6,extractor:s=>{let{tags:o=[]}=s;return o.reduce((a,u)=>[...a,...lunr.tokenizer(u)],[])}});for(let s of r)this.add(s,{boost:s.boost})})}search(e){if(e)try{let r=this.highlight(e),n=ue(e).filter(o=>o.presence!==lunr.Query.presence.PROHIBITED),i=this.index.search(`${e}*`).reduce((o,{ref:a,score:u,matchData:c})=>{let h=this.documents.get(a);if(typeof h!="undefined"){let{location:y,title:g,text:b,tags:m,parent:Q}=h,p=ce(n,Object.keys(c.metadata)),d=+!Q+ +Object.values(p).every(w=>w);o.push(Z(M({location:y,title:r(g),text:r(b)},m&&{tags:m.map(r)}),{score:u*(1+d),terms:p}))}return o},[]).sort((o,a)=>a.score-o.score).reduce((o,a)=>{let u=this.documents.get(a.location);if(typeof u!="undefined"){let c="parent"in u?u.parent.location:u.location;o.set(c,[...o.get(c)||[],a])}return o},new Map),s;if(this.options.suggestions){let o=this.index.query(a=>{for(let u of n)a.term(u.term,{fields:["title"],presence:lunr.Query.presence.REQUIRED,wildcard:lunr.Query.wildcard.TRAILING})});s=o.length?Object.keys(o[0].matchData.metadata):[]}return M({items:[...i.values()]},typeof s!="undefined"&&{suggestions:s})}catch(r){console.warn(`Invalid query: ${e} \u2013 see https://bit.ly/2s3ChXG`)}return{items:[]}}};var Y;function ke(t){return z(this,null,function*(){let e="../lunr";if(typeof parent!="undefined"&&"IFrameWorker"in parent){let n=document.querySelector("script[src]"),[i]=n.src.split("/worker");e=e.replace("..",i)}let r=[];for(let n of t.lang){switch(n){case"ja":r.push(`${e}/tinyseg.js`);break;case"hi":case"th":r.push(`${e}/wordcut.js`);break}n!=="en"&&r.push(`${e}/min/lunr.${n}.min.js`)}t.lang.length>1&&r.push(`${e}/min/lunr.multi.min.js`),r.length&&(yield importScripts(`${e}/min/lunr.stemmer.support.min.js`,...r))})}function Te(t){return z(this,null,function*(){switch(t.type){case 0:return yield ke(t.data.config),Y=new U(t.data),{type:1};case 2:return{type:3,data:Y?Y.search(t.data):{items:[]}};default:throw new TypeError("Invalid message type")}})}self.lunr=le.default;addEventListener("message",t=>z(void 0,null,function*(){postMessage(yield Te(t.data))}));})(); +//# sourceMappingURL=search.ecf98df9.min.js.map + diff --git a/assets/javascripts/workers/search.ecf98df9.min.js.map b/assets/javascripts/workers/search.ecf98df9.min.js.map new file mode 100644 index 000000000..eada3e644 --- /dev/null +++ b/assets/javascripts/workers/search.ecf98df9.min.js.map @@ -0,0 +1,8 @@ +{ + "version": 3, + "sources": ["node_modules/lunr/lunr.js", "node_modules/escape-html/index.js", "src/assets/javascripts/integrations/search/worker/main/index.ts", "src/assets/javascripts/polyfills/index.ts", "src/assets/javascripts/integrations/search/document/index.ts", "src/assets/javascripts/integrations/search/highlighter/index.ts", "src/assets/javascripts/integrations/search/query/_/index.ts", "src/assets/javascripts/integrations/search/_/index.ts"], + "sourceRoot": "../../../..", + "sourcesContent": ["/**\n * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9\n * Copyright (C) 2020 Oliver Nightingale\n * @license MIT\n */\n\n;(function(){\n\n/**\n * A convenience function for configuring and constructing\n * a new lunr Index.\n *\n * A lunr.Builder instance is created and the pipeline setup\n * with a trimmer, stop word filter and stemmer.\n *\n * This builder object is yielded to the configuration function\n * that is passed as a parameter, allowing the list of fields\n * and other builder parameters to be customised.\n *\n * All documents _must_ be added within the passed config function.\n *\n * @example\n * var idx = lunr(function () {\n * this.field('title')\n * this.field('body')\n * this.ref('id')\n *\n * documents.forEach(function (doc) {\n * this.add(doc)\n * }, this)\n * })\n *\n * @see {@link lunr.Builder}\n * @see {@link lunr.Pipeline}\n * @see {@link lunr.trimmer}\n * @see {@link lunr.stopWordFilter}\n * @see {@link lunr.stemmer}\n * @namespace {function} lunr\n */\nvar lunr = function (config) {\n var builder = new lunr.Builder\n\n builder.pipeline.add(\n lunr.trimmer,\n lunr.stopWordFilter,\n lunr.stemmer\n )\n\n builder.searchPipeline.add(\n lunr.stemmer\n )\n\n config.call(builder, builder)\n return builder.build()\n}\n\nlunr.version = \"2.3.9\"\n/*!\n * lunr.utils\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * A namespace containing utils for the rest of the lunr library\n * @namespace lunr.utils\n */\nlunr.utils = {}\n\n/**\n * Print a warning message to the console.\n *\n * @param {String} message The message to be printed.\n * @memberOf lunr.utils\n * @function\n */\nlunr.utils.warn = (function (global) {\n /* eslint-disable no-console */\n return function (message) {\n if (global.console && console.warn) {\n console.warn(message)\n }\n }\n /* eslint-enable no-console */\n})(this)\n\n/**\n * Convert an object to a string.\n *\n * In the case of `null` and `undefined` the function returns\n * the empty string, in all other cases the result of calling\n * `toString` on the passed object is returned.\n *\n * @param {Any} obj The object to convert to a string.\n * @return {String} string representation of the passed object.\n * @memberOf lunr.utils\n */\nlunr.utils.asString = function (obj) {\n if (obj === void 0 || obj === null) {\n return \"\"\n } else {\n return obj.toString()\n }\n}\n\n/**\n * Clones an object.\n *\n * Will create a copy of an existing object such that any mutations\n * on the copy cannot affect the original.\n *\n * Only shallow objects are supported, passing a nested object to this\n * function will cause a TypeError.\n *\n * Objects with primitives, and arrays of primitives are supported.\n *\n * @param {Object} obj The object to clone.\n * @return {Object} a clone of the passed object.\n * @throws {TypeError} when a nested object is passed.\n * @memberOf Utils\n */\nlunr.utils.clone = function (obj) {\n if (obj === null || obj === undefined) {\n return obj\n }\n\n var clone = Object.create(null),\n keys = Object.keys(obj)\n\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i],\n val = obj[key]\n\n if (Array.isArray(val)) {\n clone[key] = val.slice()\n continue\n }\n\n if (typeof val === 'string' ||\n typeof val === 'number' ||\n typeof val === 'boolean') {\n clone[key] = val\n continue\n }\n\n throw new TypeError(\"clone is not deep and does not support nested objects\")\n }\n\n return clone\n}\nlunr.FieldRef = function (docRef, fieldName, stringValue) {\n this.docRef = docRef\n this.fieldName = fieldName\n this._stringValue = stringValue\n}\n\nlunr.FieldRef.joiner = \"/\"\n\nlunr.FieldRef.fromString = function (s) {\n var n = s.indexOf(lunr.FieldRef.joiner)\n\n if (n === -1) {\n throw \"malformed field ref string\"\n }\n\n var fieldRef = s.slice(0, n),\n docRef = s.slice(n + 1)\n\n return new lunr.FieldRef (docRef, fieldRef, s)\n}\n\nlunr.FieldRef.prototype.toString = function () {\n if (this._stringValue == undefined) {\n this._stringValue = this.fieldName + lunr.FieldRef.joiner + this.docRef\n }\n\n return this._stringValue\n}\n/*!\n * lunr.Set\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * A lunr set.\n *\n * @constructor\n */\nlunr.Set = function (elements) {\n this.elements = Object.create(null)\n\n if (elements) {\n this.length = elements.length\n\n for (var i = 0; i < this.length; i++) {\n this.elements[elements[i]] = true\n }\n } else {\n this.length = 0\n }\n}\n\n/**\n * A complete set that contains all elements.\n *\n * @static\n * @readonly\n * @type {lunr.Set}\n */\nlunr.Set.complete = {\n intersect: function (other) {\n return other\n },\n\n union: function () {\n return this\n },\n\n contains: function () {\n return true\n }\n}\n\n/**\n * An empty set that contains no elements.\n *\n * @static\n * @readonly\n * @type {lunr.Set}\n */\nlunr.Set.empty = {\n intersect: function () {\n return this\n },\n\n union: function (other) {\n return other\n },\n\n contains: function () {\n return false\n }\n}\n\n/**\n * Returns true if this set contains the specified object.\n *\n * @param {object} object - Object whose presence in this set is to be tested.\n * @returns {boolean} - True if this set contains the specified object.\n */\nlunr.Set.prototype.contains = function (object) {\n return !!this.elements[object]\n}\n\n/**\n * Returns a new set containing only the elements that are present in both\n * this set and the specified set.\n *\n * @param {lunr.Set} other - set to intersect with this set.\n * @returns {lunr.Set} a new set that is the intersection of this and the specified set.\n */\n\nlunr.Set.prototype.intersect = function (other) {\n var a, b, elements, intersection = []\n\n if (other === lunr.Set.complete) {\n return this\n }\n\n if (other === lunr.Set.empty) {\n return other\n }\n\n if (this.length < other.length) {\n a = this\n b = other\n } else {\n a = other\n b = this\n }\n\n elements = Object.keys(a.elements)\n\n for (var i = 0; i < elements.length; i++) {\n var element = elements[i]\n if (element in b.elements) {\n intersection.push(element)\n }\n }\n\n return new lunr.Set (intersection)\n}\n\n/**\n * Returns a new set combining the elements of this and the specified set.\n *\n * @param {lunr.Set} other - set to union with this set.\n * @return {lunr.Set} a new set that is the union of this and the specified set.\n */\n\nlunr.Set.prototype.union = function (other) {\n if (other === lunr.Set.complete) {\n return lunr.Set.complete\n }\n\n if (other === lunr.Set.empty) {\n return this\n }\n\n return new lunr.Set(Object.keys(this.elements).concat(Object.keys(other.elements)))\n}\n/**\n * A function to calculate the inverse document frequency for\n * a posting. This is shared between the builder and the index\n *\n * @private\n * @param {object} posting - The posting for a given term\n * @param {number} documentCount - The total number of documents.\n */\nlunr.idf = function (posting, documentCount) {\n var documentsWithTerm = 0\n\n for (var fieldName in posting) {\n if (fieldName == '_index') continue // Ignore the term index, its not a field\n documentsWithTerm += Object.keys(posting[fieldName]).length\n }\n\n var x = (documentCount - documentsWithTerm + 0.5) / (documentsWithTerm + 0.5)\n\n return Math.log(1 + Math.abs(x))\n}\n\n/**\n * A token wraps a string representation of a token\n * as it is passed through the text processing pipeline.\n *\n * @constructor\n * @param {string} [str=''] - The string token being wrapped.\n * @param {object} [metadata={}] - Metadata associated with this token.\n */\nlunr.Token = function (str, metadata) {\n this.str = str || \"\"\n this.metadata = metadata || {}\n}\n\n/**\n * Returns the token string that is being wrapped by this object.\n *\n * @returns {string}\n */\nlunr.Token.prototype.toString = function () {\n return this.str\n}\n\n/**\n * A token update function is used when updating or optionally\n * when cloning a token.\n *\n * @callback lunr.Token~updateFunction\n * @param {string} str - The string representation of the token.\n * @param {Object} metadata - All metadata associated with this token.\n */\n\n/**\n * Applies the given function to the wrapped string token.\n *\n * @example\n * token.update(function (str, metadata) {\n * return str.toUpperCase()\n * })\n *\n * @param {lunr.Token~updateFunction} fn - A function to apply to the token string.\n * @returns {lunr.Token}\n */\nlunr.Token.prototype.update = function (fn) {\n this.str = fn(this.str, this.metadata)\n return this\n}\n\n/**\n * Creates a clone of this token. Optionally a function can be\n * applied to the cloned token.\n *\n * @param {lunr.Token~updateFunction} [fn] - An optional function to apply to the cloned token.\n * @returns {lunr.Token}\n */\nlunr.Token.prototype.clone = function (fn) {\n fn = fn || function (s) { return s }\n return new lunr.Token (fn(this.str, this.metadata), this.metadata)\n}\n/*!\n * lunr.tokenizer\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * A function for splitting a string into tokens ready to be inserted into\n * the search index. Uses `lunr.tokenizer.separator` to split strings, change\n * the value of this property to change how strings are split into tokens.\n *\n * This tokenizer will convert its parameter to a string by calling `toString` and\n * then will split this string on the character in `lunr.tokenizer.separator`.\n * Arrays will have their elements converted to strings and wrapped in a lunr.Token.\n *\n * Optional metadata can be passed to the tokenizer, this metadata will be cloned and\n * added as metadata to every token that is created from the object to be tokenized.\n *\n * @static\n * @param {?(string|object|object[])} obj - The object to convert into tokens\n * @param {?object} metadata - Optional metadata to associate with every token\n * @returns {lunr.Token[]}\n * @see {@link lunr.Pipeline}\n */\nlunr.tokenizer = function (obj, metadata) {\n if (obj == null || obj == undefined) {\n return []\n }\n\n if (Array.isArray(obj)) {\n return obj.map(function (t) {\n return new lunr.Token(\n lunr.utils.asString(t).toLowerCase(),\n lunr.utils.clone(metadata)\n )\n })\n }\n\n var str = obj.toString().toLowerCase(),\n len = str.length,\n tokens = []\n\n for (var sliceEnd = 0, sliceStart = 0; sliceEnd <= len; sliceEnd++) {\n var char = str.charAt(sliceEnd),\n sliceLength = sliceEnd - sliceStart\n\n if ((char.match(lunr.tokenizer.separator) || sliceEnd == len)) {\n\n if (sliceLength > 0) {\n var tokenMetadata = lunr.utils.clone(metadata) || {}\n tokenMetadata[\"position\"] = [sliceStart, sliceLength]\n tokenMetadata[\"index\"] = tokens.length\n\n tokens.push(\n new lunr.Token (\n str.slice(sliceStart, sliceEnd),\n tokenMetadata\n )\n )\n }\n\n sliceStart = sliceEnd + 1\n }\n\n }\n\n return tokens\n}\n\n/**\n * The separator used to split a string into tokens. Override this property to change the behaviour of\n * `lunr.tokenizer` behaviour when tokenizing strings. By default this splits on whitespace and hyphens.\n *\n * @static\n * @see lunr.tokenizer\n */\nlunr.tokenizer.separator = /[\\s\\-]+/\n/*!\n * lunr.Pipeline\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * lunr.Pipelines maintain an ordered list of functions to be applied to all\n * tokens in documents entering the search index and queries being ran against\n * the index.\n *\n * An instance of lunr.Index created with the lunr shortcut will contain a\n * pipeline with a stop word filter and an English language stemmer. Extra\n * functions can be added before or after either of these functions or these\n * default functions can be removed.\n *\n * When run the pipeline will call each function in turn, passing a token, the\n * index of that token in the original list of all tokens and finally a list of\n * all the original tokens.\n *\n * The output of functions in the pipeline will be passed to the next function\n * in the pipeline. To exclude a token from entering the index the function\n * should return undefined, the rest of the pipeline will not be called with\n * this token.\n *\n * For serialisation of pipelines to work, all functions used in an instance of\n * a pipeline should be registered with lunr.Pipeline. Registered functions can\n * then be loaded. If trying to load a serialised pipeline that uses functions\n * that are not registered an error will be thrown.\n *\n * If not planning on serialising the pipeline then registering pipeline functions\n * is not necessary.\n *\n * @constructor\n */\nlunr.Pipeline = function () {\n this._stack = []\n}\n\nlunr.Pipeline.registeredFunctions = Object.create(null)\n\n/**\n * A pipeline function maps lunr.Token to lunr.Token. A lunr.Token contains the token\n * string as well as all known metadata. A pipeline function can mutate the token string\n * or mutate (or add) metadata for a given token.\n *\n * A pipeline function can indicate that the passed token should be discarded by returning\n * null, undefined or an empty string. This token will not be passed to any downstream pipeline\n * functions and will not be added to the index.\n *\n * Multiple tokens can be returned by returning an array of tokens. Each token will be passed\n * to any downstream pipeline functions and all will returned tokens will be added to the index.\n *\n * Any number of pipeline functions may be chained together using a lunr.Pipeline.\n *\n * @interface lunr.PipelineFunction\n * @param {lunr.Token} token - A token from the document being processed.\n * @param {number} i - The index of this token in the complete list of tokens for this document/field.\n * @param {lunr.Token[]} tokens - All tokens for this document/field.\n * @returns {(?lunr.Token|lunr.Token[])}\n */\n\n/**\n * Register a function with the pipeline.\n *\n * Functions that are used in the pipeline should be registered if the pipeline\n * needs to be serialised, or a serialised pipeline needs to be loaded.\n *\n * Registering a function does not add it to a pipeline, functions must still be\n * added to instances of the pipeline for them to be used when running a pipeline.\n *\n * @param {lunr.PipelineFunction} fn - The function to check for.\n * @param {String} label - The label to register this function with\n */\nlunr.Pipeline.registerFunction = function (fn, label) {\n if (label in this.registeredFunctions) {\n lunr.utils.warn('Overwriting existing registered function: ' + label)\n }\n\n fn.label = label\n lunr.Pipeline.registeredFunctions[fn.label] = fn\n}\n\n/**\n * Warns if the function is not registered as a Pipeline function.\n *\n * @param {lunr.PipelineFunction} fn - The function to check for.\n * @private\n */\nlunr.Pipeline.warnIfFunctionNotRegistered = function (fn) {\n var isRegistered = fn.label && (fn.label in this.registeredFunctions)\n\n if (!isRegistered) {\n lunr.utils.warn('Function is not registered with pipeline. This may cause problems when serialising the index.\\n', fn)\n }\n}\n\n/**\n * Loads a previously serialised pipeline.\n *\n * All functions to be loaded must already be registered with lunr.Pipeline.\n * If any function from the serialised data has not been registered then an\n * error will be thrown.\n *\n * @param {Object} serialised - The serialised pipeline to load.\n * @returns {lunr.Pipeline}\n */\nlunr.Pipeline.load = function (serialised) {\n var pipeline = new lunr.Pipeline\n\n serialised.forEach(function (fnName) {\n var fn = lunr.Pipeline.registeredFunctions[fnName]\n\n if (fn) {\n pipeline.add(fn)\n } else {\n throw new Error('Cannot load unregistered function: ' + fnName)\n }\n })\n\n return pipeline\n}\n\n/**\n * Adds new functions to the end of the pipeline.\n *\n * Logs a warning if the function has not been registered.\n *\n * @param {lunr.PipelineFunction[]} functions - Any number of functions to add to the pipeline.\n */\nlunr.Pipeline.prototype.add = function () {\n var fns = Array.prototype.slice.call(arguments)\n\n fns.forEach(function (fn) {\n lunr.Pipeline.warnIfFunctionNotRegistered(fn)\n this._stack.push(fn)\n }, this)\n}\n\n/**\n * Adds a single function after a function that already exists in the\n * pipeline.\n *\n * Logs a warning if the function has not been registered.\n *\n * @param {lunr.PipelineFunction} existingFn - A function that already exists in the pipeline.\n * @param {lunr.PipelineFunction} newFn - The new function to add to the pipeline.\n */\nlunr.Pipeline.prototype.after = function (existingFn, newFn) {\n lunr.Pipeline.warnIfFunctionNotRegistered(newFn)\n\n var pos = this._stack.indexOf(existingFn)\n if (pos == -1) {\n throw new Error('Cannot find existingFn')\n }\n\n pos = pos + 1\n this._stack.splice(pos, 0, newFn)\n}\n\n/**\n * Adds a single function before a function that already exists in the\n * pipeline.\n *\n * Logs a warning if the function has not been registered.\n *\n * @param {lunr.PipelineFunction} existingFn - A function that already exists in the pipeline.\n * @param {lunr.PipelineFunction} newFn - The new function to add to the pipeline.\n */\nlunr.Pipeline.prototype.before = function (existingFn, newFn) {\n lunr.Pipeline.warnIfFunctionNotRegistered(newFn)\n\n var pos = this._stack.indexOf(existingFn)\n if (pos == -1) {\n throw new Error('Cannot find existingFn')\n }\n\n this._stack.splice(pos, 0, newFn)\n}\n\n/**\n * Removes a function from the pipeline.\n *\n * @param {lunr.PipelineFunction} fn The function to remove from the pipeline.\n */\nlunr.Pipeline.prototype.remove = function (fn) {\n var pos = this._stack.indexOf(fn)\n if (pos == -1) {\n return\n }\n\n this._stack.splice(pos, 1)\n}\n\n/**\n * Runs the current list of functions that make up the pipeline against the\n * passed tokens.\n *\n * @param {Array} tokens The tokens to run through the pipeline.\n * @returns {Array}\n */\nlunr.Pipeline.prototype.run = function (tokens) {\n var stackLength = this._stack.length\n\n for (var i = 0; i < stackLength; i++) {\n var fn = this._stack[i]\n var memo = []\n\n for (var j = 0; j < tokens.length; j++) {\n var result = fn(tokens[j], j, tokens)\n\n if (result === null || result === void 0 || result === '') continue\n\n if (Array.isArray(result)) {\n for (var k = 0; k < result.length; k++) {\n memo.push(result[k])\n }\n } else {\n memo.push(result)\n }\n }\n\n tokens = memo\n }\n\n return tokens\n}\n\n/**\n * Convenience method for passing a string through a pipeline and getting\n * strings out. This method takes care of wrapping the passed string in a\n * token and mapping the resulting tokens back to strings.\n *\n * @param {string} str - The string to pass through the pipeline.\n * @param {?object} metadata - Optional metadata to associate with the token\n * passed to the pipeline.\n * @returns {string[]}\n */\nlunr.Pipeline.prototype.runString = function (str, metadata) {\n var token = new lunr.Token (str, metadata)\n\n return this.run([token]).map(function (t) {\n return t.toString()\n })\n}\n\n/**\n * Resets the pipeline by removing any existing processors.\n *\n */\nlunr.Pipeline.prototype.reset = function () {\n this._stack = []\n}\n\n/**\n * Returns a representation of the pipeline ready for serialisation.\n *\n * Logs a warning if the function has not been registered.\n *\n * @returns {Array}\n */\nlunr.Pipeline.prototype.toJSON = function () {\n return this._stack.map(function (fn) {\n lunr.Pipeline.warnIfFunctionNotRegistered(fn)\n\n return fn.label\n })\n}\n/*!\n * lunr.Vector\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * A vector is used to construct the vector space of documents and queries. These\n * vectors support operations to determine the similarity between two documents or\n * a document and a query.\n *\n * Normally no parameters are required for initializing a vector, but in the case of\n * loading a previously dumped vector the raw elements can be provided to the constructor.\n *\n * For performance reasons vectors are implemented with a flat array, where an elements\n * index is immediately followed by its value. E.g. [index, value, index, value]. This\n * allows the underlying array to be as sparse as possible and still offer decent\n * performance when being used for vector calculations.\n *\n * @constructor\n * @param {Number[]} [elements] - The flat list of element index and element value pairs.\n */\nlunr.Vector = function (elements) {\n this._magnitude = 0\n this.elements = elements || []\n}\n\n\n/**\n * Calculates the position within the vector to insert a given index.\n *\n * This is used internally by insert and upsert. If there are duplicate indexes then\n * the position is returned as if the value for that index were to be updated, but it\n * is the callers responsibility to check whether there is a duplicate at that index\n *\n * @param {Number} insertIdx - The index at which the element should be inserted.\n * @returns {Number}\n */\nlunr.Vector.prototype.positionForIndex = function (index) {\n // For an empty vector the tuple can be inserted at the beginning\n if (this.elements.length == 0) {\n return 0\n }\n\n var start = 0,\n end = this.elements.length / 2,\n sliceLength = end - start,\n pivotPoint = Math.floor(sliceLength / 2),\n pivotIndex = this.elements[pivotPoint * 2]\n\n while (sliceLength > 1) {\n if (pivotIndex < index) {\n start = pivotPoint\n }\n\n if (pivotIndex > index) {\n end = pivotPoint\n }\n\n if (pivotIndex == index) {\n break\n }\n\n sliceLength = end - start\n pivotPoint = start + Math.floor(sliceLength / 2)\n pivotIndex = this.elements[pivotPoint * 2]\n }\n\n if (pivotIndex == index) {\n return pivotPoint * 2\n }\n\n if (pivotIndex > index) {\n return pivotPoint * 2\n }\n\n if (pivotIndex < index) {\n return (pivotPoint + 1) * 2\n }\n}\n\n/**\n * Inserts an element at an index within the vector.\n *\n * Does not allow duplicates, will throw an error if there is already an entry\n * for this index.\n *\n * @param {Number} insertIdx - The index at which the element should be inserted.\n * @param {Number} val - The value to be inserted into the vector.\n */\nlunr.Vector.prototype.insert = function (insertIdx, val) {\n this.upsert(insertIdx, val, function () {\n throw \"duplicate index\"\n })\n}\n\n/**\n * Inserts or updates an existing index within the vector.\n *\n * @param {Number} insertIdx - The index at which the element should be inserted.\n * @param {Number} val - The value to be inserted into the vector.\n * @param {function} fn - A function that is called for updates, the existing value and the\n * requested value are passed as arguments\n */\nlunr.Vector.prototype.upsert = function (insertIdx, val, fn) {\n this._magnitude = 0\n var position = this.positionForIndex(insertIdx)\n\n if (this.elements[position] == insertIdx) {\n this.elements[position + 1] = fn(this.elements[position + 1], val)\n } else {\n this.elements.splice(position, 0, insertIdx, val)\n }\n}\n\n/**\n * Calculates the magnitude of this vector.\n *\n * @returns {Number}\n */\nlunr.Vector.prototype.magnitude = function () {\n if (this._magnitude) return this._magnitude\n\n var sumOfSquares = 0,\n elementsLength = this.elements.length\n\n for (var i = 1; i < elementsLength; i += 2) {\n var val = this.elements[i]\n sumOfSquares += val * val\n }\n\n return this._magnitude = Math.sqrt(sumOfSquares)\n}\n\n/**\n * Calculates the dot product of this vector and another vector.\n *\n * @param {lunr.Vector} otherVector - The vector to compute the dot product with.\n * @returns {Number}\n */\nlunr.Vector.prototype.dot = function (otherVector) {\n var dotProduct = 0,\n a = this.elements, b = otherVector.elements,\n aLen = a.length, bLen = b.length,\n aVal = 0, bVal = 0,\n i = 0, j = 0\n\n while (i < aLen && j < bLen) {\n aVal = a[i], bVal = b[j]\n if (aVal < bVal) {\n i += 2\n } else if (aVal > bVal) {\n j += 2\n } else if (aVal == bVal) {\n dotProduct += a[i + 1] * b[j + 1]\n i += 2\n j += 2\n }\n }\n\n return dotProduct\n}\n\n/**\n * Calculates the similarity between this vector and another vector.\n *\n * @param {lunr.Vector} otherVector - The other vector to calculate the\n * similarity with.\n * @returns {Number}\n */\nlunr.Vector.prototype.similarity = function (otherVector) {\n return this.dot(otherVector) / this.magnitude() || 0\n}\n\n/**\n * Converts the vector to an array of the elements within the vector.\n *\n * @returns {Number[]}\n */\nlunr.Vector.prototype.toArray = function () {\n var output = new Array (this.elements.length / 2)\n\n for (var i = 1, j = 0; i < this.elements.length; i += 2, j++) {\n output[j] = this.elements[i]\n }\n\n return output\n}\n\n/**\n * A JSON serializable representation of the vector.\n *\n * @returns {Number[]}\n */\nlunr.Vector.prototype.toJSON = function () {\n return this.elements\n}\n/* eslint-disable */\n/*!\n * lunr.stemmer\n * Copyright (C) 2020 Oliver Nightingale\n * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt\n */\n\n/**\n * lunr.stemmer is an english language stemmer, this is a JavaScript\n * implementation of the PorterStemmer taken from http://tartarus.org/~martin\n *\n * @static\n * @implements {lunr.PipelineFunction}\n * @param {lunr.Token} token - The string to stem\n * @returns {lunr.Token}\n * @see {@link lunr.Pipeline}\n * @function\n */\nlunr.stemmer = (function(){\n var step2list = {\n \"ational\" : \"ate\",\n \"tional\" : \"tion\",\n \"enci\" : \"ence\",\n \"anci\" : \"ance\",\n \"izer\" : \"ize\",\n \"bli\" : \"ble\",\n \"alli\" : \"al\",\n \"entli\" : \"ent\",\n \"eli\" : \"e\",\n \"ousli\" : \"ous\",\n \"ization\" : \"ize\",\n \"ation\" : \"ate\",\n \"ator\" : \"ate\",\n \"alism\" : \"al\",\n \"iveness\" : \"ive\",\n \"fulness\" : \"ful\",\n \"ousness\" : \"ous\",\n \"aliti\" : \"al\",\n \"iviti\" : \"ive\",\n \"biliti\" : \"ble\",\n \"logi\" : \"log\"\n },\n\n step3list = {\n \"icate\" : \"ic\",\n \"ative\" : \"\",\n \"alize\" : \"al\",\n \"iciti\" : \"ic\",\n \"ical\" : \"ic\",\n \"ful\" : \"\",\n \"ness\" : \"\"\n },\n\n c = \"[^aeiou]\", // consonant\n v = \"[aeiouy]\", // vowel\n C = c + \"[^aeiouy]*\", // consonant sequence\n V = v + \"[aeiou]*\", // vowel sequence\n\n mgr0 = \"^(\" + C + \")?\" + V + C, // [C]VC... is m>0\n meq1 = \"^(\" + C + \")?\" + V + C + \"(\" + V + \")?$\", // [C]VC[V] is m=1\n mgr1 = \"^(\" + C + \")?\" + V + C + V + C, // [C]VCVC... is m>1\n s_v = \"^(\" + C + \")?\" + v; // vowel in stem\n\n var re_mgr0 = new RegExp(mgr0);\n var re_mgr1 = new RegExp(mgr1);\n var re_meq1 = new RegExp(meq1);\n var re_s_v = new RegExp(s_v);\n\n var re_1a = /^(.+?)(ss|i)es$/;\n var re2_1a = /^(.+?)([^s])s$/;\n var re_1b = /^(.+?)eed$/;\n var re2_1b = /^(.+?)(ed|ing)$/;\n var re_1b_2 = /.$/;\n var re2_1b_2 = /(at|bl|iz)$/;\n var re3_1b_2 = new RegExp(\"([^aeiouylsz])\\\\1$\");\n var re4_1b_2 = new RegExp(\"^\" + C + v + \"[^aeiouwxy]$\");\n\n var re_1c = /^(.+?[^aeiou])y$/;\n var re_2 = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;\n\n var re_3 = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;\n\n var re_4 = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;\n var re2_4 = /^(.+?)(s|t)(ion)$/;\n\n var re_5 = /^(.+?)e$/;\n var re_5_1 = /ll$/;\n var re3_5 = new RegExp(\"^\" + C + v + \"[^aeiouwxy]$\");\n\n var porterStemmer = function porterStemmer(w) {\n var stem,\n suffix,\n firstch,\n re,\n re2,\n re3,\n re4;\n\n if (w.length < 3) { return w; }\n\n firstch = w.substr(0,1);\n if (firstch == \"y\") {\n w = firstch.toUpperCase() + w.substr(1);\n }\n\n // Step 1a\n re = re_1a\n re2 = re2_1a;\n\n if (re.test(w)) { w = w.replace(re,\"$1$2\"); }\n else if (re2.test(w)) { w = w.replace(re2,\"$1$2\"); }\n\n // Step 1b\n re = re_1b;\n re2 = re2_1b;\n if (re.test(w)) {\n var fp = re.exec(w);\n re = re_mgr0;\n if (re.test(fp[1])) {\n re = re_1b_2;\n w = w.replace(re,\"\");\n }\n } else if (re2.test(w)) {\n var fp = re2.exec(w);\n stem = fp[1];\n re2 = re_s_v;\n if (re2.test(stem)) {\n w = stem;\n re2 = re2_1b_2;\n re3 = re3_1b_2;\n re4 = re4_1b_2;\n if (re2.test(w)) { w = w + \"e\"; }\n else if (re3.test(w)) { re = re_1b_2; w = w.replace(re,\"\"); }\n else if (re4.test(w)) { w = w + \"e\"; }\n }\n }\n\n // Step 1c - replace suffix y or Y by i if preceded by a non-vowel which is not the first letter of the word (so cry -> cri, by -> by, say -> say)\n re = re_1c;\n if (re.test(w)) {\n var fp = re.exec(w);\n stem = fp[1];\n w = stem + \"i\";\n }\n\n // Step 2\n re = re_2;\n if (re.test(w)) {\n var fp = re.exec(w);\n stem = fp[1];\n suffix = fp[2];\n re = re_mgr0;\n if (re.test(stem)) {\n w = stem + step2list[suffix];\n }\n }\n\n // Step 3\n re = re_3;\n if (re.test(w)) {\n var fp = re.exec(w);\n stem = fp[1];\n suffix = fp[2];\n re = re_mgr0;\n if (re.test(stem)) {\n w = stem + step3list[suffix];\n }\n }\n\n // Step 4\n re = re_4;\n re2 = re2_4;\n if (re.test(w)) {\n var fp = re.exec(w);\n stem = fp[1];\n re = re_mgr1;\n if (re.test(stem)) {\n w = stem;\n }\n } else if (re2.test(w)) {\n var fp = re2.exec(w);\n stem = fp[1] + fp[2];\n re2 = re_mgr1;\n if (re2.test(stem)) {\n w = stem;\n }\n }\n\n // Step 5\n re = re_5;\n if (re.test(w)) {\n var fp = re.exec(w);\n stem = fp[1];\n re = re_mgr1;\n re2 = re_meq1;\n re3 = re3_5;\n if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) {\n w = stem;\n }\n }\n\n re = re_5_1;\n re2 = re_mgr1;\n if (re.test(w) && re2.test(w)) {\n re = re_1b_2;\n w = w.replace(re,\"\");\n }\n\n // and turn initial Y back to y\n\n if (firstch == \"y\") {\n w = firstch.toLowerCase() + w.substr(1);\n }\n\n return w;\n };\n\n return function (token) {\n return token.update(porterStemmer);\n }\n})();\n\nlunr.Pipeline.registerFunction(lunr.stemmer, 'stemmer')\n/*!\n * lunr.stopWordFilter\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * lunr.generateStopWordFilter builds a stopWordFilter function from the provided\n * list of stop words.\n *\n * The built in lunr.stopWordFilter is built using this generator and can be used\n * to generate custom stopWordFilters for applications or non English languages.\n *\n * @function\n * @param {Array} token The token to pass through the filter\n * @returns {lunr.PipelineFunction}\n * @see lunr.Pipeline\n * @see lunr.stopWordFilter\n */\nlunr.generateStopWordFilter = function (stopWords) {\n var words = stopWords.reduce(function (memo, stopWord) {\n memo[stopWord] = stopWord\n return memo\n }, {})\n\n return function (token) {\n if (token && words[token.toString()] !== token.toString()) return token\n }\n}\n\n/**\n * lunr.stopWordFilter is an English language stop word list filter, any words\n * contained in the list will not be passed through the filter.\n *\n * This is intended to be used in the Pipeline. If the token does not pass the\n * filter then undefined will be returned.\n *\n * @function\n * @implements {lunr.PipelineFunction}\n * @params {lunr.Token} token - A token to check for being a stop word.\n * @returns {lunr.Token}\n * @see {@link lunr.Pipeline}\n */\nlunr.stopWordFilter = lunr.generateStopWordFilter([\n 'a',\n 'able',\n 'about',\n 'across',\n 'after',\n 'all',\n 'almost',\n 'also',\n 'am',\n 'among',\n 'an',\n 'and',\n 'any',\n 'are',\n 'as',\n 'at',\n 'be',\n 'because',\n 'been',\n 'but',\n 'by',\n 'can',\n 'cannot',\n 'could',\n 'dear',\n 'did',\n 'do',\n 'does',\n 'either',\n 'else',\n 'ever',\n 'every',\n 'for',\n 'from',\n 'get',\n 'got',\n 'had',\n 'has',\n 'have',\n 'he',\n 'her',\n 'hers',\n 'him',\n 'his',\n 'how',\n 'however',\n 'i',\n 'if',\n 'in',\n 'into',\n 'is',\n 'it',\n 'its',\n 'just',\n 'least',\n 'let',\n 'like',\n 'likely',\n 'may',\n 'me',\n 'might',\n 'most',\n 'must',\n 'my',\n 'neither',\n 'no',\n 'nor',\n 'not',\n 'of',\n 'off',\n 'often',\n 'on',\n 'only',\n 'or',\n 'other',\n 'our',\n 'own',\n 'rather',\n 'said',\n 'say',\n 'says',\n 'she',\n 'should',\n 'since',\n 'so',\n 'some',\n 'than',\n 'that',\n 'the',\n 'their',\n 'them',\n 'then',\n 'there',\n 'these',\n 'they',\n 'this',\n 'tis',\n 'to',\n 'too',\n 'twas',\n 'us',\n 'wants',\n 'was',\n 'we',\n 'were',\n 'what',\n 'when',\n 'where',\n 'which',\n 'while',\n 'who',\n 'whom',\n 'why',\n 'will',\n 'with',\n 'would',\n 'yet',\n 'you',\n 'your'\n])\n\nlunr.Pipeline.registerFunction(lunr.stopWordFilter, 'stopWordFilter')\n/*!\n * lunr.trimmer\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * lunr.trimmer is a pipeline function for trimming non word\n * characters from the beginning and end of tokens before they\n * enter the index.\n *\n * This implementation may not work correctly for non latin\n * characters and should either be removed or adapted for use\n * with languages with non-latin characters.\n *\n * @static\n * @implements {lunr.PipelineFunction}\n * @param {lunr.Token} token The token to pass through the filter\n * @returns {lunr.Token}\n * @see lunr.Pipeline\n */\nlunr.trimmer = function (token) {\n return token.update(function (s) {\n return s.replace(/^\\W+/, '').replace(/\\W+$/, '')\n })\n}\n\nlunr.Pipeline.registerFunction(lunr.trimmer, 'trimmer')\n/*!\n * lunr.TokenSet\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * A token set is used to store the unique list of all tokens\n * within an index. Token sets are also used to represent an\n * incoming query to the index, this query token set and index\n * token set are then intersected to find which tokens to look\n * up in the inverted index.\n *\n * A token set can hold multiple tokens, as in the case of the\n * index token set, or it can hold a single token as in the\n * case of a simple query token set.\n *\n * Additionally token sets are used to perform wildcard matching.\n * Leading, contained and trailing wildcards are supported, and\n * from this edit distance matching can also be provided.\n *\n * Token sets are implemented as a minimal finite state automata,\n * where both common prefixes and suffixes are shared between tokens.\n * This helps to reduce the space used for storing the token set.\n *\n * @constructor\n */\nlunr.TokenSet = function () {\n this.final = false\n this.edges = {}\n this.id = lunr.TokenSet._nextId\n lunr.TokenSet._nextId += 1\n}\n\n/**\n * Keeps track of the next, auto increment, identifier to assign\n * to a new tokenSet.\n *\n * TokenSets require a unique identifier to be correctly minimised.\n *\n * @private\n */\nlunr.TokenSet._nextId = 1\n\n/**\n * Creates a TokenSet instance from the given sorted array of words.\n *\n * @param {String[]} arr - A sorted array of strings to create the set from.\n * @returns {lunr.TokenSet}\n * @throws Will throw an error if the input array is not sorted.\n */\nlunr.TokenSet.fromArray = function (arr) {\n var builder = new lunr.TokenSet.Builder\n\n for (var i = 0, len = arr.length; i < len; i++) {\n builder.insert(arr[i])\n }\n\n builder.finish()\n return builder.root\n}\n\n/**\n * Creates a token set from a query clause.\n *\n * @private\n * @param {Object} clause - A single clause from lunr.Query.\n * @param {string} clause.term - The query clause term.\n * @param {number} [clause.editDistance] - The optional edit distance for the term.\n * @returns {lunr.TokenSet}\n */\nlunr.TokenSet.fromClause = function (clause) {\n if ('editDistance' in clause) {\n return lunr.TokenSet.fromFuzzyString(clause.term, clause.editDistance)\n } else {\n return lunr.TokenSet.fromString(clause.term)\n }\n}\n\n/**\n * Creates a token set representing a single string with a specified\n * edit distance.\n *\n * Insertions, deletions, substitutions and transpositions are each\n * treated as an edit distance of 1.\n *\n * Increasing the allowed edit distance will have a dramatic impact\n * on the performance of both creating and intersecting these TokenSets.\n * It is advised to keep the edit distance less than 3.\n *\n * @param {string} str - The string to create the token set from.\n * @param {number} editDistance - The allowed edit distance to match.\n * @returns {lunr.Vector}\n */\nlunr.TokenSet.fromFuzzyString = function (str, editDistance) {\n var root = new lunr.TokenSet\n\n var stack = [{\n node: root,\n editsRemaining: editDistance,\n str: str\n }]\n\n while (stack.length) {\n var frame = stack.pop()\n\n // no edit\n if (frame.str.length > 0) {\n var char = frame.str.charAt(0),\n noEditNode\n\n if (char in frame.node.edges) {\n noEditNode = frame.node.edges[char]\n } else {\n noEditNode = new lunr.TokenSet\n frame.node.edges[char] = noEditNode\n }\n\n if (frame.str.length == 1) {\n noEditNode.final = true\n }\n\n stack.push({\n node: noEditNode,\n editsRemaining: frame.editsRemaining,\n str: frame.str.slice(1)\n })\n }\n\n if (frame.editsRemaining == 0) {\n continue\n }\n\n // insertion\n if (\"*\" in frame.node.edges) {\n var insertionNode = frame.node.edges[\"*\"]\n } else {\n var insertionNode = new lunr.TokenSet\n frame.node.edges[\"*\"] = insertionNode\n }\n\n if (frame.str.length == 0) {\n insertionNode.final = true\n }\n\n stack.push({\n node: insertionNode,\n editsRemaining: frame.editsRemaining - 1,\n str: frame.str\n })\n\n // deletion\n // can only do a deletion if we have enough edits remaining\n // and if there are characters left to delete in the string\n if (frame.str.length > 1) {\n stack.push({\n node: frame.node,\n editsRemaining: frame.editsRemaining - 1,\n str: frame.str.slice(1)\n })\n }\n\n // deletion\n // just removing the last character from the str\n if (frame.str.length == 1) {\n frame.node.final = true\n }\n\n // substitution\n // can only do a substitution if we have enough edits remaining\n // and if there are characters left to substitute\n if (frame.str.length >= 1) {\n if (\"*\" in frame.node.edges) {\n var substitutionNode = frame.node.edges[\"*\"]\n } else {\n var substitutionNode = new lunr.TokenSet\n frame.node.edges[\"*\"] = substitutionNode\n }\n\n if (frame.str.length == 1) {\n substitutionNode.final = true\n }\n\n stack.push({\n node: substitutionNode,\n editsRemaining: frame.editsRemaining - 1,\n str: frame.str.slice(1)\n })\n }\n\n // transposition\n // can only do a transposition if there are edits remaining\n // and there are enough characters to transpose\n if (frame.str.length > 1) {\n var charA = frame.str.charAt(0),\n charB = frame.str.charAt(1),\n transposeNode\n\n if (charB in frame.node.edges) {\n transposeNode = frame.node.edges[charB]\n } else {\n transposeNode = new lunr.TokenSet\n frame.node.edges[charB] = transposeNode\n }\n\n if (frame.str.length == 1) {\n transposeNode.final = true\n }\n\n stack.push({\n node: transposeNode,\n editsRemaining: frame.editsRemaining - 1,\n str: charA + frame.str.slice(2)\n })\n }\n }\n\n return root\n}\n\n/**\n * Creates a TokenSet from a string.\n *\n * The string may contain one or more wildcard characters (*)\n * that will allow wildcard matching when intersecting with\n * another TokenSet.\n *\n * @param {string} str - The string to create a TokenSet from.\n * @returns {lunr.TokenSet}\n */\nlunr.TokenSet.fromString = function (str) {\n var node = new lunr.TokenSet,\n root = node\n\n /*\n * Iterates through all characters within the passed string\n * appending a node for each character.\n *\n * When a wildcard character is found then a self\n * referencing edge is introduced to continually match\n * any number of any characters.\n */\n for (var i = 0, len = str.length; i < len; i++) {\n var char = str[i],\n final = (i == len - 1)\n\n if (char == \"*\") {\n node.edges[char] = node\n node.final = final\n\n } else {\n var next = new lunr.TokenSet\n next.final = final\n\n node.edges[char] = next\n node = next\n }\n }\n\n return root\n}\n\n/**\n * Converts this TokenSet into an array of strings\n * contained within the TokenSet.\n *\n * This is not intended to be used on a TokenSet that\n * contains wildcards, in these cases the results are\n * undefined and are likely to cause an infinite loop.\n *\n * @returns {string[]}\n */\nlunr.TokenSet.prototype.toArray = function () {\n var words = []\n\n var stack = [{\n prefix: \"\",\n node: this\n }]\n\n while (stack.length) {\n var frame = stack.pop(),\n edges = Object.keys(frame.node.edges),\n len = edges.length\n\n if (frame.node.final) {\n /* In Safari, at this point the prefix is sometimes corrupted, see:\n * https://github.com/olivernn/lunr.js/issues/279 Calling any\n * String.prototype method forces Safari to \"cast\" this string to what\n * it's supposed to be, fixing the bug. */\n frame.prefix.charAt(0)\n words.push(frame.prefix)\n }\n\n for (var i = 0; i < len; i++) {\n var edge = edges[i]\n\n stack.push({\n prefix: frame.prefix.concat(edge),\n node: frame.node.edges[edge]\n })\n }\n }\n\n return words\n}\n\n/**\n * Generates a string representation of a TokenSet.\n *\n * This is intended to allow TokenSets to be used as keys\n * in objects, largely to aid the construction and minimisation\n * of a TokenSet. As such it is not designed to be a human\n * friendly representation of the TokenSet.\n *\n * @returns {string}\n */\nlunr.TokenSet.prototype.toString = function () {\n // NOTE: Using Object.keys here as this.edges is very likely\n // to enter 'hash-mode' with many keys being added\n //\n // avoiding a for-in loop here as it leads to the function\n // being de-optimised (at least in V8). From some simple\n // benchmarks the performance is comparable, but allowing\n // V8 to optimize may mean easy performance wins in the future.\n\n if (this._str) {\n return this._str\n }\n\n var str = this.final ? '1' : '0',\n labels = Object.keys(this.edges).sort(),\n len = labels.length\n\n for (var i = 0; i < len; i++) {\n var label = labels[i],\n node = this.edges[label]\n\n str = str + label + node.id\n }\n\n return str\n}\n\n/**\n * Returns a new TokenSet that is the intersection of\n * this TokenSet and the passed TokenSet.\n *\n * This intersection will take into account any wildcards\n * contained within the TokenSet.\n *\n * @param {lunr.TokenSet} b - An other TokenSet to intersect with.\n * @returns {lunr.TokenSet}\n */\nlunr.TokenSet.prototype.intersect = function (b) {\n var output = new lunr.TokenSet,\n frame = undefined\n\n var stack = [{\n qNode: b,\n output: output,\n node: this\n }]\n\n while (stack.length) {\n frame = stack.pop()\n\n // NOTE: As with the #toString method, we are using\n // Object.keys and a for loop instead of a for-in loop\n // as both of these objects enter 'hash' mode, causing\n // the function to be de-optimised in V8\n var qEdges = Object.keys(frame.qNode.edges),\n qLen = qEdges.length,\n nEdges = Object.keys(frame.node.edges),\n nLen = nEdges.length\n\n for (var q = 0; q < qLen; q++) {\n var qEdge = qEdges[q]\n\n for (var n = 0; n < nLen; n++) {\n var nEdge = nEdges[n]\n\n if (nEdge == qEdge || qEdge == '*') {\n var node = frame.node.edges[nEdge],\n qNode = frame.qNode.edges[qEdge],\n final = node.final && qNode.final,\n next = undefined\n\n if (nEdge in frame.output.edges) {\n // an edge already exists for this character\n // no need to create a new node, just set the finality\n // bit unless this node is already final\n next = frame.output.edges[nEdge]\n next.final = next.final || final\n\n } else {\n // no edge exists yet, must create one\n // set the finality bit and insert it\n // into the output\n next = new lunr.TokenSet\n next.final = final\n frame.output.edges[nEdge] = next\n }\n\n stack.push({\n qNode: qNode,\n output: next,\n node: node\n })\n }\n }\n }\n }\n\n return output\n}\nlunr.TokenSet.Builder = function () {\n this.previousWord = \"\"\n this.root = new lunr.TokenSet\n this.uncheckedNodes = []\n this.minimizedNodes = {}\n}\n\nlunr.TokenSet.Builder.prototype.insert = function (word) {\n var node,\n commonPrefix = 0\n\n if (word < this.previousWord) {\n throw new Error (\"Out of order word insertion\")\n }\n\n for (var i = 0; i < word.length && i < this.previousWord.length; i++) {\n if (word[i] != this.previousWord[i]) break\n commonPrefix++\n }\n\n this.minimize(commonPrefix)\n\n if (this.uncheckedNodes.length == 0) {\n node = this.root\n } else {\n node = this.uncheckedNodes[this.uncheckedNodes.length - 1].child\n }\n\n for (var i = commonPrefix; i < word.length; i++) {\n var nextNode = new lunr.TokenSet,\n char = word[i]\n\n node.edges[char] = nextNode\n\n this.uncheckedNodes.push({\n parent: node,\n char: char,\n child: nextNode\n })\n\n node = nextNode\n }\n\n node.final = true\n this.previousWord = word\n}\n\nlunr.TokenSet.Builder.prototype.finish = function () {\n this.minimize(0)\n}\n\nlunr.TokenSet.Builder.prototype.minimize = function (downTo) {\n for (var i = this.uncheckedNodes.length - 1; i >= downTo; i--) {\n var node = this.uncheckedNodes[i],\n childKey = node.child.toString()\n\n if (childKey in this.minimizedNodes) {\n node.parent.edges[node.char] = this.minimizedNodes[childKey]\n } else {\n // Cache the key for this node since\n // we know it can't change anymore\n node.child._str = childKey\n\n this.minimizedNodes[childKey] = node.child\n }\n\n this.uncheckedNodes.pop()\n }\n}\n/*!\n * lunr.Index\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * An index contains the built index of all documents and provides a query interface\n * to the index.\n *\n * Usually instances of lunr.Index will not be created using this constructor, instead\n * lunr.Builder should be used to construct new indexes, or lunr.Index.load should be\n * used to load previously built and serialized indexes.\n *\n * @constructor\n * @param {Object} attrs - The attributes of the built search index.\n * @param {Object} attrs.invertedIndex - An index of term/field to document reference.\n * @param {Object} attrs.fieldVectors - Field vectors\n * @param {lunr.TokenSet} attrs.tokenSet - An set of all corpus tokens.\n * @param {string[]} attrs.fields - The names of indexed document fields.\n * @param {lunr.Pipeline} attrs.pipeline - The pipeline to use for search terms.\n */\nlunr.Index = function (attrs) {\n this.invertedIndex = attrs.invertedIndex\n this.fieldVectors = attrs.fieldVectors\n this.tokenSet = attrs.tokenSet\n this.fields = attrs.fields\n this.pipeline = attrs.pipeline\n}\n\n/**\n * A result contains details of a document matching a search query.\n * @typedef {Object} lunr.Index~Result\n * @property {string} ref - The reference of the document this result represents.\n * @property {number} score - A number between 0 and 1 representing how similar this document is to the query.\n * @property {lunr.MatchData} matchData - Contains metadata about this match including which term(s) caused the match.\n */\n\n/**\n * Although lunr provides the ability to create queries using lunr.Query, it also provides a simple\n * query language which itself is parsed into an instance of lunr.Query.\n *\n * For programmatically building queries it is advised to directly use lunr.Query, the query language\n * is best used for human entered text rather than program generated text.\n *\n * At its simplest queries can just be a single term, e.g. `hello`, multiple terms are also supported\n * and will be combined with OR, e.g `hello world` will match documents that contain either 'hello'\n * or 'world', though those that contain both will rank higher in the results.\n *\n * Wildcards can be included in terms to match one or more unspecified characters, these wildcards can\n * be inserted anywhere within the term, and more than one wildcard can exist in a single term. Adding\n * wildcards will increase the number of documents that will be found but can also have a negative\n * impact on query performance, especially with wildcards at the beginning of a term.\n *\n * Terms can be restricted to specific fields, e.g. `title:hello`, only documents with the term\n * hello in the title field will match this query. Using a field not present in the index will lead\n * to an error being thrown.\n *\n * Modifiers can also be added to terms, lunr supports edit distance and boost modifiers on terms. A term\n * boost will make documents matching that term score higher, e.g. `foo^5`. Edit distance is also supported\n * to provide fuzzy matching, e.g. 'hello~2' will match documents with hello with an edit distance of 2.\n * Avoid large values for edit distance to improve query performance.\n *\n * Each term also supports a presence modifier. By default a term's presence in document is optional, however\n * this can be changed to either required or prohibited. For a term's presence to be required in a document the\n * term should be prefixed with a '+', e.g. `+foo bar` is a search for documents that must contain 'foo' and\n * optionally contain 'bar'. Conversely a leading '-' sets the terms presence to prohibited, i.e. it must not\n * appear in a document, e.g. `-foo bar` is a search for documents that do not contain 'foo' but may contain 'bar'.\n *\n * To escape special characters the backslash character '\\' can be used, this allows searches to include\n * characters that would normally be considered modifiers, e.g. `foo\\~2` will search for a term \"foo~2\" instead\n * of attempting to apply a boost of 2 to the search term \"foo\".\n *\n * @typedef {string} lunr.Index~QueryString\n * @example Simple single term query\n * hello\n * @example Multiple term query\n * hello world\n * @example term scoped to a field\n * title:hello\n * @example term with a boost of 10\n * hello^10\n * @example term with an edit distance of 2\n * hello~2\n * @example terms with presence modifiers\n * -foo +bar baz\n */\n\n/**\n * Performs a search against the index using lunr query syntax.\n *\n * Results will be returned sorted by their score, the most relevant results\n * will be returned first. For details on how the score is calculated, please see\n * the {@link https://lunrjs.com/guides/searching.html#scoring|guide}.\n *\n * For more programmatic querying use lunr.Index#query.\n *\n * @param {lunr.Index~QueryString} queryString - A string containing a lunr query.\n * @throws {lunr.QueryParseError} If the passed query string cannot be parsed.\n * @returns {lunr.Index~Result[]}\n */\nlunr.Index.prototype.search = function (queryString) {\n return this.query(function (query) {\n var parser = new lunr.QueryParser(queryString, query)\n parser.parse()\n })\n}\n\n/**\n * A query builder callback provides a query object to be used to express\n * the query to perform on the index.\n *\n * @callback lunr.Index~queryBuilder\n * @param {lunr.Query} query - The query object to build up.\n * @this lunr.Query\n */\n\n/**\n * Performs a query against the index using the yielded lunr.Query object.\n *\n * If performing programmatic queries against the index, this method is preferred\n * over lunr.Index#search so as to avoid the additional query parsing overhead.\n *\n * A query object is yielded to the supplied function which should be used to\n * express the query to be run against the index.\n *\n * Note that although this function takes a callback parameter it is _not_ an\n * asynchronous operation, the callback is just yielded a query object to be\n * customized.\n *\n * @param {lunr.Index~queryBuilder} fn - A function that is used to build the query.\n * @returns {lunr.Index~Result[]}\n */\nlunr.Index.prototype.query = function (fn) {\n // for each query clause\n // * process terms\n // * expand terms from token set\n // * find matching documents and metadata\n // * get document vectors\n // * score documents\n\n var query = new lunr.Query(this.fields),\n matchingFields = Object.create(null),\n queryVectors = Object.create(null),\n termFieldCache = Object.create(null),\n requiredMatches = Object.create(null),\n prohibitedMatches = Object.create(null)\n\n /*\n * To support field level boosts a query vector is created per\n * field. An empty vector is eagerly created to support negated\n * queries.\n */\n for (var i = 0; i < this.fields.length; i++) {\n queryVectors[this.fields[i]] = new lunr.Vector\n }\n\n fn.call(query, query)\n\n for (var i = 0; i < query.clauses.length; i++) {\n /*\n * Unless the pipeline has been disabled for this term, which is\n * the case for terms with wildcards, we need to pass the clause\n * term through the search pipeline. A pipeline returns an array\n * of processed terms. Pipeline functions may expand the passed\n * term, which means we may end up performing multiple index lookups\n * for a single query term.\n */\n var clause = query.clauses[i],\n terms = null,\n clauseMatches = lunr.Set.empty\n\n if (clause.usePipeline) {\n terms = this.pipeline.runString(clause.term, {\n fields: clause.fields\n })\n } else {\n terms = [clause.term]\n }\n\n for (var m = 0; m < terms.length; m++) {\n var term = terms[m]\n\n /*\n * Each term returned from the pipeline needs to use the same query\n * clause object, e.g. the same boost and or edit distance. The\n * simplest way to do this is to re-use the clause object but mutate\n * its term property.\n */\n clause.term = term\n\n /*\n * From the term in the clause we create a token set which will then\n * be used to intersect the indexes token set to get a list of terms\n * to lookup in the inverted index\n */\n var termTokenSet = lunr.TokenSet.fromClause(clause),\n expandedTerms = this.tokenSet.intersect(termTokenSet).toArray()\n\n /*\n * If a term marked as required does not exist in the tokenSet it is\n * impossible for the search to return any matches. We set all the field\n * scoped required matches set to empty and stop examining any further\n * clauses.\n */\n if (expandedTerms.length === 0 && clause.presence === lunr.Query.presence.REQUIRED) {\n for (var k = 0; k < clause.fields.length; k++) {\n var field = clause.fields[k]\n requiredMatches[field] = lunr.Set.empty\n }\n\n break\n }\n\n for (var j = 0; j < expandedTerms.length; j++) {\n /*\n * For each term get the posting and termIndex, this is required for\n * building the query vector.\n */\n var expandedTerm = expandedTerms[j],\n posting = this.invertedIndex[expandedTerm],\n termIndex = posting._index\n\n for (var k = 0; k < clause.fields.length; k++) {\n /*\n * For each field that this query term is scoped by (by default\n * all fields are in scope) we need to get all the document refs\n * that have this term in that field.\n *\n * The posting is the entry in the invertedIndex for the matching\n * term from above.\n */\n var field = clause.fields[k],\n fieldPosting = posting[field],\n matchingDocumentRefs = Object.keys(fieldPosting),\n termField = expandedTerm + \"/\" + field,\n matchingDocumentsSet = new lunr.Set(matchingDocumentRefs)\n\n /*\n * if the presence of this term is required ensure that the matching\n * documents are added to the set of required matches for this clause.\n *\n */\n if (clause.presence == lunr.Query.presence.REQUIRED) {\n clauseMatches = clauseMatches.union(matchingDocumentsSet)\n\n if (requiredMatches[field] === undefined) {\n requiredMatches[field] = lunr.Set.complete\n }\n }\n\n /*\n * if the presence of this term is prohibited ensure that the matching\n * documents are added to the set of prohibited matches for this field,\n * creating that set if it does not yet exist.\n */\n if (clause.presence == lunr.Query.presence.PROHIBITED) {\n if (prohibitedMatches[field] === undefined) {\n prohibitedMatches[field] = lunr.Set.empty\n }\n\n prohibitedMatches[field] = prohibitedMatches[field].union(matchingDocumentsSet)\n\n /*\n * Prohibited matches should not be part of the query vector used for\n * similarity scoring and no metadata should be extracted so we continue\n * to the next field\n */\n continue\n }\n\n /*\n * The query field vector is populated using the termIndex found for\n * the term and a unit value with the appropriate boost applied.\n * Using upsert because there could already be an entry in the vector\n * for the term we are working with. In that case we just add the scores\n * together.\n */\n queryVectors[field].upsert(termIndex, clause.boost, function (a, b) { return a + b })\n\n /**\n * If we've already seen this term, field combo then we've already collected\n * the matching documents and metadata, no need to go through all that again\n */\n if (termFieldCache[termField]) {\n continue\n }\n\n for (var l = 0; l < matchingDocumentRefs.length; l++) {\n /*\n * All metadata for this term/field/document triple\n * are then extracted and collected into an instance\n * of lunr.MatchData ready to be returned in the query\n * results\n */\n var matchingDocumentRef = matchingDocumentRefs[l],\n matchingFieldRef = new lunr.FieldRef (matchingDocumentRef, field),\n metadata = fieldPosting[matchingDocumentRef],\n fieldMatch\n\n if ((fieldMatch = matchingFields[matchingFieldRef]) === undefined) {\n matchingFields[matchingFieldRef] = new lunr.MatchData (expandedTerm, field, metadata)\n } else {\n fieldMatch.add(expandedTerm, field, metadata)\n }\n\n }\n\n termFieldCache[termField] = true\n }\n }\n }\n\n /**\n * If the presence was required we need to update the requiredMatches field sets.\n * We do this after all fields for the term have collected their matches because\n * the clause terms presence is required in _any_ of the fields not _all_ of the\n * fields.\n */\n if (clause.presence === lunr.Query.presence.REQUIRED) {\n for (var k = 0; k < clause.fields.length; k++) {\n var field = clause.fields[k]\n requiredMatches[field] = requiredMatches[field].intersect(clauseMatches)\n }\n }\n }\n\n /**\n * Need to combine the field scoped required and prohibited\n * matching documents into a global set of required and prohibited\n * matches\n */\n var allRequiredMatches = lunr.Set.complete,\n allProhibitedMatches = lunr.Set.empty\n\n for (var i = 0; i < this.fields.length; i++) {\n var field = this.fields[i]\n\n if (requiredMatches[field]) {\n allRequiredMatches = allRequiredMatches.intersect(requiredMatches[field])\n }\n\n if (prohibitedMatches[field]) {\n allProhibitedMatches = allProhibitedMatches.union(prohibitedMatches[field])\n }\n }\n\n var matchingFieldRefs = Object.keys(matchingFields),\n results = [],\n matches = Object.create(null)\n\n /*\n * If the query is negated (contains only prohibited terms)\n * we need to get _all_ fieldRefs currently existing in the\n * index. This is only done when we know that the query is\n * entirely prohibited terms to avoid any cost of getting all\n * fieldRefs unnecessarily.\n *\n * Additionally, blank MatchData must be created to correctly\n * populate the results.\n */\n if (query.isNegated()) {\n matchingFieldRefs = Object.keys(this.fieldVectors)\n\n for (var i = 0; i < matchingFieldRefs.length; i++) {\n var matchingFieldRef = matchingFieldRefs[i]\n var fieldRef = lunr.FieldRef.fromString(matchingFieldRef)\n matchingFields[matchingFieldRef] = new lunr.MatchData\n }\n }\n\n for (var i = 0; i < matchingFieldRefs.length; i++) {\n /*\n * Currently we have document fields that match the query, but we\n * need to return documents. The matchData and scores are combined\n * from multiple fields belonging to the same document.\n *\n * Scores are calculated by field, using the query vectors created\n * above, and combined into a final document score using addition.\n */\n var fieldRef = lunr.FieldRef.fromString(matchingFieldRefs[i]),\n docRef = fieldRef.docRef\n\n if (!allRequiredMatches.contains(docRef)) {\n continue\n }\n\n if (allProhibitedMatches.contains(docRef)) {\n continue\n }\n\n var fieldVector = this.fieldVectors[fieldRef],\n score = queryVectors[fieldRef.fieldName].similarity(fieldVector),\n docMatch\n\n if ((docMatch = matches[docRef]) !== undefined) {\n docMatch.score += score\n docMatch.matchData.combine(matchingFields[fieldRef])\n } else {\n var match = {\n ref: docRef,\n score: score,\n matchData: matchingFields[fieldRef]\n }\n matches[docRef] = match\n results.push(match)\n }\n }\n\n /*\n * Sort the results objects by score, highest first.\n */\n return results.sort(function (a, b) {\n return b.score - a.score\n })\n}\n\n/**\n * Prepares the index for JSON serialization.\n *\n * The schema for this JSON blob will be described in a\n * separate JSON schema file.\n *\n * @returns {Object}\n */\nlunr.Index.prototype.toJSON = function () {\n var invertedIndex = Object.keys(this.invertedIndex)\n .sort()\n .map(function (term) {\n return [term, this.invertedIndex[term]]\n }, this)\n\n var fieldVectors = Object.keys(this.fieldVectors)\n .map(function (ref) {\n return [ref, this.fieldVectors[ref].toJSON()]\n }, this)\n\n return {\n version: lunr.version,\n fields: this.fields,\n fieldVectors: fieldVectors,\n invertedIndex: invertedIndex,\n pipeline: this.pipeline.toJSON()\n }\n}\n\n/**\n * Loads a previously serialized lunr.Index\n *\n * @param {Object} serializedIndex - A previously serialized lunr.Index\n * @returns {lunr.Index}\n */\nlunr.Index.load = function (serializedIndex) {\n var attrs = {},\n fieldVectors = {},\n serializedVectors = serializedIndex.fieldVectors,\n invertedIndex = Object.create(null),\n serializedInvertedIndex = serializedIndex.invertedIndex,\n tokenSetBuilder = new lunr.TokenSet.Builder,\n pipeline = lunr.Pipeline.load(serializedIndex.pipeline)\n\n if (serializedIndex.version != lunr.version) {\n lunr.utils.warn(\"Version mismatch when loading serialised index. Current version of lunr '\" + lunr.version + \"' does not match serialized index '\" + serializedIndex.version + \"'\")\n }\n\n for (var i = 0; i < serializedVectors.length; i++) {\n var tuple = serializedVectors[i],\n ref = tuple[0],\n elements = tuple[1]\n\n fieldVectors[ref] = new lunr.Vector(elements)\n }\n\n for (var i = 0; i < serializedInvertedIndex.length; i++) {\n var tuple = serializedInvertedIndex[i],\n term = tuple[0],\n posting = tuple[1]\n\n tokenSetBuilder.insert(term)\n invertedIndex[term] = posting\n }\n\n tokenSetBuilder.finish()\n\n attrs.fields = serializedIndex.fields\n\n attrs.fieldVectors = fieldVectors\n attrs.invertedIndex = invertedIndex\n attrs.tokenSet = tokenSetBuilder.root\n attrs.pipeline = pipeline\n\n return new lunr.Index(attrs)\n}\n/*!\n * lunr.Builder\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * lunr.Builder performs indexing on a set of documents and\n * returns instances of lunr.Index ready for querying.\n *\n * All configuration of the index is done via the builder, the\n * fields to index, the document reference, the text processing\n * pipeline and document scoring parameters are all set on the\n * builder before indexing.\n *\n * @constructor\n * @property {string} _ref - Internal reference to the document reference field.\n * @property {string[]} _fields - Internal reference to the document fields to index.\n * @property {object} invertedIndex - The inverted index maps terms to document fields.\n * @property {object} documentTermFrequencies - Keeps track of document term frequencies.\n * @property {object} documentLengths - Keeps track of the length of documents added to the index.\n * @property {lunr.tokenizer} tokenizer - Function for splitting strings into tokens for indexing.\n * @property {lunr.Pipeline} pipeline - The pipeline performs text processing on tokens before indexing.\n * @property {lunr.Pipeline} searchPipeline - A pipeline for processing search terms before querying the index.\n * @property {number} documentCount - Keeps track of the total number of documents indexed.\n * @property {number} _b - A parameter to control field length normalization, setting this to 0 disabled normalization, 1 fully normalizes field lengths, the default value is 0.75.\n * @property {number} _k1 - A parameter to control how quickly an increase in term frequency results in term frequency saturation, the default value is 1.2.\n * @property {number} termIndex - A counter incremented for each unique term, used to identify a terms position in the vector space.\n * @property {array} metadataWhitelist - A list of metadata keys that have been whitelisted for entry in the index.\n */\nlunr.Builder = function () {\n this._ref = \"id\"\n this._fields = Object.create(null)\n this._documents = Object.create(null)\n this.invertedIndex = Object.create(null)\n this.fieldTermFrequencies = {}\n this.fieldLengths = {}\n this.tokenizer = lunr.tokenizer\n this.pipeline = new lunr.Pipeline\n this.searchPipeline = new lunr.Pipeline\n this.documentCount = 0\n this._b = 0.75\n this._k1 = 1.2\n this.termIndex = 0\n this.metadataWhitelist = []\n}\n\n/**\n * Sets the document field used as the document reference. Every document must have this field.\n * The type of this field in the document should be a string, if it is not a string it will be\n * coerced into a string by calling toString.\n *\n * The default ref is 'id'.\n *\n * The ref should _not_ be changed during indexing, it should be set before any documents are\n * added to the index. Changing it during indexing can lead to inconsistent results.\n *\n * @param {string} ref - The name of the reference field in the document.\n */\nlunr.Builder.prototype.ref = function (ref) {\n this._ref = ref\n}\n\n/**\n * A function that is used to extract a field from a document.\n *\n * Lunr expects a field to be at the top level of a document, if however the field\n * is deeply nested within a document an extractor function can be used to extract\n * the right field for indexing.\n *\n * @callback fieldExtractor\n * @param {object} doc - The document being added to the index.\n * @returns {?(string|object|object[])} obj - The object that will be indexed for this field.\n * @example Extracting a nested field\n * function (doc) { return doc.nested.field }\n */\n\n/**\n * Adds a field to the list of document fields that will be indexed. Every document being\n * indexed should have this field. Null values for this field in indexed documents will\n * not cause errors but will limit the chance of that document being retrieved by searches.\n *\n * All fields should be added before adding documents to the index. Adding fields after\n * a document has been indexed will have no effect on already indexed documents.\n *\n * Fields can be boosted at build time. This allows terms within that field to have more\n * importance when ranking search results. Use a field boost to specify that matches within\n * one field are more important than other fields.\n *\n * @param {string} fieldName - The name of a field to index in all documents.\n * @param {object} attributes - Optional attributes associated with this field.\n * @param {number} [attributes.boost=1] - Boost applied to all terms within this field.\n * @param {fieldExtractor} [attributes.extractor] - Function to extract a field from a document.\n * @throws {RangeError} fieldName cannot contain unsupported characters '/'\n */\nlunr.Builder.prototype.field = function (fieldName, attributes) {\n if (/\\//.test(fieldName)) {\n throw new RangeError (\"Field '\" + fieldName + \"' contains illegal character '/'\")\n }\n\n this._fields[fieldName] = attributes || {}\n}\n\n/**\n * A parameter to tune the amount of field length normalisation that is applied when\n * calculating relevance scores. A value of 0 will completely disable any normalisation\n * and a value of 1 will fully normalise field lengths. The default is 0.75. Values of b\n * will be clamped to the range 0 - 1.\n *\n * @param {number} number - The value to set for this tuning parameter.\n */\nlunr.Builder.prototype.b = function (number) {\n if (number < 0) {\n this._b = 0\n } else if (number > 1) {\n this._b = 1\n } else {\n this._b = number\n }\n}\n\n/**\n * A parameter that controls the speed at which a rise in term frequency results in term\n * frequency saturation. The default value is 1.2. Setting this to a higher value will give\n * slower saturation levels, a lower value will result in quicker saturation.\n *\n * @param {number} number - The value to set for this tuning parameter.\n */\nlunr.Builder.prototype.k1 = function (number) {\n this._k1 = number\n}\n\n/**\n * Adds a document to the index.\n *\n * Before adding fields to the index the index should have been fully setup, with the document\n * ref and all fields to index already having been specified.\n *\n * The document must have a field name as specified by the ref (by default this is 'id') and\n * it should have all fields defined for indexing, though null or undefined values will not\n * cause errors.\n *\n * Entire documents can be boosted at build time. Applying a boost to a document indicates that\n * this document should rank higher in search results than other documents.\n *\n * @param {object} doc - The document to add to the index.\n * @param {object} attributes - Optional attributes associated with this document.\n * @param {number} [attributes.boost=1] - Boost applied to all terms within this document.\n */\nlunr.Builder.prototype.add = function (doc, attributes) {\n var docRef = doc[this._ref],\n fields = Object.keys(this._fields)\n\n this._documents[docRef] = attributes || {}\n this.documentCount += 1\n\n for (var i = 0; i < fields.length; i++) {\n var fieldName = fields[i],\n extractor = this._fields[fieldName].extractor,\n field = extractor ? extractor(doc) : doc[fieldName],\n tokens = this.tokenizer(field, {\n fields: [fieldName]\n }),\n terms = this.pipeline.run(tokens),\n fieldRef = new lunr.FieldRef (docRef, fieldName),\n fieldTerms = Object.create(null)\n\n this.fieldTermFrequencies[fieldRef] = fieldTerms\n this.fieldLengths[fieldRef] = 0\n\n // store the length of this field for this document\n this.fieldLengths[fieldRef] += terms.length\n\n // calculate term frequencies for this field\n for (var j = 0; j < terms.length; j++) {\n var term = terms[j]\n\n if (fieldTerms[term] == undefined) {\n fieldTerms[term] = 0\n }\n\n fieldTerms[term] += 1\n\n // add to inverted index\n // create an initial posting if one doesn't exist\n if (this.invertedIndex[term] == undefined) {\n var posting = Object.create(null)\n posting[\"_index\"] = this.termIndex\n this.termIndex += 1\n\n for (var k = 0; k < fields.length; k++) {\n posting[fields[k]] = Object.create(null)\n }\n\n this.invertedIndex[term] = posting\n }\n\n // add an entry for this term/fieldName/docRef to the invertedIndex\n if (this.invertedIndex[term][fieldName][docRef] == undefined) {\n this.invertedIndex[term][fieldName][docRef] = Object.create(null)\n }\n\n // store all whitelisted metadata about this token in the\n // inverted index\n for (var l = 0; l < this.metadataWhitelist.length; l++) {\n var metadataKey = this.metadataWhitelist[l],\n metadata = term.metadata[metadataKey]\n\n if (this.invertedIndex[term][fieldName][docRef][metadataKey] == undefined) {\n this.invertedIndex[term][fieldName][docRef][metadataKey] = []\n }\n\n this.invertedIndex[term][fieldName][docRef][metadataKey].push(metadata)\n }\n }\n\n }\n}\n\n/**\n * Calculates the average document length for this index\n *\n * @private\n */\nlunr.Builder.prototype.calculateAverageFieldLengths = function () {\n\n var fieldRefs = Object.keys(this.fieldLengths),\n numberOfFields = fieldRefs.length,\n accumulator = {},\n documentsWithField = {}\n\n for (var i = 0; i < numberOfFields; i++) {\n var fieldRef = lunr.FieldRef.fromString(fieldRefs[i]),\n field = fieldRef.fieldName\n\n documentsWithField[field] || (documentsWithField[field] = 0)\n documentsWithField[field] += 1\n\n accumulator[field] || (accumulator[field] = 0)\n accumulator[field] += this.fieldLengths[fieldRef]\n }\n\n var fields = Object.keys(this._fields)\n\n for (var i = 0; i < fields.length; i++) {\n var fieldName = fields[i]\n accumulator[fieldName] = accumulator[fieldName] / documentsWithField[fieldName]\n }\n\n this.averageFieldLength = accumulator\n}\n\n/**\n * Builds a vector space model of every document using lunr.Vector\n *\n * @private\n */\nlunr.Builder.prototype.createFieldVectors = function () {\n var fieldVectors = {},\n fieldRefs = Object.keys(this.fieldTermFrequencies),\n fieldRefsLength = fieldRefs.length,\n termIdfCache = Object.create(null)\n\n for (var i = 0; i < fieldRefsLength; i++) {\n var fieldRef = lunr.FieldRef.fromString(fieldRefs[i]),\n fieldName = fieldRef.fieldName,\n fieldLength = this.fieldLengths[fieldRef],\n fieldVector = new lunr.Vector,\n termFrequencies = this.fieldTermFrequencies[fieldRef],\n terms = Object.keys(termFrequencies),\n termsLength = terms.length\n\n\n var fieldBoost = this._fields[fieldName].boost || 1,\n docBoost = this._documents[fieldRef.docRef].boost || 1\n\n for (var j = 0; j < termsLength; j++) {\n var term = terms[j],\n tf = termFrequencies[term],\n termIndex = this.invertedIndex[term]._index,\n idf, score, scoreWithPrecision\n\n if (termIdfCache[term] === undefined) {\n idf = lunr.idf(this.invertedIndex[term], this.documentCount)\n termIdfCache[term] = idf\n } else {\n idf = termIdfCache[term]\n }\n\n score = idf * ((this._k1 + 1) * tf) / (this._k1 * (1 - this._b + this._b * (fieldLength / this.averageFieldLength[fieldName])) + tf)\n score *= fieldBoost\n score *= docBoost\n scoreWithPrecision = Math.round(score * 1000) / 1000\n // Converts 1.23456789 to 1.234.\n // Reducing the precision so that the vectors take up less\n // space when serialised. Doing it now so that they behave\n // the same before and after serialisation. Also, this is\n // the fastest approach to reducing a number's precision in\n // JavaScript.\n\n fieldVector.insert(termIndex, scoreWithPrecision)\n }\n\n fieldVectors[fieldRef] = fieldVector\n }\n\n this.fieldVectors = fieldVectors\n}\n\n/**\n * Creates a token set of all tokens in the index using lunr.TokenSet\n *\n * @private\n */\nlunr.Builder.prototype.createTokenSet = function () {\n this.tokenSet = lunr.TokenSet.fromArray(\n Object.keys(this.invertedIndex).sort()\n )\n}\n\n/**\n * Builds the index, creating an instance of lunr.Index.\n *\n * This completes the indexing process and should only be called\n * once all documents have been added to the index.\n *\n * @returns {lunr.Index}\n */\nlunr.Builder.prototype.build = function () {\n this.calculateAverageFieldLengths()\n this.createFieldVectors()\n this.createTokenSet()\n\n return new lunr.Index({\n invertedIndex: this.invertedIndex,\n fieldVectors: this.fieldVectors,\n tokenSet: this.tokenSet,\n fields: Object.keys(this._fields),\n pipeline: this.searchPipeline\n })\n}\n\n/**\n * Applies a plugin to the index builder.\n *\n * A plugin is a function that is called with the index builder as its context.\n * Plugins can be used to customise or extend the behaviour of the index\n * in some way. A plugin is just a function, that encapsulated the custom\n * behaviour that should be applied when building the index.\n *\n * The plugin function will be called with the index builder as its argument, additional\n * arguments can also be passed when calling use. The function will be called\n * with the index builder as its context.\n *\n * @param {Function} plugin The plugin to apply.\n */\nlunr.Builder.prototype.use = function (fn) {\n var args = Array.prototype.slice.call(arguments, 1)\n args.unshift(this)\n fn.apply(this, args)\n}\n/**\n * Contains and collects metadata about a matching document.\n * A single instance of lunr.MatchData is returned as part of every\n * lunr.Index~Result.\n *\n * @constructor\n * @param {string} term - The term this match data is associated with\n * @param {string} field - The field in which the term was found\n * @param {object} metadata - The metadata recorded about this term in this field\n * @property {object} metadata - A cloned collection of metadata associated with this document.\n * @see {@link lunr.Index~Result}\n */\nlunr.MatchData = function (term, field, metadata) {\n var clonedMetadata = Object.create(null),\n metadataKeys = Object.keys(metadata || {})\n\n // Cloning the metadata to prevent the original\n // being mutated during match data combination.\n // Metadata is kept in an array within the inverted\n // index so cloning the data can be done with\n // Array#slice\n for (var i = 0; i < metadataKeys.length; i++) {\n var key = metadataKeys[i]\n clonedMetadata[key] = metadata[key].slice()\n }\n\n this.metadata = Object.create(null)\n\n if (term !== undefined) {\n this.metadata[term] = Object.create(null)\n this.metadata[term][field] = clonedMetadata\n }\n}\n\n/**\n * An instance of lunr.MatchData will be created for every term that matches a\n * document. However only one instance is required in a lunr.Index~Result. This\n * method combines metadata from another instance of lunr.MatchData with this\n * objects metadata.\n *\n * @param {lunr.MatchData} otherMatchData - Another instance of match data to merge with this one.\n * @see {@link lunr.Index~Result}\n */\nlunr.MatchData.prototype.combine = function (otherMatchData) {\n var terms = Object.keys(otherMatchData.metadata)\n\n for (var i = 0; i < terms.length; i++) {\n var term = terms[i],\n fields = Object.keys(otherMatchData.metadata[term])\n\n if (this.metadata[term] == undefined) {\n this.metadata[term] = Object.create(null)\n }\n\n for (var j = 0; j < fields.length; j++) {\n var field = fields[j],\n keys = Object.keys(otherMatchData.metadata[term][field])\n\n if (this.metadata[term][field] == undefined) {\n this.metadata[term][field] = Object.create(null)\n }\n\n for (var k = 0; k < keys.length; k++) {\n var key = keys[k]\n\n if (this.metadata[term][field][key] == undefined) {\n this.metadata[term][field][key] = otherMatchData.metadata[term][field][key]\n } else {\n this.metadata[term][field][key] = this.metadata[term][field][key].concat(otherMatchData.metadata[term][field][key])\n }\n\n }\n }\n }\n}\n\n/**\n * Add metadata for a term/field pair to this instance of match data.\n *\n * @param {string} term - The term this match data is associated with\n * @param {string} field - The field in which the term was found\n * @param {object} metadata - The metadata recorded about this term in this field\n */\nlunr.MatchData.prototype.add = function (term, field, metadata) {\n if (!(term in this.metadata)) {\n this.metadata[term] = Object.create(null)\n this.metadata[term][field] = metadata\n return\n }\n\n if (!(field in this.metadata[term])) {\n this.metadata[term][field] = metadata\n return\n }\n\n var metadataKeys = Object.keys(metadata)\n\n for (var i = 0; i < metadataKeys.length; i++) {\n var key = metadataKeys[i]\n\n if (key in this.metadata[term][field]) {\n this.metadata[term][field][key] = this.metadata[term][field][key].concat(metadata[key])\n } else {\n this.metadata[term][field][key] = metadata[key]\n }\n }\n}\n/**\n * A lunr.Query provides a programmatic way of defining queries to be performed\n * against a {@link lunr.Index}.\n *\n * Prefer constructing a lunr.Query using the {@link lunr.Index#query} method\n * so the query object is pre-initialized with the right index fields.\n *\n * @constructor\n * @property {lunr.Query~Clause[]} clauses - An array of query clauses.\n * @property {string[]} allFields - An array of all available fields in a lunr.Index.\n */\nlunr.Query = function (allFields) {\n this.clauses = []\n this.allFields = allFields\n}\n\n/**\n * Constants for indicating what kind of automatic wildcard insertion will be used when constructing a query clause.\n *\n * This allows wildcards to be added to the beginning and end of a term without having to manually do any string\n * concatenation.\n *\n * The wildcard constants can be bitwise combined to select both leading and trailing wildcards.\n *\n * @constant\n * @default\n * @property {number} wildcard.NONE - The term will have no wildcards inserted, this is the default behaviour\n * @property {number} wildcard.LEADING - Prepend the term with a wildcard, unless a leading wildcard already exists\n * @property {number} wildcard.TRAILING - Append a wildcard to the term, unless a trailing wildcard already exists\n * @see lunr.Query~Clause\n * @see lunr.Query#clause\n * @see lunr.Query#term\n * @example query term with trailing wildcard\n * query.term('foo', { wildcard: lunr.Query.wildcard.TRAILING })\n * @example query term with leading and trailing wildcard\n * query.term('foo', {\n * wildcard: lunr.Query.wildcard.LEADING | lunr.Query.wildcard.TRAILING\n * })\n */\n\nlunr.Query.wildcard = new String (\"*\")\nlunr.Query.wildcard.NONE = 0\nlunr.Query.wildcard.LEADING = 1\nlunr.Query.wildcard.TRAILING = 2\n\n/**\n * Constants for indicating what kind of presence a term must have in matching documents.\n *\n * @constant\n * @enum {number}\n * @see lunr.Query~Clause\n * @see lunr.Query#clause\n * @see lunr.Query#term\n * @example query term with required presence\n * query.term('foo', { presence: lunr.Query.presence.REQUIRED })\n */\nlunr.Query.presence = {\n /**\n * Term's presence in a document is optional, this is the default value.\n */\n OPTIONAL: 1,\n\n /**\n * Term's presence in a document is required, documents that do not contain\n * this term will not be returned.\n */\n REQUIRED: 2,\n\n /**\n * Term's presence in a document is prohibited, documents that do contain\n * this term will not be returned.\n */\n PROHIBITED: 3\n}\n\n/**\n * A single clause in a {@link lunr.Query} contains a term and details on how to\n * match that term against a {@link lunr.Index}.\n *\n * @typedef {Object} lunr.Query~Clause\n * @property {string[]} fields - The fields in an index this clause should be matched against.\n * @property {number} [boost=1] - Any boost that should be applied when matching this clause.\n * @property {number} [editDistance] - Whether the term should have fuzzy matching applied, and how fuzzy the match should be.\n * @property {boolean} [usePipeline] - Whether the term should be passed through the search pipeline.\n * @property {number} [wildcard=lunr.Query.wildcard.NONE] - Whether the term should have wildcards appended or prepended.\n * @property {number} [presence=lunr.Query.presence.OPTIONAL] - The terms presence in any matching documents.\n */\n\n/**\n * Adds a {@link lunr.Query~Clause} to this query.\n *\n * Unless the clause contains the fields to be matched all fields will be matched. In addition\n * a default boost of 1 is applied to the clause.\n *\n * @param {lunr.Query~Clause} clause - The clause to add to this query.\n * @see lunr.Query~Clause\n * @returns {lunr.Query}\n */\nlunr.Query.prototype.clause = function (clause) {\n if (!('fields' in clause)) {\n clause.fields = this.allFields\n }\n\n if (!('boost' in clause)) {\n clause.boost = 1\n }\n\n if (!('usePipeline' in clause)) {\n clause.usePipeline = true\n }\n\n if (!('wildcard' in clause)) {\n clause.wildcard = lunr.Query.wildcard.NONE\n }\n\n if ((clause.wildcard & lunr.Query.wildcard.LEADING) && (clause.term.charAt(0) != lunr.Query.wildcard)) {\n clause.term = \"*\" + clause.term\n }\n\n if ((clause.wildcard & lunr.Query.wildcard.TRAILING) && (clause.term.slice(-1) != lunr.Query.wildcard)) {\n clause.term = \"\" + clause.term + \"*\"\n }\n\n if (!('presence' in clause)) {\n clause.presence = lunr.Query.presence.OPTIONAL\n }\n\n this.clauses.push(clause)\n\n return this\n}\n\n/**\n * A negated query is one in which every clause has a presence of\n * prohibited. These queries require some special processing to return\n * the expected results.\n *\n * @returns boolean\n */\nlunr.Query.prototype.isNegated = function () {\n for (var i = 0; i < this.clauses.length; i++) {\n if (this.clauses[i].presence != lunr.Query.presence.PROHIBITED) {\n return false\n }\n }\n\n return true\n}\n\n/**\n * Adds a term to the current query, under the covers this will create a {@link lunr.Query~Clause}\n * to the list of clauses that make up this query.\n *\n * The term is used as is, i.e. no tokenization will be performed by this method. Instead conversion\n * to a token or token-like string should be done before calling this method.\n *\n * The term will be converted to a string by calling `toString`. Multiple terms can be passed as an\n * array, each term in the array will share the same options.\n *\n * @param {object|object[]} term - The term(s) to add to the query.\n * @param {object} [options] - Any additional properties to add to the query clause.\n * @returns {lunr.Query}\n * @see lunr.Query#clause\n * @see lunr.Query~Clause\n * @example adding a single term to a query\n * query.term(\"foo\")\n * @example adding a single term to a query and specifying search fields, term boost and automatic trailing wildcard\n * query.term(\"foo\", {\n * fields: [\"title\"],\n * boost: 10,\n * wildcard: lunr.Query.wildcard.TRAILING\n * })\n * @example using lunr.tokenizer to convert a string to tokens before using them as terms\n * query.term(lunr.tokenizer(\"foo bar\"))\n */\nlunr.Query.prototype.term = function (term, options) {\n if (Array.isArray(term)) {\n term.forEach(function (t) { this.term(t, lunr.utils.clone(options)) }, this)\n return this\n }\n\n var clause = options || {}\n clause.term = term.toString()\n\n this.clause(clause)\n\n return this\n}\nlunr.QueryParseError = function (message, start, end) {\n this.name = \"QueryParseError\"\n this.message = message\n this.start = start\n this.end = end\n}\n\nlunr.QueryParseError.prototype = new Error\nlunr.QueryLexer = function (str) {\n this.lexemes = []\n this.str = str\n this.length = str.length\n this.pos = 0\n this.start = 0\n this.escapeCharPositions = []\n}\n\nlunr.QueryLexer.prototype.run = function () {\n var state = lunr.QueryLexer.lexText\n\n while (state) {\n state = state(this)\n }\n}\n\nlunr.QueryLexer.prototype.sliceString = function () {\n var subSlices = [],\n sliceStart = this.start,\n sliceEnd = this.pos\n\n for (var i = 0; i < this.escapeCharPositions.length; i++) {\n sliceEnd = this.escapeCharPositions[i]\n subSlices.push(this.str.slice(sliceStart, sliceEnd))\n sliceStart = sliceEnd + 1\n }\n\n subSlices.push(this.str.slice(sliceStart, this.pos))\n this.escapeCharPositions.length = 0\n\n return subSlices.join('')\n}\n\nlunr.QueryLexer.prototype.emit = function (type) {\n this.lexemes.push({\n type: type,\n str: this.sliceString(),\n start: this.start,\n end: this.pos\n })\n\n this.start = this.pos\n}\n\nlunr.QueryLexer.prototype.escapeCharacter = function () {\n this.escapeCharPositions.push(this.pos - 1)\n this.pos += 1\n}\n\nlunr.QueryLexer.prototype.next = function () {\n if (this.pos >= this.length) {\n return lunr.QueryLexer.EOS\n }\n\n var char = this.str.charAt(this.pos)\n this.pos += 1\n return char\n}\n\nlunr.QueryLexer.prototype.width = function () {\n return this.pos - this.start\n}\n\nlunr.QueryLexer.prototype.ignore = function () {\n if (this.start == this.pos) {\n this.pos += 1\n }\n\n this.start = this.pos\n}\n\nlunr.QueryLexer.prototype.backup = function () {\n this.pos -= 1\n}\n\nlunr.QueryLexer.prototype.acceptDigitRun = function () {\n var char, charCode\n\n do {\n char = this.next()\n charCode = char.charCodeAt(0)\n } while (charCode > 47 && charCode < 58)\n\n if (char != lunr.QueryLexer.EOS) {\n this.backup()\n }\n}\n\nlunr.QueryLexer.prototype.more = function () {\n return this.pos < this.length\n}\n\nlunr.QueryLexer.EOS = 'EOS'\nlunr.QueryLexer.FIELD = 'FIELD'\nlunr.QueryLexer.TERM = 'TERM'\nlunr.QueryLexer.EDIT_DISTANCE = 'EDIT_DISTANCE'\nlunr.QueryLexer.BOOST = 'BOOST'\nlunr.QueryLexer.PRESENCE = 'PRESENCE'\n\nlunr.QueryLexer.lexField = function (lexer) {\n lexer.backup()\n lexer.emit(lunr.QueryLexer.FIELD)\n lexer.ignore()\n return lunr.QueryLexer.lexText\n}\n\nlunr.QueryLexer.lexTerm = function (lexer) {\n if (lexer.width() > 1) {\n lexer.backup()\n lexer.emit(lunr.QueryLexer.TERM)\n }\n\n lexer.ignore()\n\n if (lexer.more()) {\n return lunr.QueryLexer.lexText\n }\n}\n\nlunr.QueryLexer.lexEditDistance = function (lexer) {\n lexer.ignore()\n lexer.acceptDigitRun()\n lexer.emit(lunr.QueryLexer.EDIT_DISTANCE)\n return lunr.QueryLexer.lexText\n}\n\nlunr.QueryLexer.lexBoost = function (lexer) {\n lexer.ignore()\n lexer.acceptDigitRun()\n lexer.emit(lunr.QueryLexer.BOOST)\n return lunr.QueryLexer.lexText\n}\n\nlunr.QueryLexer.lexEOS = function (lexer) {\n if (lexer.width() > 0) {\n lexer.emit(lunr.QueryLexer.TERM)\n }\n}\n\n// This matches the separator used when tokenising fields\n// within a document. These should match otherwise it is\n// not possible to search for some tokens within a document.\n//\n// It is possible for the user to change the separator on the\n// tokenizer so it _might_ clash with any other of the special\n// characters already used within the search string, e.g. :.\n//\n// This means that it is possible to change the separator in\n// such a way that makes some words unsearchable using a search\n// string.\nlunr.QueryLexer.termSeparator = lunr.tokenizer.separator\n\nlunr.QueryLexer.lexText = function (lexer) {\n while (true) {\n var char = lexer.next()\n\n if (char == lunr.QueryLexer.EOS) {\n return lunr.QueryLexer.lexEOS\n }\n\n // Escape character is '\\'\n if (char.charCodeAt(0) == 92) {\n lexer.escapeCharacter()\n continue\n }\n\n if (char == \":\") {\n return lunr.QueryLexer.lexField\n }\n\n if (char == \"~\") {\n lexer.backup()\n if (lexer.width() > 0) {\n lexer.emit(lunr.QueryLexer.TERM)\n }\n return lunr.QueryLexer.lexEditDistance\n }\n\n if (char == \"^\") {\n lexer.backup()\n if (lexer.width() > 0) {\n lexer.emit(lunr.QueryLexer.TERM)\n }\n return lunr.QueryLexer.lexBoost\n }\n\n // \"+\" indicates term presence is required\n // checking for length to ensure that only\n // leading \"+\" are considered\n if (char == \"+\" && lexer.width() === 1) {\n lexer.emit(lunr.QueryLexer.PRESENCE)\n return lunr.QueryLexer.lexText\n }\n\n // \"-\" indicates term presence is prohibited\n // checking for length to ensure that only\n // leading \"-\" are considered\n if (char == \"-\" && lexer.width() === 1) {\n lexer.emit(lunr.QueryLexer.PRESENCE)\n return lunr.QueryLexer.lexText\n }\n\n if (char.match(lunr.QueryLexer.termSeparator)) {\n return lunr.QueryLexer.lexTerm\n }\n }\n}\n\nlunr.QueryParser = function (str, query) {\n this.lexer = new lunr.QueryLexer (str)\n this.query = query\n this.currentClause = {}\n this.lexemeIdx = 0\n}\n\nlunr.QueryParser.prototype.parse = function () {\n this.lexer.run()\n this.lexemes = this.lexer.lexemes\n\n var state = lunr.QueryParser.parseClause\n\n while (state) {\n state = state(this)\n }\n\n return this.query\n}\n\nlunr.QueryParser.prototype.peekLexeme = function () {\n return this.lexemes[this.lexemeIdx]\n}\n\nlunr.QueryParser.prototype.consumeLexeme = function () {\n var lexeme = this.peekLexeme()\n this.lexemeIdx += 1\n return lexeme\n}\n\nlunr.QueryParser.prototype.nextClause = function () {\n var completedClause = this.currentClause\n this.query.clause(completedClause)\n this.currentClause = {}\n}\n\nlunr.QueryParser.parseClause = function (parser) {\n var lexeme = parser.peekLexeme()\n\n if (lexeme == undefined) {\n return\n }\n\n switch (lexeme.type) {\n case lunr.QueryLexer.PRESENCE:\n return lunr.QueryParser.parsePresence\n case lunr.QueryLexer.FIELD:\n return lunr.QueryParser.parseField\n case lunr.QueryLexer.TERM:\n return lunr.QueryParser.parseTerm\n default:\n var errorMessage = \"expected either a field or a term, found \" + lexeme.type\n\n if (lexeme.str.length >= 1) {\n errorMessage += \" with value '\" + lexeme.str + \"'\"\n }\n\n throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n }\n}\n\nlunr.QueryParser.parsePresence = function (parser) {\n var lexeme = parser.consumeLexeme()\n\n if (lexeme == undefined) {\n return\n }\n\n switch (lexeme.str) {\n case \"-\":\n parser.currentClause.presence = lunr.Query.presence.PROHIBITED\n break\n case \"+\":\n parser.currentClause.presence = lunr.Query.presence.REQUIRED\n break\n default:\n var errorMessage = \"unrecognised presence operator'\" + lexeme.str + \"'\"\n throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n }\n\n var nextLexeme = parser.peekLexeme()\n\n if (nextLexeme == undefined) {\n var errorMessage = \"expecting term or field, found nothing\"\n throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n }\n\n switch (nextLexeme.type) {\n case lunr.QueryLexer.FIELD:\n return lunr.QueryParser.parseField\n case lunr.QueryLexer.TERM:\n return lunr.QueryParser.parseTerm\n default:\n var errorMessage = \"expecting term or field, found '\" + nextLexeme.type + \"'\"\n throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)\n }\n}\n\nlunr.QueryParser.parseField = function (parser) {\n var lexeme = parser.consumeLexeme()\n\n if (lexeme == undefined) {\n return\n }\n\n if (parser.query.allFields.indexOf(lexeme.str) == -1) {\n var possibleFields = parser.query.allFields.map(function (f) { return \"'\" + f + \"'\" }).join(', '),\n errorMessage = \"unrecognised field '\" + lexeme.str + \"', possible fields: \" + possibleFields\n\n throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n }\n\n parser.currentClause.fields = [lexeme.str]\n\n var nextLexeme = parser.peekLexeme()\n\n if (nextLexeme == undefined) {\n var errorMessage = \"expecting term, found nothing\"\n throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n }\n\n switch (nextLexeme.type) {\n case lunr.QueryLexer.TERM:\n return lunr.QueryParser.parseTerm\n default:\n var errorMessage = \"expecting term, found '\" + nextLexeme.type + \"'\"\n throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)\n }\n}\n\nlunr.QueryParser.parseTerm = function (parser) {\n var lexeme = parser.consumeLexeme()\n\n if (lexeme == undefined) {\n return\n }\n\n parser.currentClause.term = lexeme.str.toLowerCase()\n\n if (lexeme.str.indexOf(\"*\") != -1) {\n parser.currentClause.usePipeline = false\n }\n\n var nextLexeme = parser.peekLexeme()\n\n if (nextLexeme == undefined) {\n parser.nextClause()\n return\n }\n\n switch (nextLexeme.type) {\n case lunr.QueryLexer.TERM:\n parser.nextClause()\n return lunr.QueryParser.parseTerm\n case lunr.QueryLexer.FIELD:\n parser.nextClause()\n return lunr.QueryParser.parseField\n case lunr.QueryLexer.EDIT_DISTANCE:\n return lunr.QueryParser.parseEditDistance\n case lunr.QueryLexer.BOOST:\n return lunr.QueryParser.parseBoost\n case lunr.QueryLexer.PRESENCE:\n parser.nextClause()\n return lunr.QueryParser.parsePresence\n default:\n var errorMessage = \"Unexpected lexeme type '\" + nextLexeme.type + \"'\"\n throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)\n }\n}\n\nlunr.QueryParser.parseEditDistance = function (parser) {\n var lexeme = parser.consumeLexeme()\n\n if (lexeme == undefined) {\n return\n }\n\n var editDistance = parseInt(lexeme.str, 10)\n\n if (isNaN(editDistance)) {\n var errorMessage = \"edit distance must be numeric\"\n throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n }\n\n parser.currentClause.editDistance = editDistance\n\n var nextLexeme = parser.peekLexeme()\n\n if (nextLexeme == undefined) {\n parser.nextClause()\n return\n }\n\n switch (nextLexeme.type) {\n case lunr.QueryLexer.TERM:\n parser.nextClause()\n return lunr.QueryParser.parseTerm\n case lunr.QueryLexer.FIELD:\n parser.nextClause()\n return lunr.QueryParser.parseField\n case lunr.QueryLexer.EDIT_DISTANCE:\n return lunr.QueryParser.parseEditDistance\n case lunr.QueryLexer.BOOST:\n return lunr.QueryParser.parseBoost\n case lunr.QueryLexer.PRESENCE:\n parser.nextClause()\n return lunr.QueryParser.parsePresence\n default:\n var errorMessage = \"Unexpected lexeme type '\" + nextLexeme.type + \"'\"\n throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)\n }\n}\n\nlunr.QueryParser.parseBoost = function (parser) {\n var lexeme = parser.consumeLexeme()\n\n if (lexeme == undefined) {\n return\n }\n\n var boost = parseInt(lexeme.str, 10)\n\n if (isNaN(boost)) {\n var errorMessage = \"boost must be numeric\"\n throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n }\n\n parser.currentClause.boost = boost\n\n var nextLexeme = parser.peekLexeme()\n\n if (nextLexeme == undefined) {\n parser.nextClause()\n return\n }\n\n switch (nextLexeme.type) {\n case lunr.QueryLexer.TERM:\n parser.nextClause()\n return lunr.QueryParser.parseTerm\n case lunr.QueryLexer.FIELD:\n parser.nextClause()\n return lunr.QueryParser.parseField\n case lunr.QueryLexer.EDIT_DISTANCE:\n return lunr.QueryParser.parseEditDistance\n case lunr.QueryLexer.BOOST:\n return lunr.QueryParser.parseBoost\n case lunr.QueryLexer.PRESENCE:\n parser.nextClause()\n return lunr.QueryParser.parsePresence\n default:\n var errorMessage = \"Unexpected lexeme type '\" + nextLexeme.type + \"'\"\n throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)\n }\n}\n\n /**\n * export the module via AMD, CommonJS or as a browser global\n * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js\n */\n ;(function (root, factory) {\n if (typeof define === 'function' && define.amd) {\n // AMD. Register as an anonymous module.\n define(factory)\n } else if (typeof exports === 'object') {\n /**\n * Node. Does not work with strict CommonJS, but\n * only CommonJS-like enviroments that support module.exports,\n * like Node.\n */\n module.exports = factory()\n } else {\n // Browser globals (root is window)\n root.lunr = factory()\n }\n }(this, function () {\n /**\n * Just return a value to define the module export.\n * This example returns an object, but the module\n * can return a function as the exported value.\n */\n return lunr\n }))\n})();\n", "/*!\n * escape-html\n * Copyright(c) 2012-2013 TJ Holowaychuk\n * Copyright(c) 2015 Andreas Lubbe\n * Copyright(c) 2015 Tiancheng \"Timothy\" Gu\n * MIT Licensed\n */\n\n'use strict';\n\n/**\n * Module variables.\n * @private\n */\n\nvar matchHtmlRegExp = /[\"'&<>]/;\n\n/**\n * Module exports.\n * @public\n */\n\nmodule.exports = escapeHtml;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @param {string} string The string to escape for inserting into HTML\n * @return {string}\n * @public\n */\n\nfunction escapeHtml(string) {\n var str = '' + string;\n var match = matchHtmlRegExp.exec(str);\n\n if (!match) {\n return str;\n }\n\n var escape;\n var html = '';\n var index = 0;\n var lastIndex = 0;\n\n for (index = match.index; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34: // \"\n escape = '"';\n break;\n case 38: // &\n escape = '&';\n break;\n case 39: // '\n escape = ''';\n break;\n case 60: // <\n escape = '<';\n break;\n case 62: // >\n escape = '>';\n break;\n default:\n continue;\n }\n\n if (lastIndex !== index) {\n html += str.substring(lastIndex, index);\n }\n\n lastIndex = index + 1;\n html += escape;\n }\n\n return lastIndex !== index\n ? html + str.substring(lastIndex, index)\n : html;\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A RTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport lunr from \"lunr\"\n\nimport \"~/polyfills\"\n\nimport { Search, SearchIndexConfig } from \"../../_\"\nimport {\n SearchMessage,\n SearchMessageType\n} from \"../message\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Add support for usage with `iframe-worker` polyfill\n *\n * While `importScripts` is synchronous when executed inside of a web worker,\n * it's not possible to provide a synchronous polyfilled implementation. The\n * cool thing is that awaiting a non-Promise is a noop, so extending the type\n * definition to return a `Promise` shouldn't break anything.\n *\n * @see https://bit.ly/2PjDnXi - GitHub comment\n */\ndeclare global {\n function importScripts(...urls: string[]): Promise | void\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Search index\n */\nlet index: Search\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch (= import) multi-language support through `lunr-languages`\n *\n * This function automatically imports the stemmers necessary to process the\n * languages, which are defined through the search index configuration.\n *\n * If the worker runs inside of an `iframe` (when using `iframe-worker` as\n * a shim), the base URL for the stemmers to be loaded must be determined by\n * searching for the first `script` element with a `src` attribute, which will\n * contain the contents of this script.\n *\n * @param config - Search index configuration\n *\n * @returns Promise resolving with no result\n */\nasync function setupSearchLanguages(\n config: SearchIndexConfig\n): Promise {\n let base = \"../lunr\"\n\n /* Detect `iframe-worker` and fix base URL */\n if (typeof parent !== \"undefined\" && \"IFrameWorker\" in parent) {\n const worker = document.querySelector(\"script[src]\")!\n const [path] = worker.src.split(\"/worker\")\n\n /* Prefix base with path */\n base = base.replace(\"..\", path)\n }\n\n /* Add scripts for languages */\n const scripts = []\n for (const lang of config.lang) {\n switch (lang) {\n\n /* Add segmenter for Japanese */\n case \"ja\":\n scripts.push(`${base}/tinyseg.js`)\n break\n\n /* Add segmenter for Hindi and Thai */\n case \"hi\":\n case \"th\":\n scripts.push(`${base}/wordcut.js`)\n break\n }\n\n /* Add language support */\n if (lang !== \"en\")\n scripts.push(`${base}/min/lunr.${lang}.min.js`)\n }\n\n /* Add multi-language support */\n if (config.lang.length > 1)\n scripts.push(`${base}/min/lunr.multi.min.js`)\n\n /* Load scripts synchronously */\n if (scripts.length)\n await importScripts(\n `${base}/min/lunr.stemmer.support.min.js`,\n ...scripts\n )\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Message handler\n *\n * @param message - Source message\n *\n * @returns Target message\n */\nexport async function handler(\n message: SearchMessage\n): Promise {\n switch (message.type) {\n\n /* Search setup message */\n case SearchMessageType.SETUP:\n await setupSearchLanguages(message.data.config)\n index = new Search(message.data)\n return {\n type: SearchMessageType.READY\n }\n\n /* Search query message */\n case SearchMessageType.QUERY:\n return {\n type: SearchMessageType.RESULT,\n data: index ? index.search(message.data) : { items: [] }\n }\n\n /* All other messages */\n default:\n throw new TypeError(\"Invalid message type\")\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Worker\n * ------------------------------------------------------------------------- */\n\n/* @ts-expect-error - expose Lunr.js in global scope, or stemmers won't work */\nself.lunr = lunr\n\n/* Handle messages */\naddEventListener(\"message\", async ev => {\n postMessage(await handler(ev.data))\n})\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Polyfills\n * ------------------------------------------------------------------------- */\n\n/* Polyfill `Object.entries` */\nif (!Object.entries)\n Object.entries = function (obj: object) {\n const data: [string, string][] = []\n for (const key of Object.keys(obj))\n // @ts-expect-error - ignore property access warning\n data.push([key, obj[key]])\n\n /* Return entries */\n return data\n }\n\n/* Polyfill `Object.values` */\nif (!Object.values)\n Object.values = function (obj: object) {\n const data: string[] = []\n for (const key of Object.keys(obj))\n // @ts-expect-error - ignore property access warning\n data.push(obj[key])\n\n /* Return values */\n return data\n }\n\n/* ------------------------------------------------------------------------- */\n\n/* Polyfills for `Element` */\nif (typeof Element !== \"undefined\") {\n\n /* Polyfill `Element.scrollTo` */\n if (!Element.prototype.scrollTo)\n Element.prototype.scrollTo = function (\n x?: ScrollToOptions | number, y?: number\n ): void {\n if (typeof x === \"object\") {\n this.scrollLeft = x.left!\n this.scrollTop = x.top!\n } else {\n this.scrollLeft = x!\n this.scrollTop = y!\n }\n }\n\n /* Polyfill `Element.replaceWith` */\n if (!Element.prototype.replaceWith)\n Element.prototype.replaceWith = function (\n ...nodes: Array\n ): void {\n const parent = this.parentNode\n if (parent) {\n if (nodes.length === 0)\n parent.removeChild(this)\n\n /* Replace children and create text nodes */\n for (let i = nodes.length - 1; i >= 0; i--) {\n let node = nodes[i]\n if (typeof node !== \"object\")\n node = document.createTextNode(node)\n else if (node.parentNode)\n node.parentNode.removeChild(node)\n\n /* Replace child or insert before previous sibling */\n if (!i)\n parent.replaceChild(node, this)\n else\n parent.insertBefore(this.previousSibling!, node)\n }\n }\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport escapeHTML from \"escape-html\"\n\nimport { SearchIndexDocument } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search document\n */\nexport interface SearchDocument extends SearchIndexDocument {\n parent?: SearchIndexDocument /* Parent article */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search document mapping\n */\nexport type SearchDocumentMap = Map\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Create a search document mapping\n *\n * @param docs - Search index documents\n *\n * @returns Search document map\n */\nexport function setupSearchDocumentMap(\n docs: SearchIndexDocument[]\n): SearchDocumentMap {\n const documents = new Map()\n const parents = new Set()\n for (const doc of docs) {\n const [path, hash] = doc.location.split(\"#\")\n\n /* Extract location, title and tags */\n const location = doc.location\n const title = doc.title\n const tags = doc.tags\n\n /* Escape and cleanup text */\n const text = escapeHTML(doc.text)\n .replace(/\\s+(?=[,.:;!?])/g, \"\")\n .replace(/\\s+/g, \" \")\n\n /* Handle section */\n if (hash) {\n const parent = documents.get(path)!\n\n /* Ignore first section, override article */\n if (!parents.has(parent)) {\n parent.title = doc.title\n parent.text = text\n\n /* Remember that we processed the article */\n parents.add(parent)\n\n /* Add subsequent section */\n } else {\n documents.set(location, {\n location,\n title,\n text,\n parent\n })\n }\n\n /* Add article */\n } else {\n documents.set(location, {\n location,\n title,\n text,\n ...tags && { tags }\n })\n }\n }\n return documents\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport escapeHTML from \"escape-html\"\n\nimport { SearchIndexConfig } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search highlight function\n *\n * @param value - Value\n *\n * @returns Highlighted value\n */\nexport type SearchHighlightFn = (value: string) => string\n\n/**\n * Search highlight factory function\n *\n * @param query - Query value\n *\n * @returns Search highlight function\n */\nexport type SearchHighlightFactoryFn = (query: string) => SearchHighlightFn\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Create a search highlighter\n *\n * @param config - Search index configuration\n * @param escape - Whether to escape HTML\n *\n * @returns Search highlight factory function\n */\nexport function setupSearchHighlighter(\n config: SearchIndexConfig, escape: boolean\n): SearchHighlightFactoryFn {\n const separator = new RegExp(config.separator, \"img\")\n const highlight = (_: unknown, data: string, term: string) => {\n return `${data}${term}`\n }\n\n /* Return factory function */\n return (query: string) => {\n query = query\n .replace(/[\\s*+\\-:~^]+/g, \" \")\n .trim()\n\n /* Create search term match expression */\n const match = new RegExp(`(^|${config.separator})(${\n query\n .replace(/[|\\\\{}()[\\]^$+*?.-]/g, \"\\\\$&\")\n .replace(separator, \"|\")\n })`, \"img\")\n\n /* Highlight string value */\n return value => (\n escape\n ? escapeHTML(value)\n : value\n )\n .replace(match, highlight)\n .replace(/<\\/mark>(\\s+)]*>/img, \"$1\")\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search query clause\n */\nexport interface SearchQueryClause {\n presence: lunr.Query.presence /* Clause presence */\n term: string /* Clause term */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search query terms\n */\nexport type SearchQueryTerms = Record\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Parse a search query for analysis\n *\n * @param value - Query value\n *\n * @returns Search query clauses\n */\nexport function parseSearchQuery(\n value: string\n): SearchQueryClause[] {\n const query = new (lunr as any).Query([\"title\", \"text\"])\n const parser = new (lunr as any).QueryParser(value, query)\n\n /* Parse and return query clauses */\n parser.parse()\n return query.clauses\n}\n\n/**\n * Analyze the search query clauses in regard to the search terms found\n *\n * @param query - Search query clauses\n * @param terms - Search terms\n *\n * @returns Search query terms\n */\nexport function getSearchQueryTerms(\n query: SearchQueryClause[], terms: string[]\n): SearchQueryTerms {\n const clauses = new Set(query)\n\n /* Match query clauses against terms */\n const result: SearchQueryTerms = {}\n for (let t = 0; t < terms.length; t++)\n for (const clause of clauses)\n if (terms[t].startsWith(clause.term)) {\n result[clause.term] = true\n clauses.delete(clause)\n }\n\n /* Annotate unmatched non-stopword query clauses */\n for (const clause of clauses)\n if (lunr.stopWordFilter?.(clause.term as any))\n result[clause.term] = false\n\n /* Return query terms */\n return result\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n SearchDocument,\n SearchDocumentMap,\n setupSearchDocumentMap\n} from \"../document\"\nimport {\n SearchHighlightFactoryFn,\n setupSearchHighlighter\n} from \"../highlighter\"\nimport { SearchOptions } from \"../options\"\nimport {\n SearchQueryTerms,\n getSearchQueryTerms,\n parseSearchQuery\n} from \"../query\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search index configuration\n */\nexport interface SearchIndexConfig {\n lang: string[] /* Search languages */\n separator: string /* Search separator */\n}\n\n/**\n * Search index document\n */\nexport interface SearchIndexDocument {\n location: string /* Document location */\n title: string /* Document title */\n text: string /* Document text */\n tags?: string[] /* Document tags */\n boost?: number /* Document boost */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search index\n *\n * This interfaces describes the format of the `search_index.json` file which\n * is automatically built by the MkDocs search plugin.\n */\nexport interface SearchIndex {\n config: SearchIndexConfig /* Search index configuration */\n docs: SearchIndexDocument[] /* Search index documents */\n options: SearchOptions /* Search options */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search metadata\n */\nexport interface SearchMetadata {\n score: number /* Score (relevance) */\n terms: SearchQueryTerms /* Search query terms */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search result document\n */\nexport type SearchResultDocument = SearchDocument & SearchMetadata\n\n/**\n * Search result item\n */\nexport type SearchResultItem = SearchResultDocument[]\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search result\n */\nexport interface SearchResult {\n items: SearchResultItem[] /* Search result items */\n suggestions?: string[] /* Search suggestions */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Compute the difference of two lists of strings\n *\n * @param a - 1st list of strings\n * @param b - 2nd list of strings\n *\n * @returns Difference\n */\nfunction difference(a: string[], b: string[]): string[] {\n const [x, y] = [new Set(a), new Set(b)]\n return [\n ...new Set([...x].filter(value => !y.has(value)))\n ]\n}\n\n/* ----------------------------------------------------------------------------\n * Class\n * ------------------------------------------------------------------------- */\n\n/**\n * Search index\n */\nexport class Search {\n\n /**\n * Search document mapping\n *\n * A mapping of URLs (including hash fragments) to the actual articles and\n * sections of the documentation. The search document mapping must be created\n * regardless of whether the index was prebuilt or not, as Lunr.js itself\n * only stores the actual index.\n */\n protected documents: SearchDocumentMap\n\n /**\n * Search highlight factory function\n */\n protected highlight: SearchHighlightFactoryFn\n\n /**\n * The underlying Lunr.js search index\n */\n protected index: lunr.Index\n\n /**\n * Search options\n */\n protected options: SearchOptions\n\n /**\n * Create the search integration\n *\n * @param data - Search index\n */\n public constructor({ config, docs, options }: SearchIndex) {\n this.options = options\n\n /* Set up document map and highlighter factory */\n this.documents = setupSearchDocumentMap(docs)\n this.highlight = setupSearchHighlighter(config, false)\n\n /* Set separator for tokenizer */\n lunr.tokenizer.separator = new RegExp(config.separator)\n\n /* Create search index */\n this.index = lunr(function () {\n\n /* Set up multi-language support */\n if (config.lang.length === 1 && config.lang[0] !== \"en\") {\n this.use((lunr as any)[config.lang[0]])\n } else if (config.lang.length > 1) {\n this.use((lunr as any).multiLanguage(...config.lang))\n }\n\n /* Compute functions to be removed from the pipeline */\n const fns = difference([\n \"trimmer\", \"stopWordFilter\", \"stemmer\"\n ], options.pipeline)\n\n /* Remove functions from the pipeline for registered languages */\n for (const lang of config.lang.map(language => (\n language === \"en\" ? lunr : (lunr as any)[language]\n ))) {\n for (const fn of fns) {\n this.pipeline.remove(lang[fn])\n this.searchPipeline.remove(lang[fn])\n }\n }\n\n /* Set up reference */\n this.ref(\"location\")\n\n /* Set up fields */\n this.field(\"title\", { boost: 1e3 })\n this.field(\"text\")\n this.field(\"tags\", { boost: 1e6, extractor: doc => {\n const { tags = [] } = doc as SearchDocument\n return tags.reduce((list, tag) => [\n ...list,\n ...lunr.tokenizer(tag)\n ], [] as lunr.Token[])\n } })\n\n /* Index documents */\n for (const doc of docs)\n this.add(doc, { boost: doc.boost })\n })\n }\n\n /**\n * Search for matching documents\n *\n * The search index which MkDocs provides is divided up into articles, which\n * contain the whole content of the individual pages, and sections, which only\n * contain the contents of the subsections obtained by breaking the individual\n * pages up at `h1` ... `h6`. As there may be many sections on different pages\n * with identical titles (for example within this very project, e.g. \"Usage\"\n * or \"Installation\"), they need to be put into the context of the containing\n * page. For this reason, section results are grouped within their respective\n * articles which are the top-level results that are returned.\n *\n * @param query - Query value\n *\n * @returns Search results\n */\n public search(query: string): SearchResult {\n if (query) {\n try {\n const highlight = this.highlight(query)\n\n /* Parse query to extract clauses for analysis */\n const clauses = parseSearchQuery(query)\n .filter(clause => (\n clause.presence !== lunr.Query.presence.PROHIBITED\n ))\n\n /* Perform search and post-process results */\n const groups = this.index.search(`${query}*`)\n\n /* Apply post-query boosts based on title and search query terms */\n .reduce((item, { ref, score, matchData }) => {\n const document = this.documents.get(ref)\n if (typeof document !== \"undefined\") {\n const { location, title, text, tags, parent } = document\n\n /* Compute and analyze search query terms */\n const terms = getSearchQueryTerms(\n clauses,\n Object.keys(matchData.metadata)\n )\n\n /* Highlight title and text and apply post-query boosts */\n const boost = +!parent + +Object.values(terms).every(t => t)\n item.push({\n location,\n title: highlight(title),\n text: highlight(text),\n ...tags && { tags: tags.map(highlight) },\n score: score * (1 + boost),\n terms\n })\n }\n return item\n }, [])\n\n /* Sort search results again after applying boosts */\n .sort((a, b) => b.score - a.score)\n\n /* Group search results by page */\n .reduce((items, result) => {\n const document = this.documents.get(result.location)\n if (typeof document !== \"undefined\") {\n const ref = \"parent\" in document\n ? document.parent!.location\n : document.location\n items.set(ref, [...items.get(ref) || [], result])\n }\n return items\n }, new Map())\n\n /* Generate search suggestions, if desired */\n let suggestions: string[] | undefined\n if (this.options.suggestions) {\n const titles = this.index.query(builder => {\n for (const clause of clauses)\n builder.term(clause.term, {\n fields: [\"title\"],\n presence: lunr.Query.presence.REQUIRED,\n wildcard: lunr.Query.wildcard.TRAILING\n })\n })\n\n /* Retrieve suggestions for best match */\n suggestions = titles.length\n ? Object.keys(titles[0].matchData.metadata)\n : []\n }\n\n /* Return items and suggestions */\n return {\n items: [...groups.values()],\n ...typeof suggestions !== \"undefined\" && { suggestions }\n }\n\n /* Log errors to console (for now) */\n } catch {\n console.warn(`Invalid query: ${query} \u2013 see https://bit.ly/2s3ChXG`)\n }\n }\n\n /* Return nothing in case of error or empty query */\n return { items: [] }\n }\n}\n"], + "mappings": "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L,CAAI,KACrDD,EAAIC,EAER,CAEA,OAAAG,EAAKP,EACLQ,EAAMzB,EACFwB,EAAG,KAAKJ,CAAC,GAAKK,EAAI,KAAKL,CAAC,IAC1BI,EAAKjB,EACLa,EAAIA,EAAE,QAAQI,EAAG,EAAE,GAKjBD,GAAW,MACbH,EAAIG,EAAQ,YAAY,EAAIH,EAAE,OAAO,CAAC,GAGjCA,CACT,EAEA,OAAO,SAAUhD,EAAO,CACtB,OAAOA,EAAM,OAAO+C,CAAa,CACnC,CACF,EAAG,EAEHpG,EAAK,SAAS,iBAAiBA,EAAK,QAAS,SAAS,EACtD;AAAA;AAAA;AAAA,GAkBAA,EAAK,uBAAyB,SAAU8G,EAAW,CACjD,IAAIC,EAAQD,EAAU,OAAO,SAAU7D,EAAM+D,EAAU,CACrD,OAAA/D,EAAK+D,GAAYA,EACV/D,CACT,EAAG,CAAC,CAAC,EAEL,OAAO,SAAUI,EAAO,CACtB,GAAIA,GAAS0D,EAAM1D,EAAM,SAAS,KAAOA,EAAM,SAAS,EAAG,OAAOA,CACpE,CACF,EAeArD,EAAK,eAAiBA,EAAK,uBAAuB,CAChD,IACA,OACA,QACA,SACA,QACA,MACA,SACA,OACA,KACA,QACA,KACA,MACA,MACA,MACA,KACA,KACA,KACA,UACA,OACA,MACA,KACA,MACA,SACA,QACA,OACA,MACA,KACA,OACA,SACA,OACA,OACA,QACA,MACA,OACA,MACA,MACA,MACA,MACA,OACA,KACA,MACA,OACA,MACA,MACA,MACA,UACA,IACA,KACA,KACA,OACA,KACA,KACA,MACA,OACA,QACA,MACA,OACA,SACA,MACA,KACA,QACA,OACA,OACA,KACA,UACA,KACA,MACA,MACA,KACA,MACA,QACA,KACA,OACA,KACA,QACA,MACA,MACA,SACA,OACA,MACA,OACA,MACA,SACA,QACA,KACA,OACA,OACA,OACA,MACA,QACA,OACA,OACA,QACA,QACA,OACA,OACA,MACA,KACA,MACA,OACA,KACA,QACA,MACA,KACA,OACA,OACA,OACA,QACA,QACA,QACA,MACA,OACA,MACA,OACA,OACA,QACA,MACA,MACA,MACF,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", + "names": ["require_lunr", "__commonJSMin", "exports", "module", "lunr", "config", "builder", "global", "message", "obj", "clone", "keys", "key", "val", "docRef", "fieldName", "stringValue", "s", "n", "fieldRef", "elements", "i", "other", "object", "a", "b", "intersection", "element", "posting", "documentCount", "documentsWithTerm", "x", "str", "metadata", "fn", "t", "len", "tokens", "sliceEnd", "sliceStart", "char", "sliceLength", "tokenMetadata", "label", "isRegistered", "serialised", "pipeline", "fnName", "fns", "existingFn", "newFn", "pos", "stackLength", "memo", "j", "result", "k", "token", "index", "start", "end", "pivotPoint", "pivotIndex", "insertIdx", "position", "sumOfSquares", "elementsLength", "otherVector", "dotProduct", "aLen", "bLen", "aVal", "bVal", "output", "step2list", "step3list", "c", "v", "C", "V", "mgr0", "meq1", "mgr1", "s_v", "re_mgr0", "re_mgr1", "re_meq1", "re_s_v", "re_1a", "re2_1a", "re_1b", "re2_1b", "re_1b_2", "re2_1b_2", "re3_1b_2", "re4_1b_2", "re_1c", "re_2", "re_3", "re_4", "re2_4", "re_5", "re_5_1", "re3_5", "porterStemmer", "w", "stem", "suffix", "firstch", "re", "re2", "re3", "re4", "fp", "stopWords", "words", "stopWord", "arr", "clause", "editDistance", "root", "stack", "frame", "noEditNode", "insertionNode", "substitutionNode", "charA", "charB", "transposeNode", "node", "final", "next", "edges", "edge", "labels", "qEdges", "qLen", "nEdges", "nLen", "q", "qEdge", "nEdge", "qNode", "word", "commonPrefix", "nextNode", "downTo", "childKey", "attrs", "queryString", "query", "parser", "matchingFields", "queryVectors", "termFieldCache", "requiredMatches", "prohibitedMatches", "terms", "clauseMatches", "m", "term", "termTokenSet", "expandedTerms", "field", "expandedTerm", "termIndex", "fieldPosting", "matchingDocumentRefs", "termField", "matchingDocumentsSet", "l", "matchingDocumentRef", "matchingFieldRef", "fieldMatch", "allRequiredMatches", "allProhibitedMatches", "matchingFieldRefs", "results", "matches", "fieldVector", "score", "docMatch", "match", "invertedIndex", "fieldVectors", "ref", "serializedIndex", "serializedVectors", "serializedInvertedIndex", "tokenSetBuilder", "tuple", "attributes", "number", "doc", "fields", "extractor", "fieldTerms", "metadataKey", "fieldRefs", "numberOfFields", "accumulator", "documentsWithField", "fieldRefsLength", "termIdfCache", "fieldLength", "termFrequencies", "termsLength", "fieldBoost", "docBoost", "tf", "idf", "scoreWithPrecision", "args", "clonedMetadata", "metadataKeys", "otherMatchData", "allFields", "options", "state", "subSlices", "type", "charCode", "lexer", "lexeme", "completedClause", "errorMessage", "nextLexeme", "possibleFields", "f", "boost", "factory", "require_escape_html", "__commonJSMin", "exports", "module", "matchHtmlRegExp", "escapeHtml", "string", "str", "match", "escape", "html", "index", "lastIndex", "import_lunr", "obj", "data", "key", "x", "y", "nodes", "parent", "i", "node", "import_escape_html", "setupSearchDocumentMap", "docs", "documents", "parents", "doc", "path", "hash", "location", "title", "tags", "text", "escapeHTML", "parent", "__spreadValues", "import_escape_html", "setupSearchHighlighter", "config", "escape", "separator", "highlight", "_", "data", "term", "query", "match", "value", "escapeHTML", "parseSearchQuery", "value", "query", "getSearchQueryTerms", "terms", "_a", "clauses", "result", "t", "clause", "difference", "a", "b", "x", "y", "value", "Search", "config", "docs", "options", "setupSearchDocumentMap", "setupSearchHighlighter", "fns", "lang", "language", "fn", "doc", "tags", "list", "tag", "query", "highlight", "clauses", "parseSearchQuery", "clause", "groups", "item", "ref", "score", "matchData", "document", "location", "title", "text", "parent", "terms", "getSearchQueryTerms", "boost", "t", "__spreadProps", "__spreadValues", "items", "result", "suggestions", "titles", "builder", "e", "index", "setupSearchLanguages", "config", "__async", "base", "worker", "path", "scripts", "lang", "handler", "message", "Search", "lunr", "ev"] +} diff --git a/assets/launch-process-thumb.png b/assets/launch-process-thumb.png new file mode 100644 index 000000000..57279f3c8 Binary files /dev/null and b/assets/launch-process-thumb.png differ diff --git a/assets/launch-process.png b/assets/launch-process.png new file mode 100644 index 000000000..c9ceb8907 Binary files /dev/null and b/assets/launch-process.png differ diff --git a/assets/logo-C2FLR.png b/assets/logo-C2FLR.png new file mode 100644 index 000000000..8cee8ed5c Binary files /dev/null and b/assets/logo-C2FLR.png differ diff --git a/assets/logo-CFLR.png b/assets/logo-CFLR.png new file mode 100644 index 000000000..3612d73f0 Binary files /dev/null and b/assets/logo-CFLR.png differ diff --git a/assets/logo-FLR.png b/assets/logo-FLR.png new file mode 100644 index 000000000..12b255eff Binary files /dev/null and b/assets/logo-FLR.png differ diff --git a/assets/logo-SGB.png b/assets/logo-SGB.png new file mode 100644 index 000000000..3ea90b0c7 Binary files /dev/null and b/assets/logo-SGB.png differ diff --git a/assets/overrides/404.html b/assets/overrides/404.html new file mode 100644 index 000000000..024343d02 --- /dev/null +++ b/assets/overrides/404.html @@ -0,0 +1,4 @@ + +Redirecting... \ No newline at end of file diff --git a/assets/overrides/api-icon.svg b/assets/overrides/api-icon.svg new file mode 100644 index 000000000..ee5792677 --- /dev/null +++ b/assets/overrides/api-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/overrides/dev-icon.svg b/assets/overrides/dev-icon.svg new file mode 100644 index 000000000..072826083 --- /dev/null +++ b/assets/overrides/dev-icon.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/assets/overrides/exchange-icon.svg b/assets/overrides/exchange-icon.svg new file mode 100644 index 000000000..86b54447e --- /dev/null +++ b/assets/overrides/exchange-icon.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/overrides/infra-icon.svg b/assets/overrides/infra-icon.svg new file mode 100644 index 000000000..190843e43 --- /dev/null +++ b/assets/overrides/infra-icon.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/overrides/logo.svg b/assets/overrides/logo.svg new file mode 100644 index 000000000..e5c6fb447 --- /dev/null +++ b/assets/overrides/logo.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/overrides/main.html b/assets/overrides/main.html new file mode 100644 index 000000000..a5ebc3229 --- /dev/null +++ b/assets/overrides/main.html @@ -0,0 +1,22 @@ +{% extends "base.html" %} + +{% block extrahead %} + {{ super() }} + {% if page and page.meta and page.meta.og_image %} + + + + + + + {% endif %} +{% endblock %} + +{% block content %} + {% if page.meta.section_icon %} +

    + {% include page.meta.section_icon %} +

    + {% endif %} + {{ super() }} +{% endblock %} diff --git a/assets/overrides/partials/copyright.html b/assets/overrides/partials/copyright.html new file mode 100644 index 000000000..213e374a7 --- /dev/null +++ b/assets/overrides/partials/copyright.html @@ -0,0 +1,41 @@ + + + + \ No newline at end of file diff --git a/assets/overrides/partials/footer.html b/assets/overrides/partials/footer.html new file mode 100644 index 000000000..d62eb4b1d --- /dev/null +++ b/assets/overrides/partials/footer.html @@ -0,0 +1,13 @@ +
    + + +
    \ No newline at end of file diff --git a/assets/overrides/partials/logo.html b/assets/overrides/partials/logo.html new file mode 100644 index 000000000..fdeb629d6 --- /dev/null +++ b/assets/overrides/partials/logo.html @@ -0,0 +1,6 @@ +{% if config.theme.logo %} + {% include config.theme.logo %} +{% else %} + {% set icon = config.theme.icon.logo or "material/library" %} + {% include ".icons/" ~ icon ~ ".svg" %} +{% endif %} diff --git a/assets/overrides/tech-icon.svg b/assets/overrides/tech-icon.svg new file mode 100644 index 000000000..f14eacf80 --- /dev/null +++ b/assets/overrides/tech-icon.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/overrides/user-icon.svg b/assets/overrides/user-icon.svg new file mode 100644 index 000000000..52f385041 --- /dev/null +++ b/assets/overrides/user-icon.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/pda-enabled.png b/assets/pda-enabled.png new file mode 100644 index 000000000..14120c648 Binary files /dev/null and b/assets/pda-enabled.png differ diff --git a/assets/pda-faqs-enable.png b/assets/pda-faqs-enable.png new file mode 100644 index 000000000..c0020db39 Binary files /dev/null and b/assets/pda-faqs-enable.png differ diff --git a/assets/pda-main-account-opens.png b/assets/pda-main-account-opens.png new file mode 100644 index 000000000..814281fa6 Binary files /dev/null and b/assets/pda-main-account-opens.png differ diff --git a/assets/pda-user-delegation-account.png b/assets/pda-user-delegation-account.png new file mode 100644 index 000000000..39268b617 Binary files /dev/null and b/assets/pda-user-delegation-account.png differ diff --git a/assets/price-history-dashboard.png b/assets/price-history-dashboard.png new file mode 100644 index 000000000..81f8f2d6f Binary files /dev/null and b/assets/price-history-dashboard.png differ diff --git a/assets/price-history-providers.png b/assets/price-history-providers.png new file mode 100644 index 000000000..573d6a646 Binary files /dev/null and b/assets/price-history-providers.png differ diff --git a/assets/price-history-sgb-providers.png b/assets/price-history-sgb-providers.png new file mode 100644 index 000000000..3131ba357 Binary files /dev/null and b/assets/price-history-sgb-providers.png differ diff --git a/assets/price-history.png b/assets/price-history.png new file mode 100644 index 000000000..36fce0c05 Binary files /dev/null and b/assets/price-history.png differ diff --git a/assets/rewards-portal-claim.png b/assets/rewards-portal-claim.png new file mode 100644 index 000000000..5f3a70ad7 Binary files /dev/null and b/assets/rewards-portal-claim.png differ diff --git a/assets/safepal-songbird-logo.png b/assets/safepal-songbird-logo.png new file mode 100644 index 000000000..578389761 Binary files /dev/null and b/assets/safepal-songbird-logo.png differ diff --git a/assets/stylesheets/extra.css b/assets/stylesheets/extra.css new file mode 100644 index 000000000..9e4ed902c --- /dev/null +++ b/assets/stylesheets/extra.css @@ -0,0 +1,480 @@ +/* Define Flare's colors */ +:root>* { + --md-accent-fg-color: #d3385b; + --md-accent-fg-color--transparent: #d3385b40; + --md-default-fg-color--light: #222; + --md-default-fg-color--lightest: #eee; + --md-footer-bg-color--dark: var(--md-default-fg-color--lightest); + --md-footer-fg-color--light: var(--md-primary-bg-color); + --md-footer-fg-color--lighter: var(--md-primary-bg-color--light); + --md-typeset-a-color: var(--md-primary-bg-color); + --md-code-bg-color--transparent: var(--md-code-bg-color); + --md-code-hl-color: var(--md-accent-fg-color--transparent); + --md-code-hl-comment-color: darkseagreen; +} + +[data-md-color-scheme="flaredark"] { + --md-default-bg-color: #222; + --md-default-fg-color: white; + --md-default-fg-color--light: white; + --md-default-fg-color--lighter: #555; + --md-default-fg-color--lightest: #444; + --md-primary-fg-color: #222; + --md-primary-fg-color--light: #333; + --md-primary-fg-color--dark: #111; + --md-primary-bg-color: #bbb; + --md-primary-bg-color--light: #888; + --md-typeset-color: var(--md-primary-bg-color); + --md-typeset-a-color: var(--md-primary-bg-color); + /* Code highlighting color shades */ + --md-code-bg-color: black; + --md-code-bg-color--transparent: #0004; + --md-code-fg-color: var(--md-primary-bg-color--light); + --md-code-hl-operator-color: var(--md-default-fg-color--light); + --md-code-hl-punctuation-color: var(--md-default-fg-color--light); + --md-code-hl-name-color: var(--md-code-fg-color); + --md-code-hl-generic-color: var(--md-default-fg-color--light); + --md-code-hl-variable-color: var(--md-default-fg-color--light); +} + +/* Remove shadow under header */ +.md-header { + box-shadow: none; +} + +/* Logo and title: color and alignment */ +.md-header__title, +.md-logo { + line-height: 2.8rem; + color: var(--md-default-fg-color); +} + +/* Cookie consent buttons */ +.md-typeset .md-button { + background-color: var(--md-accent-fg-color); + color: var(--md-default-bg-color); +} + +/* Back to top button */ +.md-top { + background: var(--md-default-fg-color--lightest); +} + +/* Run-me admonition type */ +:root { + --md-admonition-icon--run-me: url('data:image/svg+xml;charset=utf-8,') +} + +.md-typeset .admonition.run-me, +.md-typeset details.run-me { + border-color: #d3385b; +} + +.md-typeset .run-me>.admonition-title, +.md-typeset .run-me>summary { + background-color: #d3385b55; +} + +.md-typeset .run-me>.admonition-title::before, +.md-typeset .run-me>summary::before { + background-color: #d3385b; + -webkit-mask-image: var(--md-admonition-icon--run-me); + mask-image: var(--md-admonition-icon--run-me); +} + +/* Restore admonition and details text size and colors */ +.md-typeset :is(.admonition, details) { + font-size: initial; + background-color: var(--md-default-bg-color--lightest); + color: var(--md-typeset-color); +} +.md-typeset :is(.admonition-title, summary) { + color: var(--md-default-fg-color); +} +/* Remove little extra margin when admonitions are inside lists */ +.md-typeset li .admonition-title { + margin-top: 0 !important; +} +/* Custom borderless admonition, just to help position images. Use with: */ +/* !!! image inline end "" */ +.md-typeset .admonition.image, +.md-typeset details.image { + border: 0; + box-shadow: none; +} +/* Slightly darker admonition headers */ +.md-typeset :is(.note) > :is(.admonition-title, summary) { + background-color: #448AFF55; +} +.md-typeset :is(.tip, .important) > :is(.admonition-title, summary) { + background-color: #00BFA555; +} +.md-typeset :is(.caution, .warning, .attention) > :is(.admonition-title, summary) { + background-color: #FF910055; +} +.md-typeset :is(.danger)> :is(.admonition-title, summary) { + background-color: #FF174455; +} +.md-typeset :is(.info)> :is(.admonition-title, summary) { + background-color: #00B8D455; +} +.md-typeset :is(.example)> :is(.admonition-title, summary) { + background-color: #7D4CFF55; +} + +/* Hide the GitHub link at the top, it's not that interesting */ +.md-header__source, +.md-nav__source { + display: none; +} + +/* Underline links in the main text. Our primary color is too close + * to the regular text color and links are invisible. */ +.md-typeset a { + text-decoration: underline; + text-decoration-color: var(--md-default-fg-color--lighter); +} + +/* Do not underline the permalinks in the headers */ +.headerlink { + text-decoration: none !important; +} + +/* Glossary */ +dt { + color: var(--md-primary-bg-color); + font-weight: bold; + padding-left: 10px; +} + +dt:target { + background: var(--md-accent-fg-color--transparent); + border-radius: 4px; +} + +/* Glossary links */ +a[href*="/glossary/#"] { + text-decoration-style: dotted; + text-decoration-thickness: 1px; +} + +/* Enlarge Flare logo in the header */ +.md-header__button.md-logo { + padding: 0; +} + +.md-header__button.md-logo :-webkit-any(img, svg) { + height: 1.5rem; +} + +/* Side by side images */ +figure img.side-by-side { + display: inline; + width: 49%; +} + +/* API reference guide */ +.api-node { + margin-top: 8px; + padding-left: 8px; + padding-right: 8px; + border: solid 1px var(--md-default-fg-color--lightest); +} +.api-node-type h2 { + border-top: solid 4px var(--md-default-fg-color--lighter); + padding-top: 20px +} +.api-node h3 { + font-size: x-large; + margin: 0; + padding-top: 10px; +} +.api-node-internal td:first-child { + white-space: nowrap; +} +.api-node-source p { + text-align: right; + font-size: smaller; + color: var(--md-default-fg-color--lighter); + margin: 0; +} +.api-node-source a { + color: var(--md-default-fg-color--lighter); +} + +/* BETA tags + * Use as: `BETA`{.beta} */ +.md-typeset code.beta { + background-color: var(--md-accent-fg-color); + color: white; + border-radius: 0.3rem; +} + +/* Separating line for some nav links */ +.md-nav__item [href*="glossary/"], +.md-nav__item [href*="external-resources/"] { + border-top: solid 1px var(--md-default-fg-color--lightest); + padding-top: 8px; +} + +/* Separating line for the TOC titles (primary and secondary) */ +.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link, +.md-nav__title { + border-bottom: solid 1px var(--md-default-fg-color--lightest); + padding-bottom: 8px; +} + +/* Bold text for current page in TOC and TABS*/ +.md-nav--primary .md-nav__item .md-nav__link--active, +.md-nav--secondary .md-nav__item .md-nav__link--active, +.md-tabs__link--active { + font-weight: bold; + color: var(--md-default-fg-color); +} + +.md-tabs__item:has(.md-tabs__link--active) { + background: var(--md-default-bg-color); + border-radius: 10px 10px 0 0; +} + +/* Previous headers in the secondary TOC */ +.md-nav__link--passed { + color: var(--md-default-fg-color--lighter); +} + +/* Highlight header links on hover */ +.md-tabs__link:is(:focus, :hover), +.md-header__button:is(:focus, :hover) { + color: var(--md-accent-fg-color); +} + +/* Header separator line */ +.md-header .md-tabs { + border-bottom: 0; + background-color: var(--md-default-fg-color--lightest); +} + +.md-header { + background-color: var(--md-default-fg-color--lightest); +} + +/* Cards */ +.md-typeset .cards ul { + list-style: none; + display: flex; + flex-wrap: wrap; + justify-content: space-around; + margin-left: 0; + margin-top: 40px; +} + +.md-typeset .cards ul li { + border: 1px solid var(--md-default-fg-color--lightest); + border-radius: 16px; + width: 550px; + padding: 8px; + margin-left: 0; + transition: background 0.25s; + padding: 16px; +} + +.md-typeset .cards ul li:hover { + background: rgba(181, 78, 95, 0.2); + border: 1px solid var(--md-default-fg-color); +} + +.md-typeset .cards p { + margin: 0; +} + +.md-typeset .cards strong { + color: var(--md-accent-fg-color); +} + +.md-typeset .cards a { + text-decoration: none; + color: var(--md-primary-bg-color); +} + +.md-typeset .cards svg { + float: left; + margin-right: 16px; +} + +/* Recolor SVG icons in cards */ +.stroked-svg svg path, +.stroked-svg svg line, +.stroked-svg svg circle, +.stroked-svg svg ellipse { + stroke: var(--md-primary-bg-color); +} + +.filled-svg svg path, +.filled-svg svg line, +.filled-svg svg circle, +.filled-svg svg ellipse, +.filled-svg svg rect { + fill: var(--md-primary-bg-color); +} + +.big-svg { + text-align: center; +} + +.big-svg svg { + width: 25%; +} + +/* Images */ +.md-content figure { + background: white; + border-color: var(--md-default-fg-color--lighter); + border-width: 8px 1px 1px 1px; + border-style: solid; +} + +.md-content figure img { + padding: 8px; + margin: auto; +} + +.md-content figure figcaption { + background: var(--md-default-fg-color--lighter); + margin: 0; + padding-left: 8px; + padding-right: 8px; + max-width: 100%; +} + +.md-content figure figcaption p { + margin: 0; +} + +.md-content figure:hover { + border-color: var(--md-accent-fg-color); +} + +.md-content figure:hover figcaption { + background: var(--md-accent-fg-color); +} + +/* Tables */ +.md-typeset table:not([class]), +.md-typeset table:not([class]) td { + border-color: var(--md-default-fg-color--lightest); +} +.md-typeset table:not([class]) th { + background-color: var(--md-code-bg-color--transparent); +} + +/* Inline code blocks */ +.md-typeset code { + background: var(--md-code-bg-color--transparent); +} +.md-typeset pre code { + background: var(--md-code-bg-color); +} + +/* Custom admonition for Tools */ +:root { + --md-admonition-icon--tool: url('data:image/svg+xml;charset=utf-8,') +} + +.md-typeset .admonition.tool, +.md-typeset details.tooL { + border-color: #d3385b80; +} + +.md-typeset .tool>.admonition-title, +.md-typeset .tool>summary { + background-color: #d3385b40; +} + +.md-typeset .tool>.admonition-title::before, +.md-typeset .tool>summary::before { + background-color: #d3385b; + -webkit-mask-image: var(--md-admonition-icon--tool); + mask-image: var(--md-admonition-icon--tool); +} + +/* Tabbed boxes */ +.md-typeset .tabbed-labels>label { + color: var(--md-typeset-color); +} + +/* Important tables */ +.md-typeset .important-table table:not([class]) th, +.md-typeset .important-table table:not([class]) td { + font-size: large; + background: var(--md-code-bg-color); + vertical-align: middle; +} + +.important-table .md-typeset__scrollwrap { + margin-left: auto; + margin-right: auto; + width: fit-content; +} + +/* Footer links */ +.md-footer-meta.md-typeset a:hover { + color: var(--md-accent-fg-color) !important; +} + +/* Contract lists */ +#contract-list-results ul { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + list-style: none; + border: 1px solid var(--md-default-fg-color--lightest); + padding: 5px; + margin: 0; +} + +#contract-list-results ul li { + margin: 0; +} + +/* Boolean tables */ +.md-typeset .boolean-table .boolean-false { + color: red; + padding: 0; + font-size: x-large; + vertical-align: middle; +} +.md-typeset .boolean-table .boolean-true { + color: green; + padding: 0; + font-size: x-large; + vertical-align: middle; +} + +/* Generic horizontally-centered text */ +.center { + text-align: center; +} + +/* Source code license link after example code blocks */ +.source-code-license, +.source-code-license a { + text-align: right; + font-size: small; + color: var(--md-default-fg-color--lighter); + line-height: 0; +} + +/* More discreet line numbers in code blocks */ +.linenos span { + color: var(--md-primary-bg-color--light); +} + +/* Special format for tutorial steps */ +.tutorial h3 { + color: var(--md-code-hl-comment-color); +} +.tutorial h3:before { + content: "// "; +} +.highlight a .c1:hover { + color: var(--md-accent-fg-color); +} diff --git a/assets/stylesheets/main.69437709.min.css b/assets/stylesheets/main.69437709.min.css new file mode 100644 index 000000000..702d01386 --- /dev/null +++ b/assets/stylesheets/main.69437709.min.css @@ -0,0 +1 @@ +@charset "UTF-8";html{-webkit-text-size-adjust:none;-moz-text-size-adjust:none;-ms-text-size-adjust:none;text-size-adjust:none;box-sizing:border-box}*,:after,:before{box-sizing:inherit}@media (prefers-reduced-motion){*,:after,:before{transition:none!important}}body{margin:0}a,button,input,label{-webkit-tap-highlight-color:transparent}a{color:inherit;text-decoration:none}hr{border:0;box-sizing:initial;display:block;height:.05rem;overflow:visible;padding:0}small{font-size:80%}sub,sup{line-height:1em}img{border-style:none}table{border-collapse:initial;border-spacing:0}td,th{font-weight:400;vertical-align:top}button{background:transparent;border:0;font-family:inherit;font-size:inherit;margin:0;padding:0}input{border:0;outline:none}:root,[data-md-color-scheme=default]{--md-default-fg-color:rgba(0,0,0,.87);--md-default-fg-color--light:rgba(0,0,0,.54);--md-default-fg-color--lighter:rgba(0,0,0,.32);--md-default-fg-color--lightest:rgba(0,0,0,.07);--md-default-bg-color:#fff;--md-default-bg-color--light:hsla(0,0%,100%,.7);--md-default-bg-color--lighter:hsla(0,0%,100%,.3);--md-default-bg-color--lightest:hsla(0,0%,100%,.12);--md-primary-fg-color:#4051b5;--md-primary-fg-color--light:#5d6cc0;--md-primary-fg-color--dark:#303fa1;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7);--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:rgba(82,108,254,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7);--md-code-fg-color:#36464e;--md-code-bg-color:#f5f5f5;--md-code-hl-color:rgba(255,255,0,.5);--md-code-hl-number-color:#d52a2a;--md-code-hl-special-color:#db1457;--md-code-hl-function-color:#a846b9;--md-code-hl-constant-color:#6e59d9;--md-code-hl-keyword-color:#3f6ec6;--md-code-hl-string-color:#1c7d4d;--md-code-hl-name-color:var(--md-code-fg-color);--md-code-hl-operator-color:var(--md-default-fg-color--light);--md-code-hl-punctuation-color:var(--md-default-fg-color--light);--md-code-hl-comment-color:var(--md-default-fg-color--light);--md-code-hl-generic-color:var(--md-default-fg-color--light);--md-code-hl-variable-color:var(--md-default-fg-color--light);--md-typeset-color:var(--md-default-fg-color);--md-typeset-a-color:var(--md-primary-fg-color);--md-typeset-mark-color:rgba(255,255,0,.5);--md-typeset-del-color:rgba(245,80,61,.15);--md-typeset-ins-color:rgba(11,213,112,.15);--md-typeset-kbd-color:#fafafa;--md-typeset-kbd-accent-color:#fff;--md-typeset-kbd-border-color:#b8b8b8;--md-typeset-table-color:rgba(0,0,0,.12);--md-admonition-fg-color:var(--md-default-fg-color);--md-admonition-bg-color:var(--md-default-bg-color);--md-footer-fg-color:#fff;--md-footer-fg-color--light:hsla(0,0%,100%,.7);--md-footer-fg-color--lighter:hsla(0,0%,100%,.3);--md-footer-bg-color:rgba(0,0,0,.87);--md-footer-bg-color--dark:rgba(0,0,0,.32);--md-shadow-z1:0 0.2rem 0.5rem rgba(0,0,0,.05),0 0 0.05rem rgba(0,0,0,.1);--md-shadow-z2:0 0.2rem 0.5rem rgba(0,0,0,.1),0 0 0.05rem rgba(0,0,0,.25);--md-shadow-z3:0 0.2rem 0.5rem rgba(0,0,0,.2),0 0 0.05rem rgba(0,0,0,.35)}.md-icon svg{fill:currentcolor;display:block;height:1.2rem;width:1.2rem}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;--md-text-font-family:var(--md-text-font,_),-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif;--md-code-font-family:var(--md-code-font,_),SFMono-Regular,Consolas,Menlo,monospace}body,input{font-feature-settings:"kern","liga";font-family:var(--md-text-font-family)}body,code,input,kbd,pre{color:var(--md-typeset-color)}code,kbd,pre{font-feature-settings:"kern";font-family:var(--md-code-font-family)}:root{--md-typeset-table-sort-icon:url('data:image/svg+xml;charset=utf-8,');--md-typeset-table-sort-icon--asc:url('data:image/svg+xml;charset=utf-8,');--md-typeset-table-sort-icon--desc:url('data:image/svg+xml;charset=utf-8,')}.md-typeset{-webkit-print-color-adjust:exact;color-adjust:exact;font-size:.8rem;line-height:1.6}@media print{.md-typeset{font-size:.68rem}}.md-typeset blockquote,.md-typeset dl,.md-typeset figure,.md-typeset ol,.md-typeset pre,.md-typeset ul{margin-bottom:1em;margin-top:1em}.md-typeset h1{color:var(--md-default-fg-color--light);font-size:2em;line-height:1.3;margin:0 0 1.25em}.md-typeset h1,.md-typeset h2{font-weight:300;letter-spacing:-.01em}.md-typeset h2{font-size:1.5625em;line-height:1.4;margin:1.6em 0 .64em}.md-typeset h3{font-size:1.25em;font-weight:400;letter-spacing:-.01em;line-height:1.5;margin:1.6em 0 .8em}.md-typeset h2+h3{margin-top:.8em}.md-typeset h4{font-weight:700;letter-spacing:-.01em;margin:1em 0}.md-typeset h5,.md-typeset h6{color:var(--md-default-fg-color--light);font-size:.8em;font-weight:700;letter-spacing:-.01em;margin:1.25em 0}.md-typeset h5{text-transform:uppercase}.md-typeset hr{border-bottom:.05rem solid var(--md-default-fg-color--lightest);display:flow-root;margin:1.5em 0}.md-typeset a{color:var(--md-typeset-a-color);word-break:break-word}.md-typeset a,.md-typeset a:before{transition:color 125ms}.md-typeset a:focus,.md-typeset a:hover{color:var(--md-accent-fg-color)}.md-typeset a:focus code,.md-typeset a:hover code{background-color:var(--md-accent-fg-color--transparent)}.md-typeset a code{color:currentcolor;transition:background-color 125ms}.md-typeset a.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset code,.md-typeset kbd,.md-typeset pre{color:var(--md-code-fg-color);direction:ltr}@media print{.md-typeset code,.md-typeset kbd,.md-typeset pre{white-space:pre-wrap}}.md-typeset code{background-color:var(--md-code-bg-color);border-radius:.1rem;-webkit-box-decoration-break:clone;box-decoration-break:clone;font-size:.85em;padding:0 .2941176471em;word-break:break-word}.md-typeset code:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-typeset pre{display:flow-root;line-height:1.4;position:relative}.md-typeset pre>code{-webkit-box-decoration-break:slice;box-decoration-break:slice;box-shadow:none;display:block;margin:0;outline-color:var(--md-accent-fg-color);overflow:auto;padding:.7720588235em 1.1764705882em;scrollbar-color:var(--md-default-fg-color--lighter) transparent;scrollbar-width:thin;touch-action:auto;word-break:normal}.md-typeset pre>code:hover{scrollbar-color:var(--md-accent-fg-color) transparent}.md-typeset pre>code::-webkit-scrollbar{height:.2rem;width:.2rem}.md-typeset pre>code::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-typeset pre>code::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}.md-typeset kbd{background-color:var(--md-typeset-kbd-color);border-radius:.1rem;box-shadow:0 .1rem 0 .05rem var(--md-typeset-kbd-border-color),0 .1rem 0 var(--md-typeset-kbd-border-color),0 -.1rem .2rem var(--md-typeset-kbd-accent-color) inset;color:var(--md-default-fg-color);display:inline-block;font-size:.75em;padding:0 .6666666667em;vertical-align:text-top;word-break:break-word}.md-typeset mark{background-color:var(--md-typeset-mark-color);-webkit-box-decoration-break:clone;box-decoration-break:clone;color:inherit;word-break:break-word}.md-typeset abbr{border-bottom:.05rem dotted var(--md-default-fg-color--light);cursor:help;text-decoration:none}@media (hover:none){.md-typeset abbr{position:relative}.md-typeset abbr[title]:-webkit-any(:focus,:hover):after{background-color:var(--md-default-fg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z3);color:var(--md-default-bg-color);content:attr(title);display:inline-block;font-size:.7rem;margin-top:2em;max-width:80%;min-width:-webkit-max-content;min-width:max-content;padding:.2rem .3rem;position:absolute;width:auto}.md-typeset abbr[title]:-moz-any(:focus,:hover):after{background-color:var(--md-default-fg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z3);color:var(--md-default-bg-color);content:attr(title);display:inline-block;font-size:.7rem;margin-top:2em;max-width:80%;min-width:-moz-max-content;min-width:max-content;padding:.2rem .3rem;position:absolute;width:auto}[dir=ltr] .md-typeset abbr[title]:-webkit-any(:focus,:hover):after{left:0}[dir=ltr] .md-typeset abbr[title]:-moz-any(:focus,:hover):after{left:0}[dir=ltr] .md-typeset abbr[title]:is(:focus,:hover):after{left:0}[dir=rtl] .md-typeset abbr[title]:-webkit-any(:focus,:hover):after{right:0}[dir=rtl] .md-typeset abbr[title]:-moz-any(:focus,:hover):after{right:0}[dir=rtl] .md-typeset abbr[title]:is(:focus,:hover):after{right:0}.md-typeset abbr[title]:is(:focus,:hover):after{background-color:var(--md-default-fg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z3);color:var(--md-default-bg-color);content:attr(title);display:inline-block;font-size:.7rem;margin-top:2em;max-width:80%;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;padding:.2rem .3rem;position:absolute;width:auto}}.md-typeset small{opacity:.75}[dir=ltr] .md-typeset sub,[dir=ltr] .md-typeset sup{margin-left:.078125em}[dir=rtl] .md-typeset sub,[dir=rtl] .md-typeset sup{margin-right:.078125em}[dir=ltr] .md-typeset blockquote{padding-left:.6rem}[dir=rtl] .md-typeset blockquote{padding-right:.6rem}[dir=ltr] .md-typeset blockquote{border-left:.2rem solid var(--md-default-fg-color--lighter)}[dir=rtl] .md-typeset blockquote{border-right:.2rem solid var(--md-default-fg-color--lighter)}.md-typeset blockquote{color:var(--md-default-fg-color--light);margin-left:0;margin-right:0}.md-typeset ul{list-style-type:disc}[dir=ltr] .md-typeset ol,[dir=ltr] .md-typeset ul{margin-left:.625em}[dir=rtl] .md-typeset ol,[dir=rtl] .md-typeset ul{margin-right:.625em}.md-typeset ol,.md-typeset ul{padding:0}.md-typeset ol:not([hidden]),.md-typeset ul:not([hidden]){display:flow-root}.md-typeset ol ol,.md-typeset ul ol{list-style-type:lower-alpha}.md-typeset ol ol ol,.md-typeset ul ol ol{list-style-type:lower-roman}[dir=ltr] .md-typeset ol li,[dir=ltr] .md-typeset ul li{margin-left:1.25em}[dir=rtl] .md-typeset ol li,[dir=rtl] .md-typeset ul li{margin-right:1.25em}.md-typeset ol li,.md-typeset ul li{margin-bottom:.5em}.md-typeset ol li blockquote,.md-typeset ol li p,.md-typeset ul li blockquote,.md-typeset ul li p{margin:.5em 0}.md-typeset ol li:last-child,.md-typeset ul li:last-child{margin-bottom:0}.md-typeset ol li :-webkit-any(ul,ol),.md-typeset ul li :-webkit-any(ul,ol){margin-bottom:.5em;margin-top:.5em}.md-typeset ol li :-moz-any(ul,ol),.md-typeset ul li :-moz-any(ul,ol){margin-bottom:.5em;margin-top:.5em}[dir=ltr] .md-typeset ol li :-webkit-any(ul,ol),[dir=ltr] .md-typeset ul li :-webkit-any(ul,ol){margin-left:.625em}[dir=ltr] .md-typeset ol li :-moz-any(ul,ol),[dir=ltr] .md-typeset ul li :-moz-any(ul,ol){margin-left:.625em}[dir=ltr] .md-typeset ol li :is(ul,ol),[dir=ltr] .md-typeset ul li :is(ul,ol){margin-left:.625em}[dir=rtl] .md-typeset ol li :-webkit-any(ul,ol),[dir=rtl] .md-typeset ul li :-webkit-any(ul,ol){margin-right:.625em}[dir=rtl] .md-typeset ol li :-moz-any(ul,ol),[dir=rtl] .md-typeset ul li :-moz-any(ul,ol){margin-right:.625em}[dir=rtl] .md-typeset ol li :is(ul,ol),[dir=rtl] .md-typeset ul li :is(ul,ol){margin-right:.625em}.md-typeset ol li :is(ul,ol),.md-typeset ul li :is(ul,ol){margin-bottom:.5em;margin-top:.5em}[dir=ltr] .md-typeset dd{margin-left:1.875em}[dir=rtl] .md-typeset dd{margin-right:1.875em}.md-typeset dd{margin-bottom:1.5em;margin-top:1em}.md-typeset img,.md-typeset svg,.md-typeset video{height:auto;max-width:100%}.md-typeset img[align=left]{margin:1em 1em 1em 0}.md-typeset img[align=right]{margin:1em 0 1em 1em}.md-typeset img[align]:only-child{margin-top:0}.md-typeset img[src$="#gh-dark-mode-only"],.md-typeset img[src$="#only-dark"]{display:none}.md-typeset figure{display:flow-root;margin:1em auto;max-width:100%;text-align:center;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.md-typeset figure img{display:block}.md-typeset figcaption{font-style:italic;margin:1em auto;max-width:24rem}.md-typeset iframe{max-width:100%}.md-typeset table:not([class]){background-color:var(--md-default-bg-color);border:.05rem solid var(--md-typeset-table-color);border-radius:.1rem;display:inline-block;font-size:.64rem;max-width:100%;overflow:auto;touch-action:auto}@media print{.md-typeset table:not([class]){display:table}}.md-typeset table:not([class])+*{margin-top:1.5em}.md-typeset table:not([class]) :-webkit-any(th,td)>:first-child{margin-top:0}.md-typeset table:not([class]) :-moz-any(th,td)>:first-child{margin-top:0}.md-typeset table:not([class]) :is(th,td)>:first-child{margin-top:0}.md-typeset table:not([class]) :-webkit-any(th,td)>:last-child{margin-bottom:0}.md-typeset table:not([class]) :-moz-any(th,td)>:last-child{margin-bottom:0}.md-typeset table:not([class]) :is(th,td)>:last-child{margin-bottom:0}.md-typeset table:not([class]) :-webkit-any(th,td):not([align]){text-align:left}.md-typeset table:not([class]) :-moz-any(th,td):not([align]){text-align:left}.md-typeset table:not([class]) :is(th,td):not([align]){text-align:left}[dir=rtl] .md-typeset table:not([class]) :-webkit-any(th,td):not([align]){text-align:right}[dir=rtl] .md-typeset table:not([class]) :-moz-any(th,td):not([align]){text-align:right}[dir=rtl] .md-typeset table:not([class]) :is(th,td):not([align]){text-align:right}.md-typeset table:not([class]) th{font-weight:700;min-width:5rem;padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) th a{color:inherit}.md-typeset table:not([class]) td{border-top:.05rem solid var(--md-typeset-table-color);padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) tbody tr{transition:background-color 125ms}.md-typeset table:not([class]) tbody tr:hover{background-color:rgba(0,0,0,.035);box-shadow:0 .05rem 0 var(--md-default-bg-color) inset}.md-typeset table:not([class]) a{word-break:normal}.md-typeset table th[role=columnheader]{cursor:pointer}[dir=ltr] .md-typeset table th[role=columnheader]:after{margin-left:.5em}[dir=rtl] .md-typeset table th[role=columnheader]:after{margin-right:.5em}.md-typeset table th[role=columnheader]:after{content:"";display:inline-block;height:1.2em;-webkit-mask-image:var(--md-typeset-table-sort-icon);mask-image:var(--md-typeset-table-sort-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color 125ms;vertical-align:text-bottom;width:1.2em}.md-typeset table th[role=columnheader]:hover:after{background-color:var(--md-default-fg-color--lighter)}.md-typeset table th[role=columnheader][aria-sort=ascending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--asc);mask-image:var(--md-typeset-table-sort-icon--asc)}.md-typeset table th[role=columnheader][aria-sort=descending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--desc);mask-image:var(--md-typeset-table-sort-icon--desc)}.md-typeset__scrollwrap{margin:1em -.8rem;overflow-x:auto;touch-action:auto}.md-typeset__table{display:inline-block;margin-bottom:.5em;padding:0 .8rem}@media print{.md-typeset__table{display:block}}html .md-typeset__table table{display:table;margin:0;overflow:hidden;width:100%}@media screen and (max-width:44.9375em){.md-content__inner>pre{margin:1em -.8rem}.md-content__inner>pre code{border-radius:0}}.md-banner{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color);overflow:auto}@media print{.md-banner{display:none}}.md-banner--warning{background:var(--md-typeset-mark-color);color:var(--md-default-fg-color)}.md-banner__inner{font-size:.7rem;margin:.6rem auto;padding:0 .8rem}.md-banner__button{color:inherit;cursor:pointer;float:right;transition:opacity .25s}.md-banner__button:hover{opacity:.7}html{font-size:125%;height:100%;overflow-x:hidden}@media screen and (min-width:100em){html{font-size:137.5%}}@media screen and (min-width:125em){html{font-size:150%}}body{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;font-size:.5rem;min-height:100%;position:relative;width:100%}@media print{body{display:block}}@media screen and (max-width:59.9375em){body[data-md-scrolllock]{position:fixed}}.md-grid{margin-left:auto;margin-right:auto;max-width:61rem}.md-container{display:flex;flex-direction:column;flex-grow:1}@media print{.md-container{display:block}}.md-main{flex-grow:1}.md-main__inner{display:flex;height:100%;margin-top:1.5rem}.md-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.md-toggle{display:none}.md-option{height:0;opacity:0;position:absolute;width:0}.md-option:checked+label:not([hidden]){display:block}.md-option.focus-visible+label{outline-color:var(--md-accent-fg-color);outline-style:auto}.md-skip{background-color:var(--md-default-fg-color);border-radius:.1rem;color:var(--md-default-bg-color);font-size:.64rem;margin:.5rem;opacity:0;outline-color:var(--md-accent-fg-color);padding:.3rem .5rem;position:fixed;transform:translateY(.4rem);z-index:-1}.md-skip:focus{opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 175ms 75ms;z-index:10}@page{margin:25mm}:root{--md-clipboard-icon:url('data:image/svg+xml;charset=utf-8,')}.md-clipboard{border-radius:.1rem;color:var(--md-default-fg-color--lightest);cursor:pointer;height:1.5em;outline-color:var(--md-accent-fg-color);outline-offset:.1rem;position:absolute;right:.5em;top:.5em;transition:color .25s;width:1.5em;z-index:1}@media print{.md-clipboard{display:none}}.md-clipboard:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}:hover>.md-clipboard{color:var(--md-default-fg-color--light)}.md-clipboard:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-clipboard:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-clipboard:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-clipboard:after{background-color:currentcolor;content:"";display:block;height:1.125em;margin:0 auto;-webkit-mask-image:var(--md-clipboard-icon);mask-image:var(--md-clipboard-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:1.125em}.md-clipboard--inline{cursor:pointer}.md-clipboard--inline code{transition:color .25s,background-color .25s}.md-clipboard--inline:-webkit-any(:focus,:hover) code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-clipboard--inline:-moz-any(:focus,:hover) code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-clipboard--inline:is(:focus,:hover) code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}@-webkit-keyframes consent{0%{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}@keyframes consent{0%{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}@-webkit-keyframes overlay{0%{opacity:0}to{opacity:1}}@keyframes overlay{0%{opacity:0}to{opacity:1}}.md-consent__overlay{-webkit-animation:overlay .25s both;animation:overlay .25s both;-webkit-backdrop-filter:blur(.1rem);backdrop-filter:blur(.1rem);background-color:rgba(0,0,0,.54);height:100%;opacity:1;position:fixed;top:0;width:100%;z-index:5}.md-consent__inner{-webkit-animation:consent .5s cubic-bezier(.1,.7,.1,1) both;animation:consent .5s cubic-bezier(.1,.7,.1,1) both;background-color:var(--md-default-bg-color);border:0;border-radius:.1rem;bottom:0;box-shadow:0 0 .2rem rgba(0,0,0,.1),0 .2rem .4rem rgba(0,0,0,.2);max-height:100%;overflow:auto;padding:0;position:fixed;width:100%;z-index:5}.md-consent__form{padding:.8rem}.md-consent__settings{display:none;margin:1em 0}input:checked+.md-consent__settings{display:block}.md-consent__controls{margin-bottom:.8rem}.md-typeset .md-consent__controls .md-button{display:inline}@media screen and (max-width:44.9375em){.md-typeset .md-consent__controls .md-button{display:block;margin-top:.4rem;text-align:center;width:100%}}.md-consent label{cursor:pointer}.md-content{flex-grow:1;min-width:0}.md-content__inner{margin:0 .8rem 1.2rem;padding-top:.6rem}@media screen and (min-width:76.25em){[dir=ltr] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}[dir=ltr] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner,[dir=rtl] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-right:1.2rem}[dir=rtl] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}}.md-content__inner:before{content:"";display:block;height:.4rem}.md-content__inner>:last-child{margin-bottom:0}[dir=ltr] .md-content__button{margin-left:.4rem}[dir=rtl] .md-content__button{margin-right:.4rem}.md-content__button{float:right;margin:.4rem 0;padding:0}@media print{.md-content__button{display:none}}[dir=rtl] .md-content__button{float:left}.md-typeset .md-content__button{color:var(--md-default-fg-color--lighter)}.md-content__button svg{display:inline;vertical-align:top}[dir=rtl] .md-content__button svg{transform:scaleX(-1)}[dir=ltr] .md-dialog{right:.8rem}[dir=rtl] .md-dialog{left:.8rem}.md-dialog{background-color:var(--md-default-fg-color);border-radius:.1rem;bottom:.8rem;box-shadow:var(--md-shadow-z3);min-width:11.1rem;opacity:0;padding:.4rem .6rem;pointer-events:none;position:fixed;transform:translateY(100%);transition:transform 0ms .4s,opacity .4s;z-index:4}@media print{.md-dialog{display:none}}.md-dialog--active{opacity:1;pointer-events:auto;transform:translateY(0);transition:transform .4s cubic-bezier(.075,.85,.175,1),opacity .4s}.md-dialog__inner{color:var(--md-default-bg-color);font-size:.7rem}.md-feedback{margin:2em 0 1em;text-align:center}.md-feedback fieldset{border:none;margin:0;padding:0}.md-feedback__title{font-weight:700;margin:1em auto}.md-feedback__inner{position:relative}.md-feedback__list{align-content:baseline;display:flex;flex-wrap:wrap;justify-content:center;position:relative}.md-feedback__list:hover .md-icon:not(:disabled){color:var(--md-default-fg-color--lighter)}:disabled .md-feedback__list{min-height:1.8rem}.md-feedback__icon{color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;margin:0 .1rem;transition:color 125ms}.md-feedback__icon:not(:disabled).md-icon:hover{color:var(--md-accent-fg-color)}.md-feedback__icon:disabled{color:var(--md-default-fg-color--lightest);pointer-events:none}.md-feedback__note{opacity:0;position:relative;transform:translateY(.4rem);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s}.md-feedback__note>*{margin:0 auto;max-width:16rem}:disabled .md-feedback__note{opacity:1;transform:translateY(0)}.md-footer{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color)}@media print{.md-footer{display:none}}.md-footer__inner{justify-content:space-between;overflow:auto;padding:.2rem}.md-footer__inner:not([hidden]){display:flex}.md-footer__link{display:flex;flex-grow:0.01;outline-color:var(--md-accent-fg-color);overflow:hidden;padding-bottom:.4rem;padding-top:1.4rem;transition:opacity .25s}.md-footer__link:-webkit-any(:focus,:hover){opacity:.7}.md-footer__link:-moz-any(:focus,:hover){opacity:.7}.md-footer__link:is(:focus,:hover){opacity:.7}[dir=rtl] .md-footer__link svg{transform:scaleX(-1)}@media screen and (max-width:44.9375em){.md-footer__link--prev .md-footer__title{display:none}}[dir=ltr] .md-footer__link--next{margin-left:auto}[dir=rtl] .md-footer__link--next{margin-right:auto}.md-footer__link--next{text-align:right}[dir=rtl] .md-footer__link--next{text-align:left}.md-footer__title{flex-grow:1;font-size:.9rem;line-height:2.4rem;max-width:calc(100% - 2.4rem);padding:0 1rem;position:relative;white-space:nowrap}.md-footer__button{margin:.2rem;padding:.4rem}.md-footer__direction{font-size:.64rem;left:0;margin-top:-1rem;opacity:.7;padding:0 1rem;position:absolute;right:0}.md-footer-meta{background-color:var(--md-footer-bg-color--dark)}.md-footer-meta__inner{display:flex;flex-wrap:wrap;justify-content:space-between;padding:.2rem}html .md-footer-meta.md-typeset a{color:var(--md-footer-fg-color--light)}html .md-footer-meta.md-typeset a:-webkit-any(:focus,:hover){color:var(--md-footer-fg-color)}html .md-footer-meta.md-typeset a:-moz-any(:focus,:hover){color:var(--md-footer-fg-color)}html .md-footer-meta.md-typeset a:is(:focus,:hover){color:var(--md-footer-fg-color)}.md-copyright{color:var(--md-footer-fg-color--lighter);font-size:.64rem;margin:auto .6rem;padding:.4rem 0;width:100%}@media screen and (min-width:45em){.md-copyright{width:auto}}.md-copyright__highlight{color:var(--md-footer-fg-color--light)}.md-social{margin:0 .4rem;padding:.2rem 0 .6rem}@media screen and (min-width:45em){.md-social{padding:.6rem 0}}.md-social__link{display:inline-block;height:1.6rem;text-align:center;width:1.6rem}.md-social__link:before{line-height:1.9}.md-social__link svg{fill:currentcolor;max-height:.8rem;vertical-align:-25%}.md-typeset .md-button{border:.1rem solid;border-radius:.1rem;color:var(--md-primary-fg-color);cursor:pointer;display:inline-block;font-weight:700;padding:.625em 2em;transition:color 125ms,background-color 125ms,border-color 125ms}.md-typeset .md-button--primary{background-color:var(--md-primary-fg-color);border-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color)}.md-typeset .md-button:-webkit-any(:focus,:hover){background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-typeset .md-button:-moz-any(:focus,:hover){background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-typeset .md-button:is(:focus,:hover){background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[dir=ltr] .md-typeset .md-input{border-top-left-radius:.1rem}[dir=ltr] .md-typeset .md-input,[dir=rtl] .md-typeset .md-input{border-top-right-radius:.1rem}[dir=rtl] .md-typeset .md-input{border-top-left-radius:.1rem}.md-typeset .md-input{border-bottom:.1rem solid var(--md-default-fg-color--lighter);box-shadow:var(--md-shadow-z1);font-size:.8rem;height:1.8rem;padding:0 .6rem;transition:border .25s,box-shadow .25s}.md-typeset .md-input:-webkit-any(:focus,:hover){border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input:-moz-any(:focus,:hover){border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input:is(:focus,:hover){border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input--stretch{width:100%}.md-header{background-color:var(--md-primary-fg-color);box-shadow:0 0 .2rem transparent,0 .2rem .4rem transparent;color:var(--md-primary-bg-color);display:block;left:0;position:-webkit-sticky;position:sticky;right:0;top:0;z-index:4}@media print{.md-header{display:none}}.md-header[hidden]{transform:translateY(-100%);transition:transform .25s cubic-bezier(.8,0,.6,1),box-shadow .25s}.md-header--shadow{box-shadow:0 0 .2rem rgba(0,0,0,.1),0 .2rem .4rem rgba(0,0,0,.2);transition:transform .25s cubic-bezier(.1,.7,.1,1),box-shadow .25s}.md-header__inner{align-items:center;display:flex;padding:0 .2rem}.md-header__button{color:currentcolor;cursor:pointer;margin:.2rem;outline-color:var(--md-accent-fg-color);padding:.4rem;position:relative;transition:opacity .25s;vertical-align:middle;z-index:1}.md-header__button:hover{opacity:.7}.md-header__button:not([hidden]){display:inline-block}.md-header__button:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-header__button.md-logo{margin:.2rem;padding:.4rem}@media screen and (max-width:76.1875em){.md-header__button.md-logo{display:none}}.md-header__button.md-logo :-webkit-any(img,svg){fill:currentcolor;display:block;height:1.2rem;width:auto}.md-header__button.md-logo :-moz-any(img,svg){fill:currentcolor;display:block;height:1.2rem;width:auto}.md-header__button.md-logo :is(img,svg){fill:currentcolor;display:block;height:1.2rem;width:auto}@media screen and (min-width:60em){.md-header__button[for=__search]{display:none}}.no-js .md-header__button[for=__search]{display:none}[dir=rtl] .md-header__button[for=__search] svg{transform:scaleX(-1)}@media screen and (min-width:76.25em){.md-header__button[for=__drawer]{display:none}}.md-header__topic{display:flex;max-width:100%;position:absolute;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;white-space:nowrap}.md-header__topic+.md-header__topic{opacity:0;pointer-events:none;transform:translateX(1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__topic+.md-header__topic{transform:translateX(-1.25rem)}.md-header__topic:first-child{font-weight:700}[dir=ltr] .md-header__title{margin-right:.4rem}[dir=rtl] .md-header__title{margin-left:.4rem}[dir=ltr] .md-header__title{margin-left:1rem}[dir=rtl] .md-header__title{margin-right:1rem}.md-header__title{flex-grow:1;font-size:.9rem;height:2.4rem;line-height:2.4rem}.md-header__title--active .md-header__topic{opacity:0;pointer-events:none;transform:translateX(-1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__title--active .md-header__topic{transform:translateX(1.25rem)}.md-header__title--active .md-header__topic+.md-header__topic{opacity:1;pointer-events:auto;transform:translateX(0);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;z-index:0}.md-header__title>.md-header__ellipsis{height:100%;position:relative;width:100%}.md-header__option{display:flex;flex-shrink:0;max-width:100%;transition:max-width 0ms .25s,opacity .25s .25s;white-space:nowrap}[data-md-toggle=search]:checked~.md-header .md-header__option{max-width:0;opacity:0;transition:max-width 0ms,opacity 0ms}.md-header__source{display:none}@media screen and (min-width:60em){[dir=ltr] .md-header__source{margin-left:1rem}[dir=rtl] .md-header__source{margin-right:1rem}.md-header__source{display:block;max-width:11.7rem;width:11.7rem}}@media screen and (min-width:76.25em){[dir=ltr] .md-header__source{margin-left:1.4rem}[dir=rtl] .md-header__source{margin-right:1.4rem}}:root{--md-nav-icon--prev:url('data:image/svg+xml;charset=utf-8,');--md-nav-icon--next:url('data:image/svg+xml;charset=utf-8,');--md-toc-icon:url('data:image/svg+xml;charset=utf-8,')}.md-nav{font-size:.7rem;line-height:1.3}.md-nav__title{display:block;font-weight:700;overflow:hidden;padding:0 .6rem;text-overflow:ellipsis}.md-nav__title .md-nav__button{display:none}.md-nav__title .md-nav__button img{height:100%;width:auto}.md-nav__title .md-nav__button.md-logo :-webkit-any(img,svg){fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__title .md-nav__button.md-logo :-moz-any(img,svg){fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__title .md-nav__button.md-logo :is(img,svg){fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__list{list-style:none;margin:0;padding:0}.md-nav__item{padding:0 .6rem}[dir=ltr] .md-nav__item .md-nav__item{padding-right:0}[dir=rtl] .md-nav__item .md-nav__item{padding-left:0}.md-nav__link{align-items:center;cursor:pointer;display:flex;justify-content:space-between;margin-top:.625em;overflow:hidden;scroll-snap-align:start;text-overflow:ellipsis;transition:color 125ms}.md-nav__link--passed{color:var(--md-default-fg-color--light)}.md-nav__item .md-nav__link--active{color:var(--md-typeset-a-color)}.md-nav__item .md-nav__link--index [href]{width:100%}.md-nav__link:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav__link:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav__link.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-nav--primary .md-nav__link[for=__toc]{display:none}.md-nav--primary .md-nav__link[for=__toc] .md-icon:after{background-color:currentcolor;display:block;height:100%;-webkit-mask-image:var(--md-toc-icon);mask-image:var(--md-toc-icon);width:100%}.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:none}.md-nav__link>*{cursor:pointer;display:flex}.md-nav__icon{flex-shrink:0}.md-nav__source{display:none}@media screen and (max-width:76.1875em){.md-nav--primary,.md-nav--primary .md-nav{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;height:100%;left:0;position:absolute;right:0;top:0;z-index:1}.md-nav--primary :-webkit-any(.md-nav__title,.md-nav__item){font-size:.8rem;line-height:1.5}.md-nav--primary :-moz-any(.md-nav__title,.md-nav__item){font-size:.8rem;line-height:1.5}.md-nav--primary :is(.md-nav__title,.md-nav__item){font-size:.8rem;line-height:1.5}.md-nav--primary .md-nav__title{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light);cursor:pointer;height:5.6rem;line-height:2.4rem;padding:3rem .8rem .2rem;position:relative;white-space:nowrap}[dir=ltr] .md-nav--primary .md-nav__title .md-nav__icon{left:.4rem}[dir=rtl] .md-nav--primary .md-nav__title .md-nav__icon{right:.4rem}.md-nav--primary .md-nav__title .md-nav__icon{display:block;height:1.2rem;margin:.2rem;position:absolute;top:.4rem;width:1.2rem}.md-nav--primary .md-nav__title .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--prev);mask-image:var(--md-nav-icon--prev);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}.md-nav--primary .md-nav__title~.md-nav__list{background-color:var(--md-default-bg-color);box-shadow:0 .05rem 0 var(--md-default-fg-color--lightest) inset;overflow-y:auto;-ms-scroll-snap-type:y mandatory;scroll-snap-type:y mandatory;touch-action:pan-y}.md-nav--primary .md-nav__title~.md-nav__list>:first-child{border-top:0}.md-nav--primary .md-nav__title[for=__drawer]{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);font-weight:700}.md-nav--primary .md-nav__title .md-logo{display:block;left:.2rem;margin:.2rem;padding:.4rem;position:absolute;right:.2rem;top:.2rem}.md-nav--primary .md-nav__list{flex:1}.md-nav--primary .md-nav__item{border-top:.05rem solid var(--md-default-fg-color--lightest);padding:0}.md-nav--primary .md-nav__item--active>.md-nav__link{color:var(--md-typeset-a-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__link{margin-top:0;padding:.6rem .8rem}[dir=ltr] .md-nav--primary .md-nav__link .md-nav__icon{margin-right:-.2rem}[dir=rtl] .md-nav--primary .md-nav__link .md-nav__icon{margin-left:-.2rem}.md-nav--primary .md-nav__link .md-nav__icon{font-size:1.2rem;height:1.2rem;width:1.2rem}.md-nav--primary .md-nav__link .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}[dir=rtl] .md-nav--primary .md-nav__icon:after{transform:scale(-1)}.md-nav--primary .md-nav--secondary .md-nav{background-color:initial;position:static}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-left:1.4rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-right:1.4rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-left:2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-right:2rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-left:2.6rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-right:2.6rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-left:3.2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-right:3.2rem}.md-nav--secondary{background-color:initial}.md-nav__toggle~.md-nav{display:flex;opacity:0;transform:translateX(100%);transition:transform .25s cubic-bezier(.8,0,.6,1),opacity 125ms 50ms}[dir=rtl] .md-nav__toggle~.md-nav{transform:translateX(-100%)}.md-nav__toggle:checked~.md-nav{opacity:1;transform:translateX(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 125ms 125ms}.md-nav__toggle:checked~.md-nav>.md-nav__list{-webkit-backface-visibility:hidden;backface-visibility:hidden}}@media screen and (max-width:59.9375em){.md-nav--primary .md-nav__link[for=__toc]{display:flex}.md-nav--primary .md-nav__link[for=__toc] .md-icon:after{content:""}.md-nav--primary .md-nav__link[for=__toc]+.md-nav__link{display:none}.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:flex}.md-nav__source{background-color:var(--md-primary-fg-color--dark);color:var(--md-primary-bg-color);display:block;padding:0 .2rem}}@media screen and (min-width:60em) and (max-width:76.1875em){.md-nav--integrated .md-nav__link[for=__toc]{display:flex}.md-nav--integrated .md-nav__link[for=__toc] .md-icon:after{content:""}.md-nav--integrated .md-nav__link[for=__toc]+.md-nav__link{display:none}.md-nav--integrated .md-nav__link[for=__toc]~.md-nav{display:flex}}@media screen and (min-width:60em){.md-nav--secondary .md-nav__title[for=__toc]{scroll-snap-align:start}.md-nav--secondary .md-nav__title .md-nav__icon{display:none}}@media screen and (min-width:76.25em){.md-nav{transition:max-height .25s cubic-bezier(.86,0,.07,1)}.md-nav--primary .md-nav__title[for=__drawer]{scroll-snap-align:start}.md-nav--primary .md-nav__title .md-nav__icon,.md-nav__toggle~.md-nav{display:none}.md-nav__toggle:-webkit-any(:checked,:indeterminate)~.md-nav{display:block}.md-nav__toggle:-moz-any(:checked,:indeterminate)~.md-nav{display:block}.md-nav__toggle:is(:checked,:indeterminate)~.md-nav{display:block}.md-nav__item--nested>.md-nav>.md-nav__title{display:none}.md-nav__item--section{display:block;margin:1.25em 0}.md-nav__item--section:last-child{margin-bottom:0}.md-nav__item--section>.md-nav__link{font-weight:700;pointer-events:none}.md-nav__item--section>.md-nav__link--index [href]{pointer-events:auto}.md-nav__item--section>.md-nav__link .md-nav__icon{display:none}.md-nav__item--section>.md-nav{display:block}.md-nav__item--section>.md-nav>.md-nav__list>.md-nav__item{padding:0}.md-nav__icon{border-radius:100%;float:right;height:.9rem;transition:background-color .25s,transform .25s;width:.9rem}[dir=rtl] .md-nav__icon{float:left;transform:rotate(180deg)}.md-nav__icon:hover{background-color:var(--md-accent-fg-color--transparent)}.md-nav__icon:after{background-color:currentcolor;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:-.1rem;width:100%}.md-nav__item--nested .md-nav__toggle:checked~.md-nav__link .md-nav__icon,.md-nav__item--nested .md-nav__toggle:indeterminate~.md-nav__link .md-nav__icon{transform:rotate(90deg)}.md-nav--lifted>.md-nav__list>.md-nav__item,.md-nav--lifted>.md-nav__list>.md-nav__item--nested,.md-nav--lifted>.md-nav__title{display:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active{display:block;padding:0}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link{font-weight:700;margin-top:0;padding:0 .6rem;pointer-events:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link--index [href]{pointer-events:auto}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link .md-nav__icon{display:none}.md-nav--lifted .md-nav[data-md-level="1"]{display:block}[dir=ltr] .md-nav--lifted .md-nav[data-md-level="1"]>.md-nav__list>.md-nav__item{padding-right:.6rem}[dir=rtl] .md-nav--lifted .md-nav[data-md-level="1"]>.md-nav__list>.md-nav__item{padding-left:.6rem}.md-nav--integrated>.md-nav__list>.md-nav__item--active:not(.md-nav__item--nested){padding:0 .6rem}.md-nav--integrated>.md-nav__list>.md-nav__item--active:not(.md-nav__item--nested)>.md-nav__link{padding:0}[dir=ltr] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-left:.05rem solid var(--md-primary-fg-color)}[dir=rtl] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-right:.05rem solid var(--md-primary-fg-color)}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{display:block;margin-bottom:1.25em}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary>.md-nav__title{display:none}}:root{--md-search-result-icon:url('data:image/svg+xml;charset=utf-8,')}.md-search{position:relative}@media screen and (min-width:60em){.md-search{padding:.2rem 0}}.no-js .md-search{display:none}.md-search__overlay{opacity:0;z-index:1}@media screen and (max-width:59.9375em){[dir=ltr] .md-search__overlay{left:-2.2rem}[dir=rtl] .md-search__overlay{right:-2.2rem}.md-search__overlay{background-color:var(--md-default-bg-color);border-radius:1rem;height:2rem;overflow:hidden;pointer-events:none;position:absolute;top:-1rem;transform-origin:center;transition:transform .3s .1s,opacity .2s .2s;width:2rem}[data-md-toggle=search]:checked~.md-header .md-search__overlay{opacity:1;transition:transform .4s,opacity .1s}}@media screen and (min-width:60em){[dir=ltr] .md-search__overlay{left:0}[dir=rtl] .md-search__overlay{right:0}.md-search__overlay{background-color:rgba(0,0,0,.54);cursor:pointer;height:0;position:fixed;top:0;transition:width 0ms .25s,height 0ms .25s,opacity .25s;width:0}[data-md-toggle=search]:checked~.md-header .md-search__overlay{height:200vh;opacity:1;transition:width 0ms,height 0ms,opacity .25s;width:100%}}@media screen and (max-width:29.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(45)}}@media screen and (min-width:30em) and (max-width:44.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(60)}}@media screen and (min-width:45em) and (max-width:59.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(75)}}.md-search__inner{-webkit-backface-visibility:hidden;backface-visibility:hidden}@media screen and (max-width:59.9375em){[dir=ltr] .md-search__inner{left:0}[dir=rtl] .md-search__inner{right:0}.md-search__inner{height:0;opacity:0;overflow:hidden;position:fixed;top:0;transform:translateX(5%);transition:width 0ms .3s,height 0ms .3s,transform .15s cubic-bezier(.4,0,.2,1) .15s,opacity .15s .15s;width:0;z-index:2}[dir=rtl] .md-search__inner{transform:translateX(-5%)}[data-md-toggle=search]:checked~.md-header .md-search__inner{height:100%;opacity:1;transform:translateX(0);transition:width 0ms 0ms,height 0ms 0ms,transform .15s cubic-bezier(.1,.7,.1,1) .15s,opacity .15s .15s;width:100%}}@media screen and (min-width:60em){.md-search__inner{float:right;padding:.1rem 0;position:relative;transition:width .25s cubic-bezier(.1,.7,.1,1);width:11.7rem}[dir=rtl] .md-search__inner{float:left}}@media screen and (min-width:60em) and (max-width:76.1875em){[data-md-toggle=search]:checked~.md-header .md-search__inner{width:23.4rem}}@media screen and (min-width:76.25em){[data-md-toggle=search]:checked~.md-header .md-search__inner{width:34.4rem}}.md-search__form{background-color:var(--md-default-bg-color);box-shadow:0 0 .6rem transparent;height:2.4rem;position:relative;transition:color .25s,background-color .25s;z-index:2}@media screen and (min-width:60em){.md-search__form{background-color:rgba(0,0,0,.26);border-radius:.1rem;height:1.8rem}.md-search__form:hover{background-color:hsla(0,0%,100%,.12)}}[data-md-toggle=search]:checked~.md-header .md-search__form{background-color:var(--md-default-bg-color);border-radius:.1rem .1rem 0 0;box-shadow:0 0 .6rem rgba(0,0,0,.07);color:var(--md-default-fg-color)}[dir=ltr] .md-search__input{padding-left:3.6rem;padding-right:2.2rem}[dir=rtl] .md-search__input{padding-left:2.2rem;padding-right:3.6rem}.md-search__input{background:transparent;font-size:.9rem;height:100%;position:relative;text-overflow:ellipsis;width:100%;z-index:2}.md-search__input::-ms-input-placeholder{-ms-transition:color .25s;transition:color .25s}.md-search__input::placeholder{transition:color .25s}.md-search__input::-ms-input-placeholder{color:var(--md-default-fg-color--light)}.md-search__input::placeholder,.md-search__input~.md-search__icon{color:var(--md-default-fg-color--light)}.md-search__input::-ms-clear{display:none}@media screen and (max-width:59.9375em){.md-search__input{font-size:.9rem;height:2.4rem;width:100%}}@media screen and (min-width:60em){[dir=ltr] .md-search__input{padding-left:2.2rem}[dir=rtl] .md-search__input{padding-right:2.2rem}.md-search__input{color:inherit;font-size:.8rem}.md-search__input::-ms-input-placeholder{color:var(--md-primary-bg-color--light)}.md-search__input::placeholder{color:var(--md-primary-bg-color--light)}.md-search__input+.md-search__icon{color:var(--md-primary-bg-color)}[data-md-toggle=search]:checked~.md-header .md-search__input{text-overflow:clip}[data-md-toggle=search]:checked~.md-header .md-search__input::-ms-input-placeholder{color:var(--md-default-fg-color--light)}[data-md-toggle=search]:checked~.md-header .md-search__input+.md-search__icon,[data-md-toggle=search]:checked~.md-header .md-search__input::placeholder{color:var(--md-default-fg-color--light)}}.md-search__icon{cursor:pointer;display:inline-block;height:1.2rem;transition:color .25s,opacity .25s;width:1.2rem}.md-search__icon:hover{opacity:.7}[dir=ltr] .md-search__icon[for=__search]{left:.5rem}[dir=rtl] .md-search__icon[for=__search]{right:.5rem}.md-search__icon[for=__search]{position:absolute;top:.3rem;z-index:2}[dir=rtl] .md-search__icon[for=__search] svg{transform:scaleX(-1)}@media screen and (max-width:59.9375em){[dir=ltr] .md-search__icon[for=__search]{left:.8rem}[dir=rtl] .md-search__icon[for=__search]{right:.8rem}.md-search__icon[for=__search]{top:.6rem}.md-search__icon[for=__search] svg:first-child{display:none}}@media screen and (min-width:60em){.md-search__icon[for=__search]{pointer-events:none}.md-search__icon[for=__search] svg:last-child{display:none}}[dir=ltr] .md-search__options{right:.5rem}[dir=rtl] .md-search__options{left:.5rem}.md-search__options{pointer-events:none;position:absolute;top:.3rem;z-index:2}@media screen and (max-width:59.9375em){[dir=ltr] .md-search__options{right:.8rem}[dir=rtl] .md-search__options{left:.8rem}.md-search__options{top:.6rem}}[dir=ltr] .md-search__options>*{margin-left:.2rem}[dir=rtl] .md-search__options>*{margin-right:.2rem}.md-search__options>*{color:var(--md-default-fg-color--light);opacity:0;transform:scale(.75);transition:transform .15s cubic-bezier(.1,.7,.1,1),opacity .15s}.md-search__options>:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>*{opacity:1;pointer-events:auto;transform:scale(1)}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>:hover{opacity:.7}[dir=ltr] .md-search__suggest{padding-left:3.6rem;padding-right:2.2rem}[dir=rtl] .md-search__suggest{padding-left:2.2rem;padding-right:3.6rem}.md-search__suggest{align-items:center;color:var(--md-default-fg-color--lighter);display:flex;font-size:.9rem;height:100%;opacity:0;position:absolute;top:0;transition:opacity 50ms;white-space:nowrap;width:100%}@media screen and (min-width:60em){[dir=ltr] .md-search__suggest{padding-left:2.2rem}[dir=rtl] .md-search__suggest{padding-right:2.2rem}.md-search__suggest{font-size:.8rem}}[data-md-toggle=search]:checked~.md-header .md-search__suggest{opacity:1;transition:opacity .3s .1s}[dir=ltr] .md-search__output{border-bottom-left-radius:.1rem}[dir=ltr] .md-search__output,[dir=rtl] .md-search__output{border-bottom-right-radius:.1rem}[dir=rtl] .md-search__output{border-bottom-left-radius:.1rem}.md-search__output{overflow:hidden;position:absolute;width:100%;z-index:1}@media screen and (max-width:59.9375em){.md-search__output{bottom:0;top:2.4rem}}@media screen and (min-width:60em){.md-search__output{opacity:0;top:1.9rem;transition:opacity .4s}[data-md-toggle=search]:checked~.md-header .md-search__output{box-shadow:var(--md-shadow-z3);opacity:1}}.md-search__scrollwrap{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--md-default-bg-color);height:100%;overflow-y:auto;touch-action:pan-y}@media (-webkit-max-device-pixel-ratio:1),(max-resolution:1dppx){.md-search__scrollwrap{transform:translateZ(0)}}@media screen and (min-width:60em) and (max-width:76.1875em){.md-search__scrollwrap{width:23.4rem}}@media screen and (min-width:76.25em){.md-search__scrollwrap{width:34.4rem}}@media screen and (min-width:60em){.md-search__scrollwrap{max-height:0;scrollbar-color:var(--md-default-fg-color--lighter) transparent;scrollbar-width:thin}[data-md-toggle=search]:checked~.md-header .md-search__scrollwrap{max-height:75vh}.md-search__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) transparent}.md-search__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-search__scrollwrap::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-search__scrollwrap::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}}.md-search-result{color:var(--md-default-fg-color);word-break:break-word}.md-search-result__meta{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light);font-size:.64rem;line-height:1.8rem;padding:0 .8rem;scroll-snap-align:start}@media screen and (min-width:60em){[dir=ltr] .md-search-result__meta{padding-left:2.2rem}[dir=rtl] .md-search-result__meta{padding-right:2.2rem}}.md-search-result__list{list-style:none;margin:0;padding:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.md-search-result__item{box-shadow:0 -.05rem var(--md-default-fg-color--lightest)}.md-search-result__item:first-child{box-shadow:none}.md-search-result__link{display:block;outline:none;scroll-snap-align:start;transition:background-color .25s}.md-search-result__link:-webkit-any(:focus,:hover){background-color:var(--md-accent-fg-color--transparent)}.md-search-result__link:-moz-any(:focus,:hover){background-color:var(--md-accent-fg-color--transparent)}.md-search-result__link:is(:focus,:hover){background-color:var(--md-accent-fg-color--transparent)}.md-search-result__link:last-child p:last-child{margin-bottom:.6rem}.md-search-result__more summary{color:var(--md-typeset-a-color);cursor:pointer;display:block;font-size:.64rem;outline:none;padding:.75em .8rem;scroll-snap-align:start;transition:color .25s,background-color .25s}@media screen and (min-width:60em){[dir=ltr] .md-search-result__more summary{padding-left:2.2rem}[dir=rtl] .md-search-result__more summary{padding-right:2.2rem}}.md-search-result__more summary:-webkit-any(:focus,:hover){background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more summary:-moz-any(:focus,:hover){background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more summary:is(:focus,:hover){background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more summary::marker{display:none}.md-search-result__more summary::-webkit-details-marker{display:none}.md-search-result__more summary~*>*{opacity:.65}.md-search-result__article{overflow:hidden;padding:0 .8rem;position:relative}@media screen and (min-width:60em){[dir=ltr] .md-search-result__article{padding-left:2.2rem}[dir=rtl] .md-search-result__article{padding-right:2.2rem}}.md-search-result__article--document .md-search-result__title{font-size:.8rem;font-weight:400;line-height:1.4;margin:.55rem 0}[dir=ltr] .md-search-result__icon{left:0}[dir=rtl] .md-search-result__icon{right:0}.md-search-result__icon{color:var(--md-default-fg-color--light);height:1.2rem;margin:.5rem;position:absolute;width:1.2rem}@media screen and (max-width:59.9375em){.md-search-result__icon{display:none}}.md-search-result__icon:after{background-color:currentcolor;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-search-result-icon);mask-image:var(--md-search-result-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}[dir=rtl] .md-search-result__icon:after{transform:scaleX(-1)}.md-search-result__title{font-size:.64rem;font-weight:700;line-height:1.6;margin:.5em 0}.md-search-result__teaser{-webkit-box-orient:vertical;-webkit-line-clamp:2;color:var(--md-default-fg-color--light);display:-webkit-box;font-size:.64rem;line-height:1.6;margin:.5em 0;max-height:2rem;overflow:hidden;text-overflow:ellipsis}@media screen and (max-width:44.9375em){.md-search-result__teaser{-webkit-line-clamp:3;max-height:3rem}}@media screen and (min-width:60em) and (max-width:76.1875em){.md-search-result__teaser{-webkit-line-clamp:3;max-height:3rem}}.md-search-result__teaser mark{background-color:initial;text-decoration:underline}.md-search-result__terms{font-size:.64rem;font-style:italic;margin:.5em 0}.md-search-result mark{background-color:initial;color:var(--md-accent-fg-color)}.md-select{position:relative;z-index:1}.md-select__inner{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);left:50%;margin-top:.2rem;max-height:0;opacity:0;position:absolute;top:calc(100% - .2rem);transform:translate3d(-50%,.3rem,0);transition:transform .25s 375ms,opacity .25s .25s,max-height 0ms .5s}.md-select:-webkit-any(:focus-within,:hover) .md-select__inner{max-height:10rem;opacity:1;transform:translate3d(-50%,0,0);-webkit-transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms;transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}.md-select:-moz-any(:focus-within,:hover) .md-select__inner{max-height:10rem;opacity:1;transform:translate3d(-50%,0,0);-moz-transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms;transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}.md-select:is(:focus-within,:hover) .md-select__inner{max-height:10rem;opacity:1;transform:translate3d(-50%,0,0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}.md-select__inner:after{border-bottom:.2rem solid transparent;border-bottom-color:var(--md-default-bg-color);border-left:.2rem solid transparent;border-right:.2rem solid transparent;border-top:0;content:"";height:0;left:50%;margin-left:-.2rem;margin-top:-.2rem;position:absolute;top:0;width:0}.md-select__list{border-radius:.1rem;font-size:.8rem;list-style-type:none;margin:0;max-height:inherit;overflow:auto;padding:0}.md-select__item{line-height:1.8rem}[dir=ltr] .md-select__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-select__link{padding-left:1.2rem;padding-right:.6rem}.md-select__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:background-color .25s,color .25s;width:100%}.md-select__link:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-select__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-select__link:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-select__link:focus{background-color:var(--md-default-fg-color--lightest)}.md-sidebar{align-self:flex-start;flex-shrink:0;padding:1.2rem 0;position:-webkit-sticky;position:sticky;top:2.4rem;width:12.1rem}@media print{.md-sidebar{display:none}}@media screen and (max-width:76.1875em){[dir=ltr] .md-sidebar--primary{left:-12.1rem}[dir=rtl] .md-sidebar--primary{right:-12.1rem}.md-sidebar--primary{background-color:var(--md-default-bg-color);display:block;height:100%;position:fixed;top:0;transform:translateX(0);transition:transform .25s cubic-bezier(.4,0,.2,1),box-shadow .25s;width:12.1rem;z-index:5}[data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{box-shadow:var(--md-shadow-z3);transform:translateX(12.1rem)}[dir=rtl] [data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{transform:translateX(-12.1rem)}.md-sidebar--primary .md-sidebar__scrollwrap{bottom:0;left:0;margin:0;overflow:hidden;position:absolute;right:0;-ms-scroll-snap-type:none;scroll-snap-type:none;top:0}}@media screen and (min-width:76.25em){.md-sidebar{height:0}.no-js .md-sidebar{height:auto}}.md-sidebar--secondary{display:none;order:2}@media screen and (min-width:60em){.md-sidebar--secondary{height:0}.no-js .md-sidebar--secondary{height:auto}.md-sidebar--secondary:not([hidden]){display:block}.md-sidebar--secondary .md-sidebar__scrollwrap{touch-action:pan-y}}.md-sidebar__scrollwrap{-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:0 .2rem;overflow-y:auto;scrollbar-color:var(--md-default-fg-color--lighter) transparent;scrollbar-width:thin}.md-sidebar__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) transparent}.md-sidebar__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-sidebar__scrollwrap::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}@media screen and (max-width:76.1875em){.md-overlay{background-color:rgba(0,0,0,.54);height:0;opacity:0;position:fixed;top:0;transition:width 0ms .25s,height 0ms .25s,opacity .25s;width:0;z-index:5}[data-md-toggle=drawer]:checked~.md-overlay{height:100%;opacity:1;transition:width 0ms,height 0ms,opacity .25s;width:100%}}@-webkit-keyframes facts{0%{height:0}to{height:.65rem}}@keyframes facts{0%{height:0}to{height:.65rem}}@-webkit-keyframes fact{0%{opacity:0;transform:translateY(100%)}50%{opacity:0}to{opacity:1;transform:translateY(0)}}@keyframes fact{0%{opacity:0;transform:translateY(100%)}50%{opacity:0}to{opacity:1;transform:translateY(0)}}:root{--md-source-forks-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-repositories-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-stars-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-version-icon:url('data:image/svg+xml;charset=utf-8,')}.md-source{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:block;font-size:.65rem;line-height:1.2;outline-color:var(--md-accent-fg-color);transition:opacity .25s;white-space:nowrap}.md-source:hover{opacity:.7}.md-source__icon{display:inline-block;height:2.4rem;vertical-align:middle;width:2rem}[dir=ltr] .md-source__icon svg{margin-left:.6rem}[dir=rtl] .md-source__icon svg{margin-right:.6rem}.md-source__icon svg{margin-top:.6rem}[dir=ltr] .md-source__icon+.md-source__repository{margin-left:-2rem}[dir=rtl] .md-source__icon+.md-source__repository{margin-right:-2rem}[dir=ltr] .md-source__icon+.md-source__repository{padding-left:2rem}[dir=rtl] .md-source__icon+.md-source__repository{padding-right:2rem}[dir=ltr] .md-source__repository{margin-left:.6rem}[dir=rtl] .md-source__repository{margin-right:.6rem}.md-source__repository{display:inline-block;max-width:calc(100% - 1.2rem);overflow:hidden;text-overflow:ellipsis;vertical-align:middle}.md-source__facts{display:flex;font-size:.55rem;gap:.4rem;list-style-type:none;margin:.1rem 0 0;opacity:.75;overflow:hidden;padding:0;width:100%}.md-source__repository--active .md-source__facts{-webkit-animation:facts .25s ease-in;animation:facts .25s ease-in}.md-source__fact{overflow:hidden;text-overflow:ellipsis}.md-source__repository--active .md-source__fact{-webkit-animation:fact .4s ease-out;animation:fact .4s ease-out}[dir=ltr] .md-source__fact:before{margin-right:.1rem}[dir=rtl] .md-source__fact:before{margin-left:.1rem}.md-source__fact:before{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-top;width:.6rem}.md-source__fact:nth-child(1n+2){flex-shrink:0}.md-source__fact--version:before{-webkit-mask-image:var(--md-source-version-icon);mask-image:var(--md-source-version-icon)}.md-source__fact--stars:before{-webkit-mask-image:var(--md-source-stars-icon);mask-image:var(--md-source-stars-icon)}.md-source__fact--forks:before{-webkit-mask-image:var(--md-source-forks-icon);mask-image:var(--md-source-forks-icon)}.md-source__fact--repositories:before{-webkit-mask-image:var(--md-source-repositories-icon);mask-image:var(--md-source-repositories-icon)}.md-tabs{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);display:block;line-height:1.3;overflow:auto;width:100%;z-index:3}@media print{.md-tabs{display:none}}@media screen and (max-width:76.1875em){.md-tabs{display:none}}.md-tabs[hidden]{pointer-events:none}[dir=ltr] .md-tabs__list{margin-left:.2rem}[dir=rtl] .md-tabs__list{margin-right:.2rem}.md-tabs__list{contain:content;list-style:none;margin:0;padding:0;white-space:nowrap}.md-tabs__item{display:inline-block;height:2.4rem;padding-left:.6rem;padding-right:.6rem}.md-tabs__link{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:block;font-size:.7rem;margin-top:.8rem;opacity:.7;outline-color:var(--md-accent-fg-color);outline-offset:.2rem;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .25s}.md-tabs__link--active,.md-tabs__link:-webkit-any(:focus,:hover){color:inherit;opacity:1}.md-tabs__link--active,.md-tabs__link:-moz-any(:focus,:hover){color:inherit;opacity:1}.md-tabs__link--active,.md-tabs__link:is(:focus,:hover){color:inherit;opacity:1}.md-tabs__item:nth-child(2) .md-tabs__link{transition-delay:20ms}.md-tabs__item:nth-child(3) .md-tabs__link{transition-delay:40ms}.md-tabs__item:nth-child(4) .md-tabs__link{transition-delay:60ms}.md-tabs__item:nth-child(5) .md-tabs__link{transition-delay:80ms}.md-tabs__item:nth-child(6) .md-tabs__link{transition-delay:.1s}.md-tabs__item:nth-child(7) .md-tabs__link{transition-delay:.12s}.md-tabs__item:nth-child(8) .md-tabs__link{transition-delay:.14s}.md-tabs__item:nth-child(9) .md-tabs__link{transition-delay:.16s}.md-tabs__item:nth-child(10) .md-tabs__link{transition-delay:.18s}.md-tabs__item:nth-child(11) .md-tabs__link{transition-delay:.2s}.md-tabs__item:nth-child(12) .md-tabs__link{transition-delay:.22s}.md-tabs__item:nth-child(13) .md-tabs__link{transition-delay:.24s}.md-tabs__item:nth-child(14) .md-tabs__link{transition-delay:.26s}.md-tabs__item:nth-child(15) .md-tabs__link{transition-delay:.28s}.md-tabs__item:nth-child(16) .md-tabs__link{transition-delay:.3s}.md-tabs[hidden] .md-tabs__link{opacity:0;transform:translateY(50%);transition:transform 0ms .1s,opacity .1s}.md-tags{margin-bottom:.75em}[dir=ltr] .md-tag{margin-right:.5em}[dir=rtl] .md-tag{margin-left:.5em}.md-tag{background:var(--md-default-fg-color--lightest);border-radius:.4rem;display:inline-block;font-size:.64rem;font-weight:700;line-height:1.6;margin-bottom:.5em;padding:.3125em .9375em}.md-tag[href]{-webkit-tap-highlight-color:transparent;color:inherit;outline:none;transition:color 125ms,background-color 125ms}.md-tag[href]:focus,.md-tag[href]:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[id]>.md-tag{vertical-align:text-top}@-webkit-keyframes pulse{0%{box-shadow:0 0 0 0 var(--md-default-fg-color--lightest);transform:scale(.95)}75%{box-shadow:0 0 0 .625em transparent;transform:scale(1)}to{box-shadow:0 0 0 0 transparent;transform:scale(.95)}}@keyframes pulse{0%{box-shadow:0 0 0 0 var(--md-default-fg-color--lightest);transform:scale(.95)}75%{box-shadow:0 0 0 .625em transparent;transform:scale(1)}to{box-shadow:0 0 0 0 transparent;transform:scale(.95)}}:root{--md-tooltip-width:20rem}.md-tooltip{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);left:clamp(var(--md-tooltip-0,0rem) + .8rem,var(--md-tooltip-x),100vw + var(--md-tooltip-0,0rem) + .8rem - var(--md-tooltip-width) - 2 * .8rem);max-height:0;max-width:calc(100vw - 1.6rem);opacity:0;position:absolute;top:var(--md-tooltip-y);transform:translateY(-.4rem);transition:transform 0ms .25s,opacity .25s,max-height 0ms .25s,z-index .25s;width:var(--md-tooltip-width);z-index:0}:focus-within>.md-tooltip{max-height:1000%;opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height .25s,z-index 0ms}.focus-visible>.md-tooltip{outline:var(--md-accent-fg-color) auto}.md-tooltip__inner{font-size:.64rem;padding:.8rem}.md-tooltip__inner.md-typeset>:first-child{margin-top:0}.md-tooltip__inner.md-typeset>:last-child{margin-bottom:0}.md-annotation{outline:none;white-space:normal}[dir=rtl] .md-annotation{direction:rtl}.md-annotation:not([hidden]){display:inline-block;line-height:1.325}.md-annotation:focus-within>*{z-index:2}.md-annotation__inner{font-family:var(--md-text-font-family);top:calc(var(--md-tooltip-y) + 1.2ch)}:not(:focus-within)>.md-annotation__inner{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.md-annotation__index{color:#fff;cursor:pointer;margin:0 1ch;position:relative;transition:z-index .25s;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:0}.md-annotation__index:after{background-color:var(--md-default-fg-color--lighter);border-radius:2ch;content:"";height:2.2ch;left:-.126em;margin:0 -.4ch;padding:0 .4ch;position:absolute;transition:color .25s,background-color .25s;width:calc(100% + 1.2ch);width:max(2.2ch,100% + 1.2ch);z-index:-1}@media not all and (prefers-reduced-motion){[data-md-visible]>.md-annotation__index:after{-webkit-animation:pulse 2s infinite;animation:pulse 2s infinite}}:-webkit-any(:focus-within,:hover)>.md-annotation__index:after{background-color:var(--md-accent-fg-color)}:-moz-any(:focus-within,:hover)>.md-annotation__index:after{background-color:var(--md-accent-fg-color)}:is(:focus-within,:hover)>.md-annotation__index:after{background-color:var(--md-accent-fg-color)}:focus-within>.md-annotation__index:after{-webkit-animation:none;animation:none;transition:color .25s,background-color .25s}.md-annotation__index [data-md-annotation-id]{display:inline-block;line-height:90%}.md-annotation__index [data-md-annotation-id]:before{content:attr(data-md-annotation-id);display:inline-block;padding-bottom:.1em;transform:scale(1.15);transition:transform .4s cubic-bezier(.1,.7,.1,1);vertical-align:.065em}@media not print{.md-annotation__index [data-md-annotation-id]:before{content:"+"}:focus-within>.md-annotation__index [data-md-annotation-id]:before{transform:scale(1.25) rotate(45deg)}}:-webkit-any(:focus-within,:hover)>.md-annotation__index{color:var(--md-accent-bg-color)}:-moz-any(:focus-within,:hover)>.md-annotation__index{color:var(--md-accent-bg-color)}:is(:focus-within,:hover)>.md-annotation__index{color:var(--md-accent-bg-color)}:focus-within>.md-annotation__index{-webkit-animation:none;animation:none;transition:none}[dir=ltr] .md-top{margin-left:50%}[dir=rtl] .md-top{margin-right:50%}.md-top{background-color:var(--md-default-bg-color);border-radius:1.6rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color--light);display:block;font-size:.7rem;outline:none;padding:.4rem .8rem;position:fixed;top:3.2rem;transform:translate(-50%);transition:color 125ms,background-color 125ms,transform 125ms cubic-bezier(.4,0,.2,1),opacity 125ms;z-index:2}@media print{.md-top{display:none}}[dir=rtl] .md-top{transform:translate(50%)}.md-top[hidden]{opacity:0;pointer-events:none;transform:translate(-50%,.2rem);transition-duration:0ms}[dir=rtl] .md-top[hidden]{transform:translate(50%,.2rem)}.md-top:-webkit-any(:focus,:hover){background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top:-moz-any(:focus,:hover){background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top:is(:focus,:hover){background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top svg{display:inline-block;vertical-align:-.5em}@-webkit-keyframes hoverfix{0%{pointer-events:none}}@keyframes hoverfix{0%{pointer-events:none}}:root{--md-version-icon:url('data:image/svg+xml;charset=utf-8,')}.md-version{flex-shrink:0;font-size:.8rem;height:2.4rem}[dir=ltr] .md-version__current{margin-left:1.4rem;margin-right:.4rem}[dir=rtl] .md-version__current{margin-left:.4rem;margin-right:1.4rem}.md-version__current{color:inherit;cursor:pointer;outline:none;position:relative;top:.05rem}[dir=ltr] .md-version__current:after{margin-left:.4rem}[dir=rtl] .md-version__current:after{margin-right:.4rem}.md-version__current:after{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-image:var(--md-version-icon);mask-image:var(--md-version-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;width:.4rem}.md-version__list{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);list-style-type:none;margin:.2rem .8rem;max-height:0;opacity:0;overflow:auto;padding:0;position:absolute;-ms-scroll-snap-type:y mandatory;scroll-snap-type:y mandatory;top:.15rem;transition:max-height 0ms .5s,opacity .25s .25s;z-index:3}.md-version:-webkit-any(:focus-within,:hover) .md-version__list{max-height:10rem;opacity:1;-webkit-transition:max-height 0ms,opacity .25s;transition:max-height 0ms,opacity .25s}.md-version:-moz-any(:focus-within,:hover) .md-version__list{max-height:10rem;opacity:1;-moz-transition:max-height 0ms,opacity .25s;transition:max-height 0ms,opacity .25s}.md-version:is(:focus-within,:hover) .md-version__list{max-height:10rem;opacity:1;transition:max-height 0ms,opacity .25s}@media (pointer:coarse){.md-version:hover .md-version__list{-webkit-animation:hoverfix .25s forwards;animation:hoverfix .25s forwards}.md-version:focus-within .md-version__list{-webkit-animation:none;animation:none}}.md-version__item{line-height:1.8rem}[dir=ltr] .md-version__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-version__link{padding-left:1.2rem;padding-right:.6rem}.md-version__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:color .25s,background-color .25s;white-space:nowrap;width:100%}.md-version__link:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-version__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-version__link:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-version__link:focus{background-color:var(--md-default-fg-color--lightest)}:root{--md-admonition-icon--note:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--abstract:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--info:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--tip:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--success:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--question:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--warning:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--failure:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--danger:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--bug:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--example:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--quote:url('data:image/svg+xml;charset=utf-8,')}.md-typeset :-webkit-any(.admonition,details){background-color:var(--md-admonition-bg-color);border:0 solid #448aff;border-radius:.1rem;box-shadow:var(--md-shadow-z1);color:var(--md-admonition-fg-color);display:flow-root;font-size:.64rem;margin:1.5625em 0;padding:0 .6rem;page-break-inside:avoid}.md-typeset :-moz-any(.admonition,details){background-color:var(--md-admonition-bg-color);border:0 solid #448aff;border-radius:.1rem;box-shadow:var(--md-shadow-z1);color:var(--md-admonition-fg-color);display:flow-root;font-size:.64rem;margin:1.5625em 0;padding:0 .6rem;page-break-inside:avoid}[dir=ltr] .md-typeset :-webkit-any(.admonition,details){border-left-width:.2rem}[dir=ltr] .md-typeset :-moz-any(.admonition,details){border-left-width:.2rem}[dir=ltr] .md-typeset :is(.admonition,details){border-left-width:.2rem}[dir=rtl] .md-typeset :-webkit-any(.admonition,details){border-right-width:.2rem}[dir=rtl] .md-typeset :-moz-any(.admonition,details){border-right-width:.2rem}[dir=rtl] .md-typeset :is(.admonition,details){border-right-width:.2rem}.md-typeset :is(.admonition,details){background-color:var(--md-admonition-bg-color);border:0 solid #448aff;border-radius:.1rem;box-shadow:var(--md-shadow-z1);color:var(--md-admonition-fg-color);display:flow-root;font-size:.64rem;margin:1.5625em 0;padding:0 .6rem;page-break-inside:avoid}@media print{.md-typeset :-webkit-any(.admonition,details){box-shadow:none}.md-typeset :-moz-any(.admonition,details){box-shadow:none}.md-typeset :is(.admonition,details){box-shadow:none}}.md-typeset :-webkit-any(.admonition,details)>*{box-sizing:border-box}.md-typeset :-moz-any(.admonition,details)>*{box-sizing:border-box}.md-typeset :is(.admonition,details)>*{box-sizing:border-box}.md-typeset :-webkit-any(.admonition,details) :-webkit-any(.admonition,details){margin-bottom:1em;margin-top:1em}.md-typeset :-moz-any(.admonition,details) :-moz-any(.admonition,details){margin-bottom:1em;margin-top:1em}.md-typeset :is(.admonition,details) :is(.admonition,details){margin-bottom:1em;margin-top:1em}.md-typeset :-webkit-any(.admonition,details) .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset :-moz-any(.admonition,details) .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset :is(.admonition,details) .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset :-webkit-any(.admonition,details) .md-typeset__table{padding:0 .6rem}.md-typeset :-moz-any(.admonition,details) .md-typeset__table{padding:0 .6rem}.md-typeset :is(.admonition,details) .md-typeset__table{padding:0 .6rem}.md-typeset :-webkit-any(.admonition,details)>.tabbed-set:only-child{margin-top:0}.md-typeset :-moz-any(.admonition,details)>.tabbed-set:only-child{margin-top:0}.md-typeset :is(.admonition,details)>.tabbed-set:only-child{margin-top:0}html .md-typeset :-webkit-any(.admonition,details)>:last-child{margin-bottom:.6rem}html .md-typeset :-moz-any(.admonition,details)>:last-child{margin-bottom:.6rem}html .md-typeset :is(.admonition,details)>:last-child{margin-bottom:.6rem}.md-typeset :-webkit-any(.admonition-title,summary){background-color:rgba(68,138,255,.1);border:none;font-weight:700;margin-bottom:0;margin-top:0;padding-bottom:.4rem;padding-top:.4rem;position:relative}.md-typeset :-moz-any(.admonition-title,summary){background-color:rgba(68,138,255,.1);border:none;font-weight:700;margin-bottom:0;margin-top:0;padding-bottom:.4rem;padding-top:.4rem;position:relative}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){margin-left:-.8rem;margin-right:-.6rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){margin-left:-.8rem;margin-right:-.6rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){margin-left:-.8rem;margin-right:-.6rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){margin-left:-.6rem;margin-right:-.8rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){margin-left:-.6rem;margin-right:-.8rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){margin-left:-.6rem;margin-right:-.8rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){padding-left:2.2rem;padding-right:.6rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){padding-left:2.2rem;padding-right:.6rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){padding-left:2.2rem;padding-right:.6rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){padding-left:.6rem;padding-right:2.2rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){padding-left:.6rem;padding-right:2.2rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){padding-left:.6rem;padding-right:2.2rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){border-left-width:.2rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){border-left-width:.2rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){border-left-width:.2rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){border-right-width:.2rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){border-right-width:.2rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){border-right-width:.2rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){border-top-left-radius:.1rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){border-top-left-radius:.1rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){border-top-left-radius:.1rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){border-top-right-radius:.1rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){border-top-right-radius:.1rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){border-top-right-radius:.1rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){border-top-right-radius:.1rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){border-top-right-radius:.1rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){border-top-right-radius:.1rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){border-top-left-radius:.1rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){border-top-left-radius:.1rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){border-top-left-radius:.1rem}.md-typeset :is(.admonition-title,summary){background-color:rgba(68,138,255,.1);border:none;font-weight:700;margin-bottom:0;margin-top:0;padding-bottom:.4rem;padding-top:.4rem;position:relative}html .md-typeset :-webkit-any(.admonition-title,summary):last-child{margin-bottom:0}html .md-typeset :-moz-any(.admonition-title,summary):last-child{margin-bottom:0}html .md-typeset :is(.admonition-title,summary):last-child{margin-bottom:0}.md-typeset :-webkit-any(.admonition-title,summary):before{background-color:#448aff;content:"";height:1rem;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;width:1rem}.md-typeset :-moz-any(.admonition-title,summary):before{background-color:#448aff;content:"";height:1rem;mask-image:var(--md-admonition-icon--note);mask-repeat:no-repeat;mask-size:contain;position:absolute;top:.625em;width:1rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary):before{left:.8rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary):before{left:.8rem}[dir=ltr] .md-typeset :is(.admonition-title,summary):before{left:.8rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary):before{right:.8rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary):before{right:.8rem}[dir=rtl] .md-typeset :is(.admonition-title,summary):before{right:.8rem}.md-typeset :is(.admonition-title,summary):before{background-color:#448aff;content:"";height:1rem;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;width:1rem}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.note){border-color:#448aff}.md-typeset :-moz-any(.admonition,details):-moz-any(.note){border-color:#448aff}.md-typeset :is(.admonition,details):is(.note){border-color:#448aff}.md-typeset :-webkit-any(.note)>:-webkit-any(.admonition-title,summary){background-color:rgba(68,138,255,.1)}.md-typeset :-moz-any(.note)>:-moz-any(.admonition-title,summary){background-color:rgba(68,138,255,.1)}.md-typeset :is(.note)>:is(.admonition-title,summary){background-color:rgba(68,138,255,.1)}.md-typeset :-webkit-any(.note)>:-webkit-any(.admonition-title,summary):before{background-color:#448aff;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.note)>:-moz-any(.admonition-title,summary):before{background-color:#448aff;mask-image:var(--md-admonition-icon--note);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.note)>:is(.admonition-title,summary):before{background-color:#448aff;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.abstract,.summary,.tldr){border-color:#00b0ff}.md-typeset :-moz-any(.admonition,details):-moz-any(.abstract,.summary,.tldr){border-color:#00b0ff}.md-typeset :is(.admonition,details):is(.abstract,.summary,.tldr){border-color:#00b0ff}.md-typeset :-webkit-any(.abstract,.summary,.tldr)>:-webkit-any(.admonition-title,summary){background-color:rgba(0,176,255,.1)}.md-typeset :-moz-any(.abstract,.summary,.tldr)>:-moz-any(.admonition-title,summary){background-color:rgba(0,176,255,.1)}.md-typeset :is(.abstract,.summary,.tldr)>:is(.admonition-title,summary){background-color:rgba(0,176,255,.1)}.md-typeset :-webkit-any(.abstract,.summary,.tldr)>:-webkit-any(.admonition-title,summary):before{background-color:#00b0ff;-webkit-mask-image:var(--md-admonition-icon--abstract);mask-image:var(--md-admonition-icon--abstract);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.abstract,.summary,.tldr)>:-moz-any(.admonition-title,summary):before{background-color:#00b0ff;mask-image:var(--md-admonition-icon--abstract);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.abstract,.summary,.tldr)>:is(.admonition-title,summary):before{background-color:#00b0ff;-webkit-mask-image:var(--md-admonition-icon--abstract);mask-image:var(--md-admonition-icon--abstract);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.info,.todo){border-color:#00b8d4}.md-typeset :-moz-any(.admonition,details):-moz-any(.info,.todo){border-color:#00b8d4}.md-typeset :is(.admonition,details):is(.info,.todo){border-color:#00b8d4}.md-typeset :-webkit-any(.info,.todo)>:-webkit-any(.admonition-title,summary){background-color:rgba(0,184,212,.1)}.md-typeset :-moz-any(.info,.todo)>:-moz-any(.admonition-title,summary){background-color:rgba(0,184,212,.1)}.md-typeset :is(.info,.todo)>:is(.admonition-title,summary){background-color:rgba(0,184,212,.1)}.md-typeset :-webkit-any(.info,.todo)>:-webkit-any(.admonition-title,summary):before{background-color:#00b8d4;-webkit-mask-image:var(--md-admonition-icon--info);mask-image:var(--md-admonition-icon--info);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.info,.todo)>:-moz-any(.admonition-title,summary):before{background-color:#00b8d4;mask-image:var(--md-admonition-icon--info);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.info,.todo)>:is(.admonition-title,summary):before{background-color:#00b8d4;-webkit-mask-image:var(--md-admonition-icon--info);mask-image:var(--md-admonition-icon--info);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.tip,.hint,.important){border-color:#00bfa5}.md-typeset :-moz-any(.admonition,details):-moz-any(.tip,.hint,.important){border-color:#00bfa5}.md-typeset :is(.admonition,details):is(.tip,.hint,.important){border-color:#00bfa5}.md-typeset :-webkit-any(.tip,.hint,.important)>:-webkit-any(.admonition-title,summary){background-color:rgba(0,191,165,.1)}.md-typeset :-moz-any(.tip,.hint,.important)>:-moz-any(.admonition-title,summary){background-color:rgba(0,191,165,.1)}.md-typeset :is(.tip,.hint,.important)>:is(.admonition-title,summary){background-color:rgba(0,191,165,.1)}.md-typeset :-webkit-any(.tip,.hint,.important)>:-webkit-any(.admonition-title,summary):before{background-color:#00bfa5;-webkit-mask-image:var(--md-admonition-icon--tip);mask-image:var(--md-admonition-icon--tip);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.tip,.hint,.important)>:-moz-any(.admonition-title,summary):before{background-color:#00bfa5;mask-image:var(--md-admonition-icon--tip);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.tip,.hint,.important)>:is(.admonition-title,summary):before{background-color:#00bfa5;-webkit-mask-image:var(--md-admonition-icon--tip);mask-image:var(--md-admonition-icon--tip);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.success,.check,.done){border-color:#00c853}.md-typeset :-moz-any(.admonition,details):-moz-any(.success,.check,.done){border-color:#00c853}.md-typeset :is(.admonition,details):is(.success,.check,.done){border-color:#00c853}.md-typeset :-webkit-any(.success,.check,.done)>:-webkit-any(.admonition-title,summary){background-color:rgba(0,200,83,.1)}.md-typeset :-moz-any(.success,.check,.done)>:-moz-any(.admonition-title,summary){background-color:rgba(0,200,83,.1)}.md-typeset :is(.success,.check,.done)>:is(.admonition-title,summary){background-color:rgba(0,200,83,.1)}.md-typeset :-webkit-any(.success,.check,.done)>:-webkit-any(.admonition-title,summary):before{background-color:#00c853;-webkit-mask-image:var(--md-admonition-icon--success);mask-image:var(--md-admonition-icon--success);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.success,.check,.done)>:-moz-any(.admonition-title,summary):before{background-color:#00c853;mask-image:var(--md-admonition-icon--success);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.success,.check,.done)>:is(.admonition-title,summary):before{background-color:#00c853;-webkit-mask-image:var(--md-admonition-icon--success);mask-image:var(--md-admonition-icon--success);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.question,.help,.faq){border-color:#64dd17}.md-typeset :-moz-any(.admonition,details):-moz-any(.question,.help,.faq){border-color:#64dd17}.md-typeset :is(.admonition,details):is(.question,.help,.faq){border-color:#64dd17}.md-typeset :-webkit-any(.question,.help,.faq)>:-webkit-any(.admonition-title,summary){background-color:rgba(100,221,23,.1)}.md-typeset :-moz-any(.question,.help,.faq)>:-moz-any(.admonition-title,summary){background-color:rgba(100,221,23,.1)}.md-typeset :is(.question,.help,.faq)>:is(.admonition-title,summary){background-color:rgba(100,221,23,.1)}.md-typeset :-webkit-any(.question,.help,.faq)>:-webkit-any(.admonition-title,summary):before{background-color:#64dd17;-webkit-mask-image:var(--md-admonition-icon--question);mask-image:var(--md-admonition-icon--question);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.question,.help,.faq)>:-moz-any(.admonition-title,summary):before{background-color:#64dd17;mask-image:var(--md-admonition-icon--question);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.question,.help,.faq)>:is(.admonition-title,summary):before{background-color:#64dd17;-webkit-mask-image:var(--md-admonition-icon--question);mask-image:var(--md-admonition-icon--question);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.warning,.caution,.attention){border-color:#ff9100}.md-typeset :-moz-any(.admonition,details):-moz-any(.warning,.caution,.attention){border-color:#ff9100}.md-typeset :is(.admonition,details):is(.warning,.caution,.attention){border-color:#ff9100}.md-typeset :-webkit-any(.warning,.caution,.attention)>:-webkit-any(.admonition-title,summary){background-color:rgba(255,145,0,.1)}.md-typeset :-moz-any(.warning,.caution,.attention)>:-moz-any(.admonition-title,summary){background-color:rgba(255,145,0,.1)}.md-typeset :is(.warning,.caution,.attention)>:is(.admonition-title,summary){background-color:rgba(255,145,0,.1)}.md-typeset :-webkit-any(.warning,.caution,.attention)>:-webkit-any(.admonition-title,summary):before{background-color:#ff9100;-webkit-mask-image:var(--md-admonition-icon--warning);mask-image:var(--md-admonition-icon--warning);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.warning,.caution,.attention)>:-moz-any(.admonition-title,summary):before{background-color:#ff9100;mask-image:var(--md-admonition-icon--warning);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.warning,.caution,.attention)>:is(.admonition-title,summary):before{background-color:#ff9100;-webkit-mask-image:var(--md-admonition-icon--warning);mask-image:var(--md-admonition-icon--warning);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.failure,.fail,.missing){border-color:#ff5252}.md-typeset :-moz-any(.admonition,details):-moz-any(.failure,.fail,.missing){border-color:#ff5252}.md-typeset :is(.admonition,details):is(.failure,.fail,.missing){border-color:#ff5252}.md-typeset :-webkit-any(.failure,.fail,.missing)>:-webkit-any(.admonition-title,summary){background-color:rgba(255,82,82,.1)}.md-typeset :-moz-any(.failure,.fail,.missing)>:-moz-any(.admonition-title,summary){background-color:rgba(255,82,82,.1)}.md-typeset :is(.failure,.fail,.missing)>:is(.admonition-title,summary){background-color:rgba(255,82,82,.1)}.md-typeset :-webkit-any(.failure,.fail,.missing)>:-webkit-any(.admonition-title,summary):before{background-color:#ff5252;-webkit-mask-image:var(--md-admonition-icon--failure);mask-image:var(--md-admonition-icon--failure);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.failure,.fail,.missing)>:-moz-any(.admonition-title,summary):before{background-color:#ff5252;mask-image:var(--md-admonition-icon--failure);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.failure,.fail,.missing)>:is(.admonition-title,summary):before{background-color:#ff5252;-webkit-mask-image:var(--md-admonition-icon--failure);mask-image:var(--md-admonition-icon--failure);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.danger,.error){border-color:#ff1744}.md-typeset :-moz-any(.admonition,details):-moz-any(.danger,.error){border-color:#ff1744}.md-typeset :is(.admonition,details):is(.danger,.error){border-color:#ff1744}.md-typeset :-webkit-any(.danger,.error)>:-webkit-any(.admonition-title,summary){background-color:rgba(255,23,68,.1)}.md-typeset :-moz-any(.danger,.error)>:-moz-any(.admonition-title,summary){background-color:rgba(255,23,68,.1)}.md-typeset :is(.danger,.error)>:is(.admonition-title,summary){background-color:rgba(255,23,68,.1)}.md-typeset :-webkit-any(.danger,.error)>:-webkit-any(.admonition-title,summary):before{background-color:#ff1744;-webkit-mask-image:var(--md-admonition-icon--danger);mask-image:var(--md-admonition-icon--danger);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.danger,.error)>:-moz-any(.admonition-title,summary):before{background-color:#ff1744;mask-image:var(--md-admonition-icon--danger);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.danger,.error)>:is(.admonition-title,summary):before{background-color:#ff1744;-webkit-mask-image:var(--md-admonition-icon--danger);mask-image:var(--md-admonition-icon--danger);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.bug){border-color:#f50057}.md-typeset :-moz-any(.admonition,details):-moz-any(.bug){border-color:#f50057}.md-typeset :is(.admonition,details):is(.bug){border-color:#f50057}.md-typeset :-webkit-any(.bug)>:-webkit-any(.admonition-title,summary){background-color:rgba(245,0,87,.1)}.md-typeset :-moz-any(.bug)>:-moz-any(.admonition-title,summary){background-color:rgba(245,0,87,.1)}.md-typeset :is(.bug)>:is(.admonition-title,summary){background-color:rgba(245,0,87,.1)}.md-typeset :-webkit-any(.bug)>:-webkit-any(.admonition-title,summary):before{background-color:#f50057;-webkit-mask-image:var(--md-admonition-icon--bug);mask-image:var(--md-admonition-icon--bug);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.bug)>:-moz-any(.admonition-title,summary):before{background-color:#f50057;mask-image:var(--md-admonition-icon--bug);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.bug)>:is(.admonition-title,summary):before{background-color:#f50057;-webkit-mask-image:var(--md-admonition-icon--bug);mask-image:var(--md-admonition-icon--bug);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.example){border-color:#7c4dff}.md-typeset :-moz-any(.admonition,details):-moz-any(.example){border-color:#7c4dff}.md-typeset :is(.admonition,details):is(.example){border-color:#7c4dff}.md-typeset :-webkit-any(.example)>:-webkit-any(.admonition-title,summary){background-color:rgba(124,77,255,.1)}.md-typeset :-moz-any(.example)>:-moz-any(.admonition-title,summary){background-color:rgba(124,77,255,.1)}.md-typeset :is(.example)>:is(.admonition-title,summary){background-color:rgba(124,77,255,.1)}.md-typeset :-webkit-any(.example)>:-webkit-any(.admonition-title,summary):before{background-color:#7c4dff;-webkit-mask-image:var(--md-admonition-icon--example);mask-image:var(--md-admonition-icon--example);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.example)>:-moz-any(.admonition-title,summary):before{background-color:#7c4dff;mask-image:var(--md-admonition-icon--example);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.example)>:is(.admonition-title,summary):before{background-color:#7c4dff;-webkit-mask-image:var(--md-admonition-icon--example);mask-image:var(--md-admonition-icon--example);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.quote,.cite){border-color:#9e9e9e}.md-typeset :-moz-any(.admonition,details):-moz-any(.quote,.cite){border-color:#9e9e9e}.md-typeset :is(.admonition,details):is(.quote,.cite){border-color:#9e9e9e}.md-typeset :-webkit-any(.quote,.cite)>:-webkit-any(.admonition-title,summary){background-color:hsla(0,0%,62%,.1)}.md-typeset :-moz-any(.quote,.cite)>:-moz-any(.admonition-title,summary){background-color:hsla(0,0%,62%,.1)}.md-typeset :is(.quote,.cite)>:is(.admonition-title,summary){background-color:hsla(0,0%,62%,.1)}.md-typeset :-webkit-any(.quote,.cite)>:-webkit-any(.admonition-title,summary):before{background-color:#9e9e9e;-webkit-mask-image:var(--md-admonition-icon--quote);mask-image:var(--md-admonition-icon--quote);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.quote,.cite)>:-moz-any(.admonition-title,summary):before{background-color:#9e9e9e;mask-image:var(--md-admonition-icon--quote);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.quote,.cite)>:is(.admonition-title,summary):before{background-color:#9e9e9e;-webkit-mask-image:var(--md-admonition-icon--quote);mask-image:var(--md-admonition-icon--quote);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}:root{--md-footnotes-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .footnote{color:var(--md-default-fg-color--light);font-size:.64rem}[dir=ltr] .md-typeset .footnote>ol{margin-left:0}[dir=rtl] .md-typeset .footnote>ol{margin-right:0}.md-typeset .footnote>ol>li{transition:color 125ms}.md-typeset .footnote>ol>li:target{color:var(--md-default-fg-color)}.md-typeset .footnote>ol>li:focus-within .footnote-backref{opacity:1;transform:translateX(0);transition:none}.md-typeset .footnote>ol>li:-webkit-any(:hover,:target) .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li:-moz-any(:hover,:target) .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li:is(:hover,:target) .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li>:first-child{margin-top:0}.md-typeset .footnote-ref{font-size:.75em;font-weight:700}html .md-typeset .footnote-ref{outline-offset:.1rem}.md-typeset [id^="fnref:"]:target>.footnote-ref{outline:auto}.md-typeset .footnote-backref{color:var(--md-typeset-a-color);display:inline-block;font-size:0;opacity:0;transform:translateX(.25rem);transition:color .25s,transform .25s .25s,opacity 125ms .25s;vertical-align:text-bottom}@media print{.md-typeset .footnote-backref{color:var(--md-typeset-a-color);opacity:1;transform:translateX(0)}}[dir=rtl] .md-typeset .footnote-backref{transform:translateX(-.25rem)}.md-typeset .footnote-backref:hover{color:var(--md-accent-fg-color)}.md-typeset .footnote-backref:before{background-color:currentcolor;content:"";display:inline-block;height:.8rem;-webkit-mask-image:var(--md-footnotes-icon);mask-image:var(--md-footnotes-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.8rem}[dir=rtl] .md-typeset .footnote-backref:before svg{transform:scaleX(-1)}[dir=ltr] .md-typeset .headerlink{margin-left:.5rem}[dir=rtl] .md-typeset .headerlink{margin-right:.5rem}.md-typeset .headerlink{color:var(--md-default-fg-color--lighter);display:inline-block;opacity:0;transition:color .25s,opacity 125ms}@media print{.md-typeset .headerlink{display:none}}.md-typeset .headerlink:focus,.md-typeset :-webkit-any(:hover,:target)>.headerlink{opacity:1;-webkit-transition:color .25s,opacity 125ms;transition:color .25s,opacity 125ms}.md-typeset .headerlink:focus,.md-typeset :-moz-any(:hover,:target)>.headerlink{opacity:1;-moz-transition:color .25s,opacity 125ms;transition:color .25s,opacity 125ms}.md-typeset .headerlink:focus,.md-typeset :is(:hover,:target)>.headerlink{opacity:1;transition:color .25s,opacity 125ms}.md-typeset .headerlink:-webkit-any(:focus,:hover),.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset .headerlink:-moz-any(:focus,:hover),.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset .headerlink:is(:focus,:hover),.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset :target{--md-scroll-margin:3.6rem;--md-scroll-offset:0rem;scroll-margin-top:calc(var(--md-scroll-margin) - var(--md-scroll-offset))}@media screen and (min-width:76.25em){.md-header--lifted~.md-container .md-typeset :target{--md-scroll-margin:6rem}}.md-typeset :-webkit-any(h1,h2,h3):target{--md-scroll-offset:0.2rem}.md-typeset :-moz-any(h1,h2,h3):target{--md-scroll-offset:0.2rem}.md-typeset :is(h1,h2,h3):target{--md-scroll-offset:0.2rem}.md-typeset h4:target{--md-scroll-offset:0.15rem}.md-typeset div.arithmatex{overflow:auto}@media screen and (max-width:44.9375em){.md-typeset div.arithmatex{margin:0 -.8rem}}.md-typeset div.arithmatex>*{margin-left:auto!important;margin-right:auto!important;padding:0 .8rem;touch-action:auto;width:-webkit-min-content;width:-moz-min-content;width:min-content}.md-typeset div.arithmatex>* mjx-container{margin:0!important}.md-typeset :-webkit-any(del,ins,.comment).critic{-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset :-moz-any(del,ins,.comment).critic{box-decoration-break:clone}.md-typeset :is(del,ins,.comment).critic{-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset del.critic{background-color:var(--md-typeset-del-color)}.md-typeset ins.critic{background-color:var(--md-typeset-ins-color)}.md-typeset .critic.comment{color:var(--md-code-hl-comment-color)}.md-typeset .critic.comment:before{content:"/* "}.md-typeset .critic.comment:after{content:" */"}.md-typeset .critic.block{box-shadow:none;display:block;margin:1em 0;overflow:auto;padding-left:.8rem;padding-right:.8rem}.md-typeset .critic.block>:first-child{margin-top:.5em}.md-typeset .critic.block>:last-child{margin-bottom:.5em}:root{--md-details-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset details{display:flow-root;overflow:visible;padding-top:0}.md-typeset details[open]>summary:after{transform:rotate(90deg)}.md-typeset details:not([open]){box-shadow:none;padding-bottom:0}.md-typeset details:not([open])>summary{border-radius:.1rem}[dir=ltr] .md-typeset summary{padding-right:1.8rem}[dir=rtl] .md-typeset summary{padding-left:1.8rem}[dir=ltr] .md-typeset summary{border-top-left-radius:.1rem}[dir=ltr] .md-typeset summary,[dir=rtl] .md-typeset summary{border-top-right-radius:.1rem}[dir=rtl] .md-typeset summary{border-top-left-radius:.1rem}.md-typeset summary{cursor:pointer;display:block;min-height:1rem}.md-typeset summary.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset summary:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[dir=ltr] .md-typeset summary:after{right:.4rem}[dir=rtl] .md-typeset summary:after{left:.4rem}.md-typeset summary:after{background-color:currentcolor;content:"";height:1rem;-webkit-mask-image:var(--md-details-icon);mask-image:var(--md-details-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;transform:rotate(0deg);transition:transform .25s;width:1rem}[dir=rtl] .md-typeset summary:after{transform:rotate(180deg)}.md-typeset summary::marker{display:none}.md-typeset summary::-webkit-details-marker{display:none}.md-typeset :-webkit-any(.emojione,.twemoji,.gemoji){display:inline-flex;height:1.125em;vertical-align:text-top}.md-typeset :-moz-any(.emojione,.twemoji,.gemoji){display:inline-flex;height:1.125em;vertical-align:text-top}.md-typeset :is(.emojione,.twemoji,.gemoji){display:inline-flex;height:1.125em;vertical-align:text-top}.md-typeset :-webkit-any(.emojione,.twemoji,.gemoji) svg{fill:currentcolor;max-height:100%;width:1.125em}.md-typeset :-moz-any(.emojione,.twemoji,.gemoji) svg{fill:currentcolor;max-height:100%;width:1.125em}.md-typeset :is(.emojione,.twemoji,.gemoji) svg{fill:currentcolor;max-height:100%;width:1.125em}.highlight :-webkit-any(.o,.ow){color:var(--md-code-hl-operator-color)}.highlight :-moz-any(.o,.ow){color:var(--md-code-hl-operator-color)}.highlight :is(.o,.ow){color:var(--md-code-hl-operator-color)}.highlight .p{color:var(--md-code-hl-punctuation-color)}.highlight :-webkit-any(.cpf,.l,.s,.sb,.sc,.s2,.si,.s1,.ss){color:var(--md-code-hl-string-color)}.highlight :-moz-any(.cpf,.l,.s,.sb,.sc,.s2,.si,.s1,.ss){color:var(--md-code-hl-string-color)}.highlight :is(.cpf,.l,.s,.sb,.sc,.s2,.si,.s1,.ss){color:var(--md-code-hl-string-color)}.highlight :-webkit-any(.cp,.se,.sh,.sr,.sx){color:var(--md-code-hl-special-color)}.highlight :-moz-any(.cp,.se,.sh,.sr,.sx){color:var(--md-code-hl-special-color)}.highlight :is(.cp,.se,.sh,.sr,.sx){color:var(--md-code-hl-special-color)}.highlight :-webkit-any(.m,.mb,.mf,.mh,.mi,.il,.mo){color:var(--md-code-hl-number-color)}.highlight :-moz-any(.m,.mb,.mf,.mh,.mi,.il,.mo){color:var(--md-code-hl-number-color)}.highlight :is(.m,.mb,.mf,.mh,.mi,.il,.mo){color:var(--md-code-hl-number-color)}.highlight :-webkit-any(.k,.kd,.kn,.kp,.kr,.kt){color:var(--md-code-hl-keyword-color)}.highlight :-moz-any(.k,.kd,.kn,.kp,.kr,.kt){color:var(--md-code-hl-keyword-color)}.highlight :is(.k,.kd,.kn,.kp,.kr,.kt){color:var(--md-code-hl-keyword-color)}.highlight :-webkit-any(.kc,.n){color:var(--md-code-hl-name-color)}.highlight :-moz-any(.kc,.n){color:var(--md-code-hl-name-color)}.highlight :is(.kc,.n){color:var(--md-code-hl-name-color)}.highlight :-webkit-any(.no,.nb,.bp){color:var(--md-code-hl-constant-color)}.highlight :-moz-any(.no,.nb,.bp){color:var(--md-code-hl-constant-color)}.highlight :is(.no,.nb,.bp){color:var(--md-code-hl-constant-color)}.highlight :-webkit-any(.nc,.ne,.nf,.nn){color:var(--md-code-hl-function-color)}.highlight :-moz-any(.nc,.ne,.nf,.nn){color:var(--md-code-hl-function-color)}.highlight :is(.nc,.ne,.nf,.nn){color:var(--md-code-hl-function-color)}.highlight :-webkit-any(.nd,.ni,.nl,.nt){color:var(--md-code-hl-keyword-color)}.highlight :-moz-any(.nd,.ni,.nl,.nt){color:var(--md-code-hl-keyword-color)}.highlight :is(.nd,.ni,.nl,.nt){color:var(--md-code-hl-keyword-color)}.highlight :-webkit-any(.c,.cm,.c1,.ch,.cs,.sd){color:var(--md-code-hl-comment-color)}.highlight :-moz-any(.c,.cm,.c1,.ch,.cs,.sd){color:var(--md-code-hl-comment-color)}.highlight :is(.c,.cm,.c1,.ch,.cs,.sd){color:var(--md-code-hl-comment-color)}.highlight :-webkit-any(.na,.nv,.vc,.vg,.vi){color:var(--md-code-hl-variable-color)}.highlight :-moz-any(.na,.nv,.vc,.vg,.vi){color:var(--md-code-hl-variable-color)}.highlight :is(.na,.nv,.vc,.vg,.vi){color:var(--md-code-hl-variable-color)}.highlight :-webkit-any(.ge,.gr,.gh,.go,.gp,.gs,.gu,.gt){color:var(--md-code-hl-generic-color)}.highlight :-moz-any(.ge,.gr,.gh,.go,.gp,.gs,.gu,.gt){color:var(--md-code-hl-generic-color)}.highlight :is(.ge,.gr,.gh,.go,.gp,.gs,.gu,.gt){color:var(--md-code-hl-generic-color)}.highlight :-webkit-any(.gd,.gi){border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight :-moz-any(.gd,.gi){border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight :is(.gd,.gi){border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight .gd{background-color:var(--md-typeset-del-color)}.highlight .gi{background-color:var(--md-typeset-ins-color)}.highlight .hll{background-color:var(--md-code-hl-color);display:block;margin:0 -1.1764705882em;padding:0 1.1764705882em}.highlight span.filename{background-color:var(--md-code-bg-color);border-bottom:.05rem solid var(--md-default-fg-color--lightest);border-top-left-radius:.1rem;border-top-right-radius:.1rem;display:flow-root;font-size:.85em;font-weight:700;margin-top:1em;padding:.6617647059em 1.1764705882em;position:relative}.highlight span.filename+pre{margin-top:0}.highlight span.filename+pre>code{border-top-left-radius:0;border-top-right-radius:0}.highlight [data-linenos]:before{background-color:var(--md-code-bg-color);box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset;color:var(--md-default-fg-color--light);content:attr(data-linenos);float:left;left:-1.1764705882em;margin-left:-1.1764705882em;margin-right:1.1764705882em;padding-left:1.1764705882em;position:-webkit-sticky;position:sticky;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:3}.highlight code a[id]{position:absolute;visibility:hidden}.highlight code[data-md-copying] .hll{display:contents}.highlight code[data-md-copying] .md-annotation{display:none}.highlighttable{display:flow-root}.highlighttable :-webkit-any(tbody,td){display:block;padding:0}.highlighttable :-moz-any(tbody,td){display:block;padding:0}.highlighttable :is(tbody,td){display:block;padding:0}.highlighttable tr{display:flex}.highlighttable pre{margin:0}.highlighttable th.filename{flex-grow:1;padding:0;text-align:left}.highlighttable th.filename span.filename{margin-top:0}.highlighttable .linenos{background-color:var(--md-code-bg-color);border-bottom-left-radius:.1rem;border-top-left-radius:.1rem;font-size:.85em;padding:.7720588235em 0 .7720588235em 1.1764705882em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.highlighttable .linenodiv{box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset;padding-right:.5882352941em}.highlighttable .linenodiv pre{color:var(--md-default-fg-color--light);text-align:right}.highlighttable .code{flex:1;min-width:0}.linenodiv a{color:inherit}.md-typeset .highlighttable{direction:ltr;margin:1em 0}.md-typeset .highlighttable>tbody>tr>.code>div>pre>code{border-bottom-left-radius:0;border-top-left-radius:0}.md-typeset .highlight+.result{border:.05rem solid var(--md-code-bg-color);border-bottom-left-radius:.1rem;border-bottom-right-radius:.1rem;border-top-width:.1rem;margin-top:-1.125em;overflow:visible;padding:0 1em}.md-typeset .highlight+.result:after{clear:both;content:"";display:block}@media screen and (max-width:44.9375em){.md-content__inner>.highlight{margin:1em -.8rem}.md-content__inner>.highlight>.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.code>div>pre>code,.md-content__inner>.highlight>.highlighttable>tbody>tr>.filename span.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.linenos,.md-content__inner>.highlight>pre>code{border-radius:0}.md-content__inner>.highlight+.result{border-left-width:0;border-radius:0;border-right-width:0;margin-left:-.8rem;margin-right:-.8rem}}.md-typeset .keys kbd:-webkit-any(:before,:after){-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys kbd:-moz-any(:before,:after){-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys kbd:is(:before,:after){-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys span{color:var(--md-default-fg-color--light);padding:0 .2em}.md-typeset .keys .key-alt:before,.md-typeset .keys .key-left-alt:before,.md-typeset .keys .key-right-alt:before{content:"⎇";padding-right:.4em}.md-typeset .keys .key-command:before,.md-typeset .keys .key-left-command:before,.md-typeset .keys .key-right-command:before{content:"⌘";padding-right:.4em}.md-typeset .keys .key-control:before,.md-typeset .keys .key-left-control:before,.md-typeset .keys .key-right-control:before{content:"⌃";padding-right:.4em}.md-typeset .keys .key-left-meta:before,.md-typeset .keys .key-meta:before,.md-typeset .keys .key-right-meta:before{content:"◆";padding-right:.4em}.md-typeset .keys .key-left-option:before,.md-typeset .keys .key-option:before,.md-typeset .keys .key-right-option:before{content:"⌥";padding-right:.4em}.md-typeset .keys .key-left-shift:before,.md-typeset .keys .key-right-shift:before,.md-typeset .keys .key-shift:before{content:"⇧";padding-right:.4em}.md-typeset .keys .key-left-super:before,.md-typeset .keys .key-right-super:before,.md-typeset .keys .key-super:before{content:"❖";padding-right:.4em}.md-typeset .keys .key-left-windows:before,.md-typeset .keys .key-right-windows:before,.md-typeset .keys .key-windows:before{content:"⊞";padding-right:.4em}.md-typeset .keys .key-arrow-down:before{content:"↓";padding-right:.4em}.md-typeset .keys .key-arrow-left:before{content:"←";padding-right:.4em}.md-typeset .keys .key-arrow-right:before{content:"→";padding-right:.4em}.md-typeset .keys .key-arrow-up:before{content:"↑";padding-right:.4em}.md-typeset .keys .key-backspace:before{content:"⌫";padding-right:.4em}.md-typeset .keys .key-backtab:before{content:"⇤";padding-right:.4em}.md-typeset .keys .key-caps-lock:before{content:"⇪";padding-right:.4em}.md-typeset .keys .key-clear:before{content:"⌧";padding-right:.4em}.md-typeset .keys .key-context-menu:before{content:"☰";padding-right:.4em}.md-typeset .keys .key-delete:before{content:"⌦";padding-right:.4em}.md-typeset .keys .key-eject:before{content:"⏏";padding-right:.4em}.md-typeset .keys .key-end:before{content:"⤓";padding-right:.4em}.md-typeset .keys .key-escape:before{content:"⎋";padding-right:.4em}.md-typeset .keys .key-home:before{content:"⤒";padding-right:.4em}.md-typeset .keys .key-insert:before{content:"⎀";padding-right:.4em}.md-typeset .keys .key-page-down:before{content:"⇟";padding-right:.4em}.md-typeset .keys .key-page-up:before{content:"⇞";padding-right:.4em}.md-typeset .keys .key-print-screen:before{content:"⎙";padding-right:.4em}.md-typeset .keys .key-tab:after{content:"⇥";padding-left:.4em}.md-typeset .keys .key-num-enter:after{content:"⌤";padding-left:.4em}.md-typeset .keys .key-enter:after{content:"⏎";padding-left:.4em}:root{--md-tabbed-icon--prev:url('data:image/svg+xml;charset=utf-8,');--md-tabbed-icon--next:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .tabbed-set{border-radius:.1rem;display:flex;flex-flow:column wrap;margin:1em 0;position:relative}.md-typeset .tabbed-set>input{height:0;opacity:0;position:absolute;width:0}.md-typeset .tabbed-set>input:target{--md-scroll-offset:0.625em}.md-typeset .tabbed-labels{-ms-overflow-style:none;box-shadow:0 -.05rem var(--md-default-fg-color--lightest) inset;display:flex;max-width:100%;overflow:auto;scrollbar-width:none}@media print{.md-typeset .tabbed-labels{display:contents}}@media screen{.js .md-typeset .tabbed-labels{position:relative}.js .md-typeset .tabbed-labels:before{background:var(--md-accent-fg-color);bottom:0;content:"";display:block;height:2px;left:0;position:absolute;transform:translateX(var(--md-indicator-x));transition:width 225ms,transform .25s;transition-timing-function:cubic-bezier(.4,0,.2,1);width:var(--md-indicator-width)}}.md-typeset .tabbed-labels::-webkit-scrollbar{display:none}.md-typeset .tabbed-labels>label{border-bottom:.1rem solid transparent;border-radius:.1rem .1rem 0 0;color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;font-size:.64rem;font-weight:700;padding:.78125em 1.25em .625em;scroll-margin-inline-start:1rem;transition:background-color .25s,color .25s;white-space:nowrap;width:auto}@media print{.md-typeset .tabbed-labels>label:first-child{order:1}.md-typeset .tabbed-labels>label:nth-child(2){order:2}.md-typeset .tabbed-labels>label:nth-child(3){order:3}.md-typeset .tabbed-labels>label:nth-child(4){order:4}.md-typeset .tabbed-labels>label:nth-child(5){order:5}.md-typeset .tabbed-labels>label:nth-child(6){order:6}.md-typeset .tabbed-labels>label:nth-child(7){order:7}.md-typeset .tabbed-labels>label:nth-child(8){order:8}.md-typeset .tabbed-labels>label:nth-child(9){order:9}.md-typeset .tabbed-labels>label:nth-child(10){order:10}.md-typeset .tabbed-labels>label:nth-child(11){order:11}.md-typeset .tabbed-labels>label:nth-child(12){order:12}.md-typeset .tabbed-labels>label:nth-child(13){order:13}.md-typeset .tabbed-labels>label:nth-child(14){order:14}.md-typeset .tabbed-labels>label:nth-child(15){order:15}.md-typeset .tabbed-labels>label:nth-child(16){order:16}.md-typeset .tabbed-labels>label:nth-child(17){order:17}.md-typeset .tabbed-labels>label:nth-child(18){order:18}.md-typeset .tabbed-labels>label:nth-child(19){order:19}.md-typeset .tabbed-labels>label:nth-child(20){order:20}}.md-typeset .tabbed-labels>label:hover{color:var(--md-accent-fg-color)}.md-typeset .tabbed-content{width:100%}@media print{.md-typeset .tabbed-content{display:contents}}.md-typeset .tabbed-block{display:none}@media print{.md-typeset .tabbed-block{display:block}.md-typeset .tabbed-block:first-child{order:1}.md-typeset .tabbed-block:nth-child(2){order:2}.md-typeset .tabbed-block:nth-child(3){order:3}.md-typeset .tabbed-block:nth-child(4){order:4}.md-typeset .tabbed-block:nth-child(5){order:5}.md-typeset .tabbed-block:nth-child(6){order:6}.md-typeset .tabbed-block:nth-child(7){order:7}.md-typeset .tabbed-block:nth-child(8){order:8}.md-typeset .tabbed-block:nth-child(9){order:9}.md-typeset .tabbed-block:nth-child(10){order:10}.md-typeset .tabbed-block:nth-child(11){order:11}.md-typeset .tabbed-block:nth-child(12){order:12}.md-typeset .tabbed-block:nth-child(13){order:13}.md-typeset .tabbed-block:nth-child(14){order:14}.md-typeset .tabbed-block:nth-child(15){order:15}.md-typeset .tabbed-block:nth-child(16){order:16}.md-typeset .tabbed-block:nth-child(17){order:17}.md-typeset .tabbed-block:nth-child(18){order:18}.md-typeset .tabbed-block:nth-child(19){order:19}.md-typeset .tabbed-block:nth-child(20){order:20}}.md-typeset .tabbed-block>.highlight:first-child>pre,.md-typeset .tabbed-block>pre:first-child{margin:0}.md-typeset .tabbed-block>.highlight:first-child>pre>code,.md-typeset .tabbed-block>pre:first-child>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child>.filename{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable{margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.filename span.filename,.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.linenos{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.code>div>pre>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child+.result{margin-top:-.125em}.md-typeset .tabbed-block>.tabbed-set{margin:0}.md-typeset .tabbed-button{align-self:center;border-radius:100%;color:var(--md-default-fg-color--light);cursor:pointer;display:block;height:.9rem;margin-top:.1rem;pointer-events:auto;transition:background-color .25s;width:.9rem}.md-typeset .tabbed-button:hover{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-typeset .tabbed-button:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-tabbed-icon--prev);mask-image:var(--md-tabbed-icon--prev);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color .25s,transform .25s;width:100%}.md-typeset .tabbed-control{background:linear-gradient(to right,var(--md-default-bg-color) 60%,transparent);display:flex;height:1.9rem;justify-content:start;pointer-events:none;position:absolute;transition:opacity 125ms;width:1.2rem}[dir=rtl] .md-typeset .tabbed-control{transform:rotate(180deg)}.md-typeset .tabbed-control[hidden]{opacity:0}.md-typeset .tabbed-control--next{background:linear-gradient(to left,var(--md-default-bg-color) 60%,transparent);justify-content:end;right:0}.md-typeset .tabbed-control--next .tabbed-button:after{-webkit-mask-image:var(--md-tabbed-icon--next);mask-image:var(--md-tabbed-icon--next)}@media screen and (max-width:44.9375em){[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels{padding-right:.8rem}.md-content__inner>.tabbed-set .tabbed-labels{margin:0 -.8rem;max-width:100vw;scroll-padding-inline-start:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-left:.8rem}.md-content__inner>.tabbed-set .tabbed-labels:after{content:""}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{margin-left:-.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{margin-right:-.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{padding-right:.8rem}.md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{width:2rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{margin-right:-.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{margin-left:-.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{padding-left:.8rem}.md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{width:2rem}}@media screen{.md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){color:var(--md-accent-fg-color)}.md-typeset .no-js .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .no-js .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .no-js .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .no-js .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .no-js .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .no-js .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .no-js .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .no-js .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .no-js .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .no-js .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .no-js .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .no-js .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .no-js .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .no-js .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .no-js .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .no-js .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .no-js .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .no-js .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .no-js .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .no-js .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9),.no-js .md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.no-js .md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.no-js .md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.no-js .md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.no-js .md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.no-js .md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.no-js .md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.no-js .md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.no-js .md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.no-js .md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.no-js .md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.no-js .md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.no-js .md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.no-js .md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.no-js .md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.no-js .md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.no-js .md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.no-js .md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.no-js .md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.no-js .md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){border-color:var(--md-accent-fg-color)}}.md-typeset .tabbed-set>input:first-child.focus-visible~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10).focus-visible~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11).focus-visible~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12).focus-visible~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13).focus-visible~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14).focus-visible~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15).focus-visible~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16).focus-visible~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17).focus-visible~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18).focus-visible~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19).focus-visible~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2).focus-visible~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20).focus-visible~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3).focus-visible~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4).focus-visible~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5).focus-visible~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6).focus-visible~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7).focus-visible~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8).focus-visible~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9).focus-visible~.tabbed-labels>:nth-child(9){background-color:var(--md-accent-fg-color--transparent)}.md-typeset .tabbed-set>input:first-child:checked~.tabbed-content>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-content>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-content>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-content>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-content>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-content>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-content>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-content>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-content>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-content>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-content>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-content>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-content>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-content>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-content>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-content>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-content>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-content>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-content>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-content>:nth-child(9){display:block}:root{--md-tasklist-icon:url('data:image/svg+xml;charset=utf-8,');--md-tasklist-icon--checked:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .task-list-item{list-style-type:none;position:relative}[dir=ltr] .md-typeset .task-list-item [type=checkbox]{left:-2em}[dir=rtl] .md-typeset .task-list-item [type=checkbox]{right:-2em}.md-typeset .task-list-item [type=checkbox]{position:absolute;top:.45em}.md-typeset .task-list-control [type=checkbox]{opacity:0;z-index:-1}[dir=ltr] .md-typeset .task-list-indicator:before{left:-1.5em}[dir=rtl] .md-typeset .task-list-indicator:before{right:-1.5em}.md-typeset .task-list-indicator:before{background-color:var(--md-default-fg-color--lightest);content:"";height:1.25em;-webkit-mask-image:var(--md-tasklist-icon);mask-image:var(--md-tasklist-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.15em;width:1.25em}.md-typeset [type=checkbox]:checked+.task-list-indicator:before{background-color:#00e676;-webkit-mask-image:var(--md-tasklist-icon--checked);mask-image:var(--md-tasklist-icon--checked)}:root>*{--md-mermaid-font-family:var(--md-text-font-family),sans-serif;--md-mermaid-edge-color:var(--md-code-fg-color);--md-mermaid-node-bg-color:var(--md-accent-fg-color--transparent);--md-mermaid-node-fg-color:var(--md-accent-fg-color);--md-mermaid-label-bg-color:var(--md-default-bg-color);--md-mermaid-label-fg-color:var(--md-code-fg-color)}.mermaid{line-height:normal;margin:1em 0}@media screen and (min-width:45em){[dir=ltr] .md-typeset .inline{margin-right:.8rem}[dir=rtl] .md-typeset .inline{margin-left:.8rem}.md-typeset .inline{float:left;margin-bottom:.8rem;margin-top:0;width:11.7rem}[dir=rtl] .md-typeset .inline{float:right}[dir=ltr] .md-typeset .inline.end{margin-left:.8rem;margin-right:0}[dir=rtl] .md-typeset .inline.end{margin-left:0;margin-right:.8rem}.md-typeset .inline.end{float:right}[dir=rtl] .md-typeset .inline.end{float:left}} \ No newline at end of file diff --git a/assets/stylesheets/main.69437709.min.css.map b/assets/stylesheets/main.69437709.min.css.map new file mode 100644 index 000000000..4c560661a --- /dev/null +++ b/assets/stylesheets/main.69437709.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["src/assets/stylesheets/main/extensions/pymdownx/_keys.scss","../../../src/assets/stylesheets/main.scss","src/assets/stylesheets/main/_resets.scss","src/assets/stylesheets/main/_colors.scss","src/assets/stylesheets/main/_icons.scss","src/assets/stylesheets/main/_typeset.scss","src/assets/stylesheets/utilities/_break.scss","src/assets/stylesheets/main/layout/_banner.scss","src/assets/stylesheets/main/layout/_base.scss","src/assets/stylesheets/main/layout/_clipboard.scss","src/assets/stylesheets/main/layout/_consent.scss","src/assets/stylesheets/main/layout/_content.scss","src/assets/stylesheets/main/layout/_dialog.scss","src/assets/stylesheets/main/layout/_feedback.scss","src/assets/stylesheets/main/layout/_footer.scss","src/assets/stylesheets/main/layout/_form.scss","src/assets/stylesheets/main/layout/_header.scss","src/assets/stylesheets/main/layout/_nav.scss","src/assets/stylesheets/main/layout/_search.scss","src/assets/stylesheets/main/layout/_select.scss","src/assets/stylesheets/main/layout/_sidebar.scss","src/assets/stylesheets/main/layout/_source.scss","src/assets/stylesheets/main/layout/_tabs.scss","src/assets/stylesheets/main/layout/_tag.scss","src/assets/stylesheets/main/layout/_tooltip.scss","src/assets/stylesheets/main/layout/_top.scss","src/assets/stylesheets/main/layout/_version.scss","src/assets/stylesheets/main/extensions/markdown/_admonition.scss","node_modules/material-design-color/material-color.scss","src/assets/stylesheets/main/extensions/markdown/_footnotes.scss","src/assets/stylesheets/main/extensions/markdown/_toc.scss","src/assets/stylesheets/main/extensions/pymdownx/_arithmatex.scss","src/assets/stylesheets/main/extensions/pymdownx/_critic.scss","src/assets/stylesheets/main/extensions/pymdownx/_details.scss","src/assets/stylesheets/main/extensions/pymdownx/_emoji.scss","src/assets/stylesheets/main/extensions/pymdownx/_highlight.scss","src/assets/stylesheets/main/extensions/pymdownx/_tabbed.scss","src/assets/stylesheets/main/extensions/pymdownx/_tasklist.scss","src/assets/stylesheets/main/integrations/_mermaid.scss","src/assets/stylesheets/main/_modifiers.scss"],"names":[],"mappings":"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CALA,UnC4lHN,CmC7kHM,aAII,6CACE,OnC4kHV,CmC7kHQ,8CACE,OnC+kHV,CmChlHQ,8CACE,OnCklHV,CmCnlHQ,8CACE,OnCqlHV,CmCtlHQ,8CACE,OnCwlHV,CmCzlHQ,8CACE,OnC2lHV,CmC5lHQ,8CACE,OnC8lHV,CmC/lHQ,8CACE,OnCimHV,CmClmHQ,8CACE,OnComHV,CmCrmHQ,+CACE,QnCumHV,CmCxmHQ,+CACE,QnC0mHV,CmC3mHQ,+CACE,QnC6mHV,CmC9mHQ,+CACE,QnCgnHV,CmCjnHQ,+CACE,QnCmnHV,CmCpnHQ,+CACE,QnCsnHV,CmCvnHQ,+CACE,QnCynHV,CmC1nHQ,+CACE,QnC4nHV,CmC7nHQ,+CACE,QnC+nHV,CmChoHQ,+CACE,QnCkoHV,CmCnoHQ,+CACE,QnCqoHV,CACF,CmChoHM,uCACE,+BnCkoHR,CmC5nHE,4BACE,UnC8nHJ,CmC3nHI,aAJF,4BAKI,gBnC8nHJ,CACF,CmC1nHE,0BACE,YnC4nHJ,CmCznHI,aAJF,0BAKI,anC4nHJ,CmCxnHM,sCACE,OnC0nHR,CmC3nHM,uCACE,OnC6nHR,CmC9nHM,uCACE,OnCgoHR,CmCjoHM,uCACE,OnCmoHR,CmCpoHM,uCACE,OnCsoHR,CmCvoHM,uCACE,OnCyoHR,CmC1oHM,uCACE,OnC4oHR,CmC7oHM,uCACE,OnC+oHR,CmChpHM,uCACE,OnCkpHR,CmCnpHM,wCACE,QnCqpHR,CmCtpHM,wCACE,QnCwpHR,CmCzpHM,wCACE,QnC2pHR,CmC5pHM,wCACE,QnC8pHR,CmC/pHM,wCACE,QnCiqHR,CmClqHM,wCACE,QnCoqHR,CmCrqHM,wCACE,QnCuqHR,CmCxqHM,wCACE,QnC0qHR,CmC3qHM,wCACE,QnC6qHR,CmC9qHM,wCACE,QnCgrHR,CmCjrHM,wCACE,QnCmrHR,CACF,CmC7qHI,+FAEE,QnC+qHN,CmC5qHM,yGACE,wBAAA,CACA,yBnC+qHR,CmCtqHM,2DAEE,wBAAA,CACA,yBAAA,CAFA,QnC0qHR,CmCnqHM,iEACE,QnCqqHR,CmClqHQ,qLAGE,wBAAA,CACA,yBAAA,CAFA,QnCsqHV,CmChqHQ,6FACE,wBAAA,CACA,yBnCkqHV,CmC7pHM,yDACE,kBnC+pHR,CmC1pHI,sCACE,QnC4pHN,CmCvpHE,2BAEE,iBAAA,CAKA,kBAAA,CADA,uCAAA,CAEA,cAAA,CAPA,aAAA,CAGA,YAAA,CACA,gBAAA,CAKA,mBAAA,CADA,gCAAA,CANA,WnCgqHJ,CmCtpHI,iCAEE,uDAAA,CADA,+BnCypHN,CmCppHI,iCAIE,6BAAA,CAOA,UAAA,CAVA,aAAA,CAEA,WAAA,CAKA,8CAAA,CAAA,sCAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBAAA,CALA,+CACE,CAJF,UnC6pHN,CmC/oHE,4BAME,+EACE,CALF,YAAA,CAGA,aAAA,CAFA,qBAAA,CAUA,mBAAA,CAZA,iBAAA,CAWA,wBAAA,CARA,YnCqpHJ,CmCzoHI,sCACE,wBnC2oHN,CmCvoHI,oCACE,SnCyoHN,CmCroHI,kCAGE,8EACE,CAFF,mBAAA,CADA,OnCyoHN,CmC/nHM,uDACE,8CAAA,CAAA,sCnCioHR,CKhvHI,wC8B6HF,wDAGE,kBnCwnHF,CmC3nHA,wDAGE,mBnCwnHF,CmC3nHA,8CAEE,eAAA,CADA,eAAA,CAGA,iCnCunHF,CmCnnHE,8DACE,mBnCsnHJ,CmCvnHE,8DACE,kBnCsnHJ,CmCvnHE,oDAEE,UnCqnHJ,CmCjnHE,8EAEE,kBnConHJ,CmCtnHE,8EAEE,mBnConHJ,CmCtnHE,8EAGE,kBnCmnHJ,CmCtnHE,8EAGE,mBnCmnHJ,CmCtnHE,oEACE,UnCqnHJ,CmC/mHE,8EAEE,mBnCknHJ,CmCpnHE,8EAEE,kBnCknHJ,CmCpnHE,8EAGE,mBnCinHJ,CmCpnHE,8EAGE,kBnCinHJ,CmCpnHE,oEACE,UnCmnHJ,CACF,CmCrmHE,cAHF,olDAII,+BnCwmHF,CmCrmHE,g8GACE,sCnCumHJ,CACF,CmClmHA,4sDACE,uDnCqmHF,CmCjmHA,wmDACE,anComHF,CoCh9HA,MACE,mVAAA,CAEA,4VpCo9HF,CoC18HE,4BAEE,oBAAA,CADA,iBpC88HJ,CoCz8HI,sDAGE,SpC28HN,CoC98HI,sDAGE,UpC28HN,CoC98HI,4CACE,iBAAA,CACA,SpC48HN,CoCt8HE,+CAEE,SAAA,CADA,UpCy8HJ,CoCp8HE,kDAGE,WpC68HJ,CoCh9HE,kDAGE,YpC68HJ,CoCh9HE,wCAME,qDAAA,CAIA,UAAA,CALA,aAAA,CAEA,0CAAA,CAAA,kCAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBAAA,CARA,iBAAA,CACA,SAAA,CAEA,YpC48HJ,CoCl8HE,gEACE,wBT0Wa,CSzWb,mDAAA,CAAA,2CpCo8HJ,CqCr/HA,QACE,8DAAA,CAGA,+CAAA,CACA,iEAAA,CACA,oDAAA,CACA,sDAAA,CACA,mDrCs/HF,CqCl/HA,SAEE,kBAAA,CADA,YrCs/HF,CK71HI,mCiChKA,8BAIE,kBtCkgIJ,CsCtgIE,8BAIE,iBtCkgIJ,CsCtgIE,oBACE,UAAA,CAIA,mBAAA,CAFA,YAAA,CADA,atCogIJ,CsC9/HI,8BACE,WtCggIN,CsC5/HI,kCAEE,iBAAA,CAAA,ctC8/HN,CsChgII,kCAEE,aAAA,CAAA,kBtC8/HN,CsChgII,wBACE,WtC+/HN,CsC3/HM,kCACE,UtC6/HR,CACF","file":"main.css"} \ No newline at end of file diff --git a/assets/stylesheets/palette.cbb835fc.min.css b/assets/stylesheets/palette.cbb835fc.min.css new file mode 100644 index 000000000..30f9264c3 --- /dev/null +++ b/assets/stylesheets/palette.cbb835fc.min.css @@ -0,0 +1 @@ +@media screen{[data-md-color-scheme=slate]{--md-hue:232;--md-default-fg-color:hsla(var(--md-hue),75%,95%,1);--md-default-fg-color--light:hsla(var(--md-hue),75%,90%,0.62);--md-default-fg-color--lighter:hsla(var(--md-hue),75%,90%,0.32);--md-default-fg-color--lightest:hsla(var(--md-hue),75%,90%,0.12);--md-default-bg-color:hsla(var(--md-hue),15%,21%,1);--md-default-bg-color--light:hsla(var(--md-hue),15%,21%,0.54);--md-default-bg-color--lighter:hsla(var(--md-hue),15%,21%,0.26);--md-default-bg-color--lightest:hsla(var(--md-hue),15%,21%,0.07);--md-code-fg-color:hsla(var(--md-hue),18%,86%,1);--md-code-bg-color:hsla(var(--md-hue),15%,15%,1);--md-code-hl-color:rgba(66,135,255,.15);--md-code-hl-number-color:#e6695b;--md-code-hl-special-color:#f06090;--md-code-hl-function-color:#c973d9;--md-code-hl-constant-color:#9383e2;--md-code-hl-keyword-color:#6791e0;--md-code-hl-string-color:#2fb170;--md-code-hl-name-color:var(--md-code-fg-color);--md-code-hl-operator-color:var(--md-default-fg-color--light);--md-code-hl-punctuation-color:var(--md-default-fg-color--light);--md-code-hl-comment-color:var(--md-default-fg-color--light);--md-code-hl-generic-color:var(--md-default-fg-color--light);--md-code-hl-variable-color:var(--md-default-fg-color--light);--md-typeset-color:var(--md-default-fg-color);--md-typeset-a-color:var(--md-primary-fg-color);--md-typeset-mark-color:rgba(66,135,255,.3);--md-typeset-kbd-color:hsla(var(--md-hue),15%,94%,0.12);--md-typeset-kbd-accent-color:hsla(var(--md-hue),15%,94%,0.2);--md-typeset-kbd-border-color:hsla(var(--md-hue),15%,14%,1);--md-typeset-table-color:hsla(var(--md-hue),75%,95%,0.12);--md-admonition-fg-color:var(--md-default-fg-color);--md-admonition-bg-color:var(--md-default-bg-color);--md-footer-bg-color:hsla(var(--md-hue),15%,12%,0.87);--md-footer-bg-color--dark:hsla(var(--md-hue),15%,10%,1);--md-shadow-z1:0 0.2rem 0.5rem rgba(0,0,0,.2),0 0 0.05rem rgba(0,0,0,.1);--md-shadow-z2:0 0.2rem 0.5rem rgba(0,0,0,.3),0 0 0.05rem rgba(0,0,0,.25);--md-shadow-z3:0 0.2rem 0.5rem rgba(0,0,0,.4),0 0 0.05rem rgba(0,0,0,.35)}[data-md-color-scheme=slate] img[src$="#gh-light-mode-only"],[data-md-color-scheme=slate] img[src$="#only-light"]{display:none}[data-md-color-scheme=slate] img[src$="#gh-dark-mode-only"],[data-md-color-scheme=slate] img[src$="#only-dark"]{display:initial}[data-md-color-scheme=slate][data-md-color-primary=pink]{--md-typeset-a-color:#ed5487}[data-md-color-scheme=slate][data-md-color-primary=purple]{--md-typeset-a-color:#bd78c9}[data-md-color-scheme=slate][data-md-color-primary=deep-purple]{--md-typeset-a-color:#a682e3}[data-md-color-scheme=slate][data-md-color-primary=indigo]{--md-typeset-a-color:#6c91d5}[data-md-color-scheme=slate][data-md-color-primary=teal]{--md-typeset-a-color:#00ccb8}[data-md-color-scheme=slate][data-md-color-primary=green]{--md-typeset-a-color:#71c174}[data-md-color-scheme=slate][data-md-color-primary=deep-orange]{--md-typeset-a-color:#ff9575}[data-md-color-scheme=slate][data-md-color-primary=brown]{--md-typeset-a-color:#c7846b}[data-md-color-scheme=slate][data-md-color-primary=black],[data-md-color-scheme=slate][data-md-color-primary=blue-grey],[data-md-color-scheme=slate][data-md-color-primary=grey],[data-md-color-scheme=slate][data-md-color-primary=white]{--md-typeset-a-color:#6c91d5}[data-md-color-switching] *,[data-md-color-switching] :after,[data-md-color-switching] :before{transition-duration:0ms!important}}[data-md-color-accent=red]{--md-accent-fg-color:#ff1947;--md-accent-fg-color--transparent:rgba(255,25,71,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=pink]{--md-accent-fg-color:#f50056;--md-accent-fg-color--transparent:rgba(245,0,86,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=purple]{--md-accent-fg-color:#df41fb;--md-accent-fg-color--transparent:rgba(223,65,251,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=deep-purple]{--md-accent-fg-color:#7c4dff;--md-accent-fg-color--transparent:rgba(124,77,255,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=indigo]{--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:rgba(82,108,254,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=blue]{--md-accent-fg-color:#4287ff;--md-accent-fg-color--transparent:rgba(66,135,255,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=light-blue]{--md-accent-fg-color:#0091eb;--md-accent-fg-color--transparent:rgba(0,145,235,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=cyan]{--md-accent-fg-color:#00bad6;--md-accent-fg-color--transparent:rgba(0,186,214,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=teal]{--md-accent-fg-color:#00bda4;--md-accent-fg-color--transparent:rgba(0,189,164,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=green]{--md-accent-fg-color:#00c753;--md-accent-fg-color--transparent:rgba(0,199,83,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=light-green]{--md-accent-fg-color:#63de17;--md-accent-fg-color--transparent:rgba(99,222,23,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=lime]{--md-accent-fg-color:#b0eb00;--md-accent-fg-color--transparent:rgba(176,235,0,.1);--md-accent-bg-color:rgba(0,0,0,.87);--md-accent-bg-color--light:rgba(0,0,0,.54)}[data-md-color-accent=yellow]{--md-accent-fg-color:#ffd500;--md-accent-fg-color--transparent:rgba(255,213,0,.1);--md-accent-bg-color:rgba(0,0,0,.87);--md-accent-bg-color--light:rgba(0,0,0,.54)}[data-md-color-accent=amber]{--md-accent-fg-color:#fa0;--md-accent-fg-color--transparent:rgba(255,170,0,.1);--md-accent-bg-color:rgba(0,0,0,.87);--md-accent-bg-color--light:rgba(0,0,0,.54)}[data-md-color-accent=orange]{--md-accent-fg-color:#ff9100;--md-accent-fg-color--transparent:rgba(255,145,0,.1);--md-accent-bg-color:rgba(0,0,0,.87);--md-accent-bg-color--light:rgba(0,0,0,.54)}[data-md-color-accent=deep-orange]{--md-accent-fg-color:#ff6e42;--md-accent-fg-color--transparent:rgba(255,110,66,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=red]{--md-primary-fg-color:#ef5552;--md-primary-fg-color--light:#e57171;--md-primary-fg-color--dark:#e53734;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=pink]{--md-primary-fg-color:#e92063;--md-primary-fg-color--light:#ec417a;--md-primary-fg-color--dark:#c3185d;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=purple]{--md-primary-fg-color:#ab47bd;--md-primary-fg-color--light:#bb69c9;--md-primary-fg-color--dark:#8c24a8;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=deep-purple]{--md-primary-fg-color:#7e56c2;--md-primary-fg-color--light:#9574cd;--md-primary-fg-color--dark:#673ab6;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=indigo]{--md-primary-fg-color:#4051b5;--md-primary-fg-color--light:#5d6cc0;--md-primary-fg-color--dark:#303fa1;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=blue]{--md-primary-fg-color:#2094f3;--md-primary-fg-color--light:#42a5f5;--md-primary-fg-color--dark:#1975d2;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=light-blue]{--md-primary-fg-color:#02a6f2;--md-primary-fg-color--light:#28b5f6;--md-primary-fg-color--dark:#0287cf;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=cyan]{--md-primary-fg-color:#00bdd6;--md-primary-fg-color--light:#25c5da;--md-primary-fg-color--dark:#0097a8;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=teal]{--md-primary-fg-color:#009485;--md-primary-fg-color--light:#26a699;--md-primary-fg-color--dark:#007a6c;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=green]{--md-primary-fg-color:#4cae4f;--md-primary-fg-color--light:#68bb6c;--md-primary-fg-color--dark:#398e3d;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=light-green]{--md-primary-fg-color:#8bc34b;--md-primary-fg-color--light:#9ccc66;--md-primary-fg-color--dark:#689f38;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=lime]{--md-primary-fg-color:#cbdc38;--md-primary-fg-color--light:#d3e156;--md-primary-fg-color--dark:#b0b52c;--md-primary-bg-color:rgba(0,0,0,.87);--md-primary-bg-color--light:rgba(0,0,0,.54)}[data-md-color-primary=yellow]{--md-primary-fg-color:#ffec3d;--md-primary-fg-color--light:#ffee57;--md-primary-fg-color--dark:#fbc02d;--md-primary-bg-color:rgba(0,0,0,.87);--md-primary-bg-color--light:rgba(0,0,0,.54)}[data-md-color-primary=amber]{--md-primary-fg-color:#ffc105;--md-primary-fg-color--light:#ffc929;--md-primary-fg-color--dark:#ffa200;--md-primary-bg-color:rgba(0,0,0,.87);--md-primary-bg-color--light:rgba(0,0,0,.54)}[data-md-color-primary=orange]{--md-primary-fg-color:#ffa724;--md-primary-fg-color--light:#ffa724;--md-primary-fg-color--dark:#fa8900;--md-primary-bg-color:rgba(0,0,0,.87);--md-primary-bg-color--light:rgba(0,0,0,.54)}[data-md-color-primary=deep-orange]{--md-primary-fg-color:#ff6e42;--md-primary-fg-color--light:#ff8a66;--md-primary-fg-color--dark:#f4511f;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=brown]{--md-primary-fg-color:#795649;--md-primary-fg-color--light:#8d6e62;--md-primary-fg-color--dark:#5d4037;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=grey]{--md-primary-fg-color:#757575;--md-primary-fg-color--light:#9e9e9e;--md-primary-fg-color--dark:#616161;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7);--md-typeset-a-color:#4051b5}[data-md-color-primary=blue-grey]{--md-primary-fg-color:#546d78;--md-primary-fg-color--light:#607c8a;--md-primary-fg-color--dark:#455a63;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7);--md-typeset-a-color:#4051b5}[data-md-color-primary=light-green]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#72ad2e}[data-md-color-primary=lime]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#8b990a}[data-md-color-primary=yellow]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#b8a500}[data-md-color-primary=amber]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#d19d00}[data-md-color-primary=orange]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#e68a00}[data-md-color-primary=white]{--md-primary-fg-color:#fff;--md-primary-fg-color--light:hsla(0,0%,100%,.7);--md-primary-fg-color--dark:rgba(0,0,0,.07);--md-primary-bg-color:rgba(0,0,0,.87);--md-primary-bg-color--light:rgba(0,0,0,.54);--md-typeset-a-color:#4051b5}@media screen and (min-width:60em){[data-md-color-primary=white] .md-search__form{background-color:rgba(0,0,0,.07)}[data-md-color-primary=white] .md-search__form:hover{background-color:rgba(0,0,0,.32)}[data-md-color-primary=white] .md-search__input+.md-search__icon{color:rgba(0,0,0,.87)}}@media screen and (min-width:76.25em){[data-md-color-primary=white] .md-tabs{border-bottom:.05rem solid rgba(0,0,0,.07)}}[data-md-color-primary=black]{--md-primary-fg-color:#000;--md-primary-fg-color--light:rgba(0,0,0,.54);--md-primary-fg-color--dark:#000;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7);--md-typeset-a-color:#4051b5}[data-md-color-primary=black] .md-header{background-color:#000}@media screen and (max-width:59.9375em){[data-md-color-primary=black] .md-nav__source{background-color:rgba(0,0,0,.87)}}@media screen and (min-width:60em){[data-md-color-primary=black] .md-search__form{background-color:hsla(0,0%,100%,.12)}[data-md-color-primary=black] .md-search__form:hover{background-color:hsla(0,0%,100%,.3)}}@media screen and (max-width:76.1875em){html [data-md-color-primary=black] .md-nav--primary .md-nav__title[for=__drawer]{background-color:#000}}@media screen and (min-width:76.25em){[data-md-color-primary=black] .md-tabs{background-color:#000}} \ No newline at end of file diff --git a/assets/stylesheets/palette.cbb835fc.min.css.map b/assets/stylesheets/palette.cbb835fc.min.css.map new file mode 100644 index 000000000..96e380c87 --- /dev/null +++ b/assets/stylesheets/palette.cbb835fc.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["src/assets/stylesheets/palette/_scheme.scss","../../../src/assets/stylesheets/palette.scss","src/assets/stylesheets/palette/_accent.scss","src/assets/stylesheets/palette/_primary.scss","src/assets/stylesheets/utilities/_break.scss"],"names":[],"mappings":"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","file":"palette.css"} \ No newline at end of file diff --git a/assets/thumbnails/tutorial-ftso-1.png b/assets/thumbnails/tutorial-ftso-1.png new file mode 100644 index 000000000..232d4fd03 Binary files /dev/null and b/assets/thumbnails/tutorial-ftso-1.png differ diff --git a/assets/tokenomics-36-month-distribution-schedule-liquid.png b/assets/tokenomics-36-month-distribution-schedule-liquid.png new file mode 100644 index 000000000..dbffec3f3 Binary files /dev/null and b/assets/tokenomics-36-month-distribution-schedule-liquid.png differ diff --git a/assets/tokenomics-36-month-token-distribution-schedule-network-participation.png b/assets/tokenomics-36-month-token-distribution-schedule-network-participation.png new file mode 100644 index 000000000..63538a9ed Binary files /dev/null and b/assets/tokenomics-36-month-token-distribution-schedule-network-participation.png differ diff --git a/assets/tokenomics-36-month-vote-power-trend.png b/assets/tokenomics-36-month-vote-power-trend.png new file mode 100644 index 000000000..401a4d26f Binary files /dev/null and b/assets/tokenomics-36-month-vote-power-trend.png differ diff --git a/assets/tokenomics-initial-distribution-macro-view-total-flare.png b/assets/tokenomics-initial-distribution-macro-view-total-flare.png new file mode 100644 index 000000000..a46568d9e Binary files /dev/null and b/assets/tokenomics-initial-distribution-macro-view-total-flare.png differ diff --git a/assets/tokenomics-month-0-circulating-flr.png b/assets/tokenomics-month-0-circulating-flr.png new file mode 100644 index 000000000..a8f499341 Binary files /dev/null and b/assets/tokenomics-month-0-circulating-flr.png differ diff --git a/assets/tokenomics-month-0-liquid-flr.png b/assets/tokenomics-month-0-liquid-flr.png new file mode 100644 index 000000000..fef2290da Binary files /dev/null and b/assets/tokenomics-month-0-liquid-flr.png differ diff --git a/assets/tokenomics-month-0-total-flr.png b/assets/tokenomics-month-0-total-flr.png new file mode 100644 index 000000000..0647ec415 Binary files /dev/null and b/assets/tokenomics-month-0-total-flr.png differ diff --git a/assets/tokenomics-month-36-circulating-&-liquid-flr.png b/assets/tokenomics-month-36-circulating-&-liquid-flr.png new file mode 100644 index 000000000..d1c95de3e Binary files /dev/null and b/assets/tokenomics-month-36-circulating-&-liquid-flr.png differ diff --git a/assets/tokenomics-terms.png b/assets/tokenomics-terms.png new file mode 100644 index 000000000..620fa6994 Binary files /dev/null and b/assets/tokenomics-terms.png differ diff --git a/assets/tokenomics-token-supply-over-36-months.png b/assets/tokenomics-token-supply-over-36-months.png new file mode 100644 index 000000000..75cdc0200 Binary files /dev/null and b/assets/tokenomics-token-supply-over-36-months.png differ diff --git a/assets/validator-network.png b/assets/validator-network.png new file mode 100644 index 000000000..1dd37387b Binary files /dev/null and b/assets/validator-network.png differ diff --git a/assets/votepower diagram.svg b/assets/votepower diagram.svg new file mode 100644 index 000000000..28b400cce --- /dev/null +++ b/assets/votepower diagram.svg @@ -0,0 +1,4 @@ + + + +
    Possible vote power block location for epoch i+1
    Possible vote power...
    Vote power block selection
    Vote pow...
    Reward epoch i
    Reward e...
    Reward epoch i+1
    Reward e...
    Reward epoch i-1
    Reward e...
    Block number: A
    End of reward epoch i-1
    Start of reward epoch i

    Block nu...
    Block number: B
    End of reward epoch i-1
    Start of reward epoch i

    Block nu...
    Block number: A + 3*(B-A)/4
    Block nu...
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/assets/wrapping-portal-faq-add-wrapped.png b/assets/wrapping-portal-faq-add-wrapped.png new file mode 100644 index 000000000..93e93253f Binary files /dev/null and b/assets/wrapping-portal-faq-add-wrapped.png differ diff --git a/assets/wrapping-portal-help.png b/assets/wrapping-portal-help.png new file mode 100644 index 000000000..9e8992927 Binary files /dev/null and b/assets/wrapping-portal-help.png differ diff --git a/dev-icon.svg b/dev-icon.svg new file mode 100644 index 000000000..072826083 --- /dev/null +++ b/dev-icon.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/dev/contracts/index.html b/dev/contracts/index.html new file mode 100644 index 000000000..777fbed8b --- /dev/null +++ b/dev/contracts/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/dev/external-resources/index.html b/dev/external-resources/index.html new file mode 100644 index 000000000..66beda561 --- /dev/null +++ b/dev/external-resources/index.html @@ -0,0 +1,3891 @@ + + + + + + + + + + + + + + + + + + External Learning Resources - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    + + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/getting-started/contract-addresses/index.html b/dev/getting-started/contract-addresses/index.html new file mode 100644 index 000000000..d92fdbe55 --- /dev/null +++ b/dev/getting-started/contract-addresses/index.html @@ -0,0 +1,4006 @@ + + + + + + + + + + + + + + + + + + Retrieving Contract Addresses - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Retrieving Contract Addresses#

    +
    +

    Attention

    +

    Developers should never rely on contract addresses gathered from off-chain sources like direct messages, social media, or even websites, as these addresses could easily lead to malicious contracts.

    +
    +

    For this reason, this documentation does not provide any contract address except for the single entry point described below. +The only secure way to retrieve contract addresses is from the blockchain itself.

    +

    As a convenience, though, Flare's smart contract repository contains the latest deployment address for all Flare's smart contracts. +These addresses can be used to speed up development, but should not be used in production.

    +

    To emphasize: Applications are strongly encouraged to retrieve any contract address they need directly from the blockchain and not have addresses hard-coded into the source code, except for the single entry point given in this page.

    +

    Retrieval from Blockchain#

    +

    All of Flare's smart contract addresses can be retrieved from the FlareContractRegistry contract. +This is the only contract address given in this documentation.

    +
    + + + + + + + + + + + +
    FlareContractRegistry
    0xaD67FE66660Fb8dFE9d6b1b4240d8650e30F6019
    +
    +
    +

    This contract is available at the same address in all Flare networks: Flare, Songbird, Coston and Coston2.

    +
    +

    Copy the above address into the Block Explorer to see the available contract's methods.

    +

    You can retrieve the current address on the blockchain of any Flare smart contract from its name by using these methods, for example:

    +
    function getContractAddressByName(
    +    string calldata _name
    +) external view returns (
    +    address);
    +
    +
    +function getContractAddressesByName(
    +    string[] calldata _names
    +) external view returns (
    +    address[] memory);
    +
    +

    The name search is case-sensitive, so you should use the proper capitalization. +For example:

    +
      +
    • WNat
    • +
    • FtsoRewardManager
    • +
    • PriceSubmitter
    • +
    +

    Applications can also retrieve all smart contract names and addresses at once using:

    +
    function getAllContracts(
    +) external view returns(
    +    string[] memory _names,
    +    address[] memory _addresses);
    +
    +

    +
    + +

    Retrieval from Source Code#

    +

    The Flare Smart Contracts repository contains an autogenerated JSON file listing the latest deployed addresses of all Flare contracts on each network.

    +

    You can find this file in the deployment/deploys folder, and parse it to retrieve the addresses of any Flare contract.

    +
    +

    Attention

    +

    As stated at the beginning, applications should NOT have Flare contract addresses in their source code.

    +

    Instead, applications are strongly encouraged to retrieve any contract address they need directly from the blockchain as described above.

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    BranchJSON file
    Flareflare_network_deployed_codeflare.json
    Songbirdsongbird_network_deployed_codesongbird.json
    Costoncoston_network_deployed_codecoston.json
    Coston2coston2_network_deployed_codecoston2.json
    + + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/getting-started/index.html b/dev/getting-started/index.html new file mode 100644 index 000000000..85ed0291e --- /dev/null +++ b/dev/getting-started/index.html @@ -0,0 +1,3834 @@ + + + + + + + + + + + + + + + + + + Getting Started - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    + + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/getting-started/setup/foundry/index.html b/dev/getting-started/setup/foundry/index.html new file mode 100644 index 000000000..d7406f4d1 --- /dev/null +++ b/dev/getting-started/setup/foundry/index.html @@ -0,0 +1,4027 @@ + + + + + + + + + + + + + + + + + + Using Foundry - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Setting Up Your Environment Using Foundry#

    +

    Foundry is a fast, portable and modular testing and deployment tool for developing EVM smart contracts. +Tests are written in Solidity to keep the workflow consistent with smart contract development and testing before deployments. +Foundry itself is written in Rust.

    +

    This article, partially based on the Foundry documentation, shows how to set up Foundry and use it to build and deploy smart contracts on Flare.

    +

    Guide#

    +

    1. Set up the Environment#

    +

    Follow the instructions for your operating system in the Foundry's Installation guide.

    +

    2. Create a Foundry Project#

    +

    Foundry can quick-start your development by providing a sample project:

    +
    forge init hello_foundry
    +
    +

    This creates a new directory hello_foundry from the default template which should look something like this:

    +
    +

    Foundry project structure +

    +
    Foundry project structure.
    +
    +

    3. Build the Contract#

    +

    To build the Counter.sol contract in the sample project run:

    +
    cd hello_foundry
    +forge build
    +
    +

    When done, it should print Compiler run successful.

    +

    You will notice that two new directories have been created, out and cache:

    +
    +

    Foundry project after build +

    +
    Foundry project after build.
    +
    +

    The out directory contains your contract artifact, such as the ABI, while the cache is used by forge to only recompile what is necessary.

    +

    4. Test the Contract#

    +

    In the test folder you should find a ready-made test file that verifies the contract works as expected.

    +

    To run tests with Foundry, you just need to run:

    +
    forge test
    +
    +

    When finished, it should print something similar to Test result: ok. 2 passed; 0 failed; finished in 24.43ms.

    +
    +

    Info

    +

    Learn more about Advanced Testing using Foundry.

    +
    +

    5. Deploy the Contract#

    +

    Forge can deploy only one contract at a time to a given network. +To do so, you must provide the URL of the RPC node to access the network, and the private key of the account that will deploy the contract.

    +

    The URL can be stored in an environment variable named FOUNDRY_ETH_RPC_URL) so you do not need to supply it every time.

    +
    +

    Important

    +

    You are going to deploy the contract on the Coston 2 network. +Make sure you have enough C2FLR in the account that will deploy the contract to pay the gas fees!

    +

    You can add C2FLR to any account using the Coston 2 Faucet.

    +
    +

    The general Foundry command to deploy a contract is:

    +
    forge create --rpc-url <your_rpc_url> \
    +  --private-key <your_private_key> \
    +  <contract_file>:<contract_name>
    +
    +

    Since Solidity files may contain multiple contracts, the :<contract_name> parameter specifies which contract to deploy from the <contract_file> source file. +Learn more about Deploying and Verifying Smart Contracts using Foundry.

    +

    To deploy the sample Counter contract to Flare's Coston 2 Network, run:

    +
    forge create --rpc-url https://coston2-api.flare.network/ext/C/rpc \
    +  --private-key d8936f6eae35c73a14ea7c1aabb8d068e16889a7f516c8abc482ba4e1489f4cd \
    +  src/Counter.sol:Counter
    +
    +

    Using the private key for your account.

    +

    Execution should look similar to this:

    +
    +

    Foundry project deployment +

    +
    Foundry project deployment.
    +
    +

    You can check the status of the contract by copy and pasting the Deployed to: address into the Coston 2 Block Explorer.

    + + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/getting-started/setup/hardhat/index.html b/dev/getting-started/setup/hardhat/index.html new file mode 100644 index 000000000..38392df08 --- /dev/null +++ b/dev/getting-started/setup/hardhat/index.html @@ -0,0 +1,4117 @@ + + + + + + + + + + + + + + + + + + Using Hardhat - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Setting Up Your Environment Using Hardhat#

    +

    Hardhat is an environment developers use to test, compile, deploy and debug dapps based on any blockchain compatible Ethereum's EVM. +Hardhat is a flexible and extensible task runner that helps you manage and automate the recurring tasks inherent to developing smart contracts and dapps.

    +

    This article, partially based on the Hardhat documentation shows you how to set up Hardhat and use it to build, test and deploy smart contracts on Flare.

    +

    Guide#

    +

    1. Set up the Environment#

    +

    Install the following dependencies:

    + +
    +

    Tip

    +

    Check the Official Guide by Hardhat if you have issues installing this package.

    +
    +

    Once the above dependencies are installed, create an npm empty project by running the following commands in a terminal:

    +
    mkdir flare-tutorial
    +cd flare-tutorial
    +npm init
    +
    +

    Press Enter on each of the prompts.

    +

    Finally, add Hardhat and a few dependencies to the project, since you will use them in this tutorial.

    +
    npm install --save-dev \
    +  hardhat \
    +  @nomicfoundation/hardhat-toolbox \
    +  @nomiclabs/hardhat-ethers \
    +  dotenv
    +
    +

    2. Create a Hardhat Project#

    +

    Hardhat can quick-start your development by providing a sample project. +Just run:

    +
    npx hardhat
    +
    +

    You should see the following prompt:

    +
    +

    Hardhat project creation prompt +

    +
    Hardhat project creation prompt.
    +
    +

    Choose the Create a JavaScript project with the Up and Down keys, and Press Enter. +Then press Y for rest of the prompts.

    +

    When done, it should print Project created.

    +

    If you take a look in the contracts folder, you should find a sample source file called Lock.sol. +It is a Solidity smart contract implementing a simple digital lock, where users can only withdraw funds after a given period of time:

    +
    // SPDX-License-Identifier: UNLICENSED
    +pragma solidity ^0.8.9;
    +
    +// Uncomment this line to use console.log
    +// import "hardhat/console.sol";
    +
    +contract Lock {
    +    uint public unlockTime;
    +    address payable public owner;
    +
    +    event Withdrawal(uint amount, uint when);
    +
    +    constructor(uint _unlockTime) payable {
    +        require(
    +            block.timestamp < _unlockTime,
    +            "Unlock time should be in the future"
    +        );
    +
    +        unlockTime = _unlockTime;
    +        owner = payable(msg.sender);
    +    }
    +
    +    function withdraw() public {
    +        // Uncomment this line, and the import of "hardhat/console.sol", to print a log in your terminal
    +        // console.log("Unlock time is %o and block timestamp is %o", unlockTime, block.timestamp);
    +
    +        require(block.timestamp >= unlockTime, "You can't withdraw yet");
    +        require(msg.sender == owner, "You aren't the owner");
    +
    +        emit Withdrawal(address(this).balance, block.timestamp);
    +
    +        owner.transfer(address(this).balance);
    +    }
    +}
    +
    +

    3. Compile the Contracts#

    +

    To compile the sample project, simply run:

    +
    npx hardhat compile
    +
    +

    Upon successful compilation it will print Compiled 1 Solidity file successfully.

    +

    4. Configure the Project#

    +

    In order to be deployed on any of the Flare networks, the project needs to be configured. +Edit the hardhat.config.js file and replace its contents with the following:

    +
    require('dotenv').config();
    +require("@nomicfoundation/hardhat-toolbox");
    +require('@nomiclabs/hardhat-ethers');
    +
    +/** @type import('hardhat/config').HardhatUserConfig */
    +module.exports = {
    +  solidity: "0.8.17",
    +  networks: {
    +    hardhat: {
    +    },
    +    coston: {
    +      url: "https://coston-api.flare.network/ext/bc/C/rpc",
    +      accounts: [process.env.PRIVATE_KEY],
    +      chainId: 16
    +    },
    +    songbird: {
    +      url: "https://songbird-api.flare.network/ext/bc/C/rpc",
    +      accounts: [process.env.PRIVATE_KEY],
    +      chainId: 19
    +    },
    +    coston2: {
    +      url: "https://coston2-api.flare.network/ext/C/rpc",
    +      accounts: [process.env.PRIVATE_KEY],
    +      chainId: 114,
    +    },
    +    flare: {
    +      url: "https://flare-api.flare.network/ext/C/rpc",
    +      accounts: [process.env.PRIVATE_KEY],
    +      chainId: 14,
    +    }
    +  },
    +};
    +
    +

    Then, create a file called .env at the root of you project (where the hardhat.config.js file resides) to store the private key for the account to use for testing. +.env files are useful to store local information which should not be committed into the source repository. +In this tutorial, you need to store your test account's private key in this format:

    +
    PRIVATE_KEY="0x0000000000000000000000000000000000000000000000000000000000000000"
    +
    +

    That is, 64 hexadecimal characters after the 0x.

    +
    +

    Caution

    +

    Make sure you never upload your .env file to a remote repository.

    +

    For this reason, the .gitignore file that Hardhat created for you already ignores .env files.

    +
    +

    5. Test the Contract#

    +

    In the test folder you should find a ready-made test file that verifies the contract works as expected.

    +

    To run tests with Hardhat, you just need to run:

    +
    npx hardhat test
    +
    +

    You should get:

    +
    +

    Lock contract test results +

    +
    Lock contract test results.
    +
    +

    6. Deploy the Contract#

    +

    Finally, you will deploy the contract to Flare's test network, Coston2, using a Hardhat script from the scripts folder.

    +

    Run this command in the root of the project:

    +
    npx hardhat run scripts/deploy.js --network coston2
    +
    +

    You should get an output similar to:

    +
    Lock with 1 ETH and unlock timestamp 1705592309 deployed to 0xdC7781FA9fA7e2d0313cd0229a5080B4e30663a5
    +
    +

    The last part is the address where the contract has been deployed. +You can check the status of the contract by copy and pasting this address in the Block Explorer.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/getting-started/setup/index.html b/dev/getting-started/setup/index.html new file mode 100644 index 000000000..480841337 --- /dev/null +++ b/dev/getting-started/setup/index.html @@ -0,0 +1,3838 @@ + + + + + + + + + + + + + + + + + + Setting Up Your Environment - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Setting Up Your Environment#

    +

    The following guides provide information to quickly set up a smart contract development environment.

    +

    Guides#

    + + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/getting-started/setup/remix/index.html b/dev/getting-started/setup/remix/index.html new file mode 100644 index 000000000..f4b013569 --- /dev/null +++ b/dev/getting-started/setup/remix/index.html @@ -0,0 +1,4057 @@ + + + + + + + + + + + + + + + + + + Using Remix - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Setting Up Your Environment Using Remix#

    +

    The Remix IDE is a powerful, open-source tool that helps you write Solidity smart contracts straight from the browser, without requiring any download, account creation, or login.

    +

    This article shows you how to deploy a Hello World contract to the Flare blockchain using the Remix IDE and the MetaMask wallet.

    +

    Guide#

    +

    1. Create a New File#

    +
      +
    • Visit the Remix IDE and click the New File button.
    • +
    • Name it HelloWorld.sol.
    • +
    • Drag and drop it to the contracts folder.
    • +
    +
    +

    New file in the Remix IDE +

    +
    New file in the Remix IDE.
    +
    +

    2. Write Your Contract#

    +

    Copy and paste the smart contract code provided below into the newly created HelloWorld.sol file.

    +
    // SPDX-License-Identifier: MIT
    +
    +// Specifies the version of Solidity, using semantic versioning.
    +pragma solidity 0.8.17;
    +
    +// Defines a contract named `HelloWorld`
    +contract HelloWorld {
    +
    +   // Declares a state variable `message` of type `string`.
    +   string public message;
    +
    +   // Constructors are used to initialize the contract's data.
    +   constructor(string memory initMessage) {
    +      // Accepts a string argument `initMessage`.
    +      message = initMessage;
    +   }
    +
    +   // A public function that accepts a string argument.
    +   function update(string memory newMessage) public {
    +      message = newMessage;
    +   }
    +}
    +
    +

    3. Compile Your Contract#

    +
      +
    • Go to the Solidity Compiler tab (on the left), and select compiler version 0.8.17.
    • +
    • Now, click the Compile HelloWorld.sol button.
    • +
    +

    After successful compilation, it will show a Green tick mark on the Compiler tab button.

    +
    +

    Compilation successful +

    +
    Compilation successful.
    +
    +

    4. Deploying on Flare Testnet#

    +

    You will now deploy the smart contract on the Coston2 network, Flare's test network.

    +

    When a smart contract is deployed on Flare's main network, it not only costs money (such as gas fees), but it also becomes immutable and cannot be modified. +Therefore, deploying your smart contracts first on the test network is highly recommended.

    +
    +

    Important

    +

    Before jumping onto Remix Deployment:

    +
      +
    • Make sure that you have added and selected the Coston2 test network to your MetaMask Wallet. + The MetaMask Wallet guide shows how to do it. + Use the values for Coston2 that you will find in the Network Configurations page.
    • +
    • Ensure that you have enough Coston2 native tokens $C2FLR to pay for gas. + Visit the Coston2 Faucet to request some $C2FLR.
    • +
    +
    +
      +
    • Go to the Deploy & Run Transactions tab (the last one) and select Injected Provider - Metamask from the ENVIRONMENT dropdown. + Accept the connection request received in MetaMask if necessary.
    • +
    +
    +

    Environment selection on Remix +

    +
    Environment selection on Remix.
    +
    +
      +
    • Click the Deploy button and confirm the CONTRACT DEPLOYMENT transaction in MetaMask.
    • +
    +
    +

    Contract deployment transaction +

    +
    Contract deployment transaction.
    +
    +
    +

    Note

    +

    The process to deploy your contract on the Flare main network is the same as above. +You only have to select Flare Network on MetaMask and use $FLR tokens.

    +
    +

    5. Interact with the Contract#

    +

    You can now interact with the contract to verify that it is working as intended.

    +
      +
    • In the Deployed Contracts section at the bottom of the left column, expand the HELLOWORLD contract to see its methods and data:
        +
      • update method.
      • +
      • message public variable.
      • +
      +
    • +
    • Type a message in the box next to the update button and click the button.
    • +
    • Confirm the deployment transaction in MetaMask.
    • +
    • Check that the contract has been updated by clicking the message button and verifying you get back the message you typed before.
    • +
    +
    +

    Interact with the contract +

    +
    Interact with the contract
    +
    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/getting-started/setup/truffle/index.html b/dev/getting-started/setup/truffle/index.html new file mode 100644 index 000000000..5117e0f2e --- /dev/null +++ b/dev/getting-started/setup/truffle/index.html @@ -0,0 +1,4089 @@ + + + + + + + + + + + + + + + + + + Using Truffle - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Setting Up Your Environment Using Truffle#

    +

    Truffle is a blockchain development environment, which you can use to create and test smart contracts by leveraging the Ethereum Virtual Machine (EVM), aiming to make life as a developer easier.

    +

    This article shows you how to set up Truffle and use it to build and deploy a smart contract on the Flare network.

    +

    Guide#

    +

    1. Set up the Environment#

    +

    Install the following dependencies:

    + +

    Once the above dependencies are installed, install Truffle:

    +
    npm install -g truffle
    +
    +

    To verify that Truffle is installed properly, type truffle version into the terminal.

    +

    2. Create a Truffle Project#

    +

    In this article you will use one of Truffle's boilerplate projects which you can find on the Truffle Boxes page. +MetaCoin box is an example of a completed coin-like contract.

    +

    Create a new directory for this Truffle project by running:

    +
    mkdir flare-truffle-tutorial
    +cd flare-truffle-tutorial
    +
    +

    Then install the MetaCoin box:

    +
    truffle unbox metacoin
    +
    +

    Once this operation is complete, you should have a project structure with the following items:

    +
    +

    Truffle Project structure +

    +
    Truffle Project structure.
    +
    +

    Finally, install the following dependencies which will be needed to deploy contracts:

    +
    npm i @truffle/hdwallet-provider dotenv
    +
    +

    3. Compile the Contract#

    +

    In the contracts folder you should find two sample source files called MetaCoin.sol and ConvertLib.sol.

    +

    To compile them, simply run:

    +
    truffle compile
    +
    +

    Upon successful compilation, you should see the following output:

    +
    +

    Truffle compilation output +

    +
    Truffle compilation output.
    +
    +

    4. Test the Contract#

    +

    In the test folder you should find examples for testing your smart contracts in both JavaScript and Solidity that verify the contracts work as expected.

    +

    To run tests:

    +
    truffle test
    +
    +

    When successful, the output should look like this:

    +
    +

    Truffle test output +

    +
    Truffle test output.
    +
    +

    5. Configure the Project#

    +

    In order to be deployed on any of the Flare networks, the project needs to be configured. +Edit the truffle-config.js file and replace its contents with the following:

    +
    const HDWalletProvider = require('@truffle/hdwallet-provider');
    +require('dotenv').config();
    +const fs = require('fs');
    +
    +module.exports = {
    +
    +  networks: {
    +    development: {
    +      host: "127.0.0.1",     // Localhost (default: none)
    +      port: 8545,            // Standard Ethereum port (default: none)
    +      network_id: "*",       // Any network (default: none)
    +    },
    +    flare: {
    +      provider: () => new HDWalletProvider(process.env.PRIVATE_KEY, `https://flare-api.flare.network/ext/C/rpc`),
    +      network_id: 14,
    +      timeoutBlocks: 200,
    +      skipDryRun: true
    +    },
    +    coston2: {
    +      provider: () => new HDWalletProvider(process.env.PRIVATE_KEY, `https://coston2-api.flare.network/ext/C/rpc`),
    +      network_id: 114,
    +      timeoutBlocks: 200,
    +      skipDryRun: true
    +    },
    +
    +  },
    +
    +  // Set default mocha options here, use special reporters etc.
    +  mocha: {
    +    // timeout: 100000
    +  },
    +
    +  // Configure your compilers
    +  compilers: {
    +    solc: {
    +      version: "0.8.13",      // Fetch exact version from solc-bin
    +    }
    +  }
    +};
    +
    +

    Then, create a file called .env at the root of you project (where the truffle-config.js file resides) to store the private key for the account to use for testing.

    +
    PRIVATE_KEY="d8936f6eae35c73a14ea7c1aabb8d068e16889a7f516c8abc482ba4e1489f4cd"
    +
    +

    .env files are useful to store local information which should not be committed into the source repository.

    +
    +

    Caution

    +

    Make sure you never upload your .env file to a remote repository.

    +

    For this reason, the .gitignore file that Truffle created for you already ignores .env files.

    +
    +

    6. Deploy the Contract#

    +
    +

    Important

    +

    You are going to deploy the contract on the Coston 2 network. +Make sure you have enough C2FLR in the account that will deploy the contract to pay the gas fees!

    +

    You can add C2FLR to any account using the Coston 2 Faucet.

    +
    +

    Run this command in the root folder of the project:

    +
    truffle migrate --network coston2
    +
    +

    You should get an output similar to:

    +
    +

    Truffle deployment output +

    +
    Truffle deployment output.
    +
    +

    You can check the status of the contract by copy and pasting the contract address: in the Block Explorer.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/index.html b/dev/index.html new file mode 100644 index 000000000..db20f2592 --- /dev/null +++ b/dev/index.html @@ -0,0 +1,3884 @@ + + + + + + + + + + + + + + + + + + Developer Docs - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + +

    + + + + + + + + + + + + + + + + + + + +

    + + + + + + + + + +

    Developer Docs#

    + +

    All Flare networks are a fork of the Avalanche project, which runs the Ethereum Virtual Machine. +Therefore, all Ethereum contracts and tools work on Flare, Songbird and Coston.

    +

    All Flare networks are layer-1 networks, and run independently of both Avalanche and Ethereum.

    +

    You can interact with the Flare networks using wallets, block explorers and the most common blockchain development environments.

    +

    As an example, all Flare networks support NFTs and many have already been created on Songbird. +The block explorer also supports displaying NFTs.

    +

    Once you have set up your development environment, you can start with the Accessing the Network tutorials.

    +

    Open-Source Repositories#

    +

    These are Flare's main source repositories, both on GitHub and GitLab.

    + +

    Topics#

    + + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/reference/automatic-claiming/index.html b/dev/reference/automatic-claiming/index.html new file mode 100644 index 000000000..7b419c337 --- /dev/null +++ b/dev/reference/automatic-claiming/index.html @@ -0,0 +1,4359 @@ + + + + + + + + + + + + + + + + + + Automatic Claiming - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + + + + +
    +
    + + + + + + + + + + +

    Automatic Claiming#

    +

    Users who do not want to claim rewards themselves can enlist executors to claim on their behalf. +Executors can then initiate the claiming process, and rewards are sent directly to the user's account.

    +

    Introduction#

    +

    Building an executor requires two parts:

    +
      +
    • An executor bot that periodically claims on behalf of the users.
    • +
    • An app that allows users to select the executor, such as the Flare Portal, which is free to use.
    • +
    +

    This page contains the following information:

    +
      +
    • The Required Contracts section briefly lists the smart contracts related to executor operation.
    • +
    • The User Operations section shows how to perform the operations required in a user-facing application, such as setting an executor.
    • +
    • The Executor Operations section shows how to perform the operations required by an executor bot, such as registering as an executor.
    • +
    • The User and Executor Reports section shows how to access information useful for performing user and executor functions.
    • +
    +

    Required Contracts#

    +

    Setting up automatic claiming requires interacting with these contracts:

    + +

    To find the addresses of these contracts, see the Contract Addresses page.

    +

    User Operations#

    +

    This section shows how to perform operations required to enable autoclaiming. +The main step is to set the executor that will perform the claiming for the user who has accrued rewards. +Then other operations are explained, such as changing the executor and disabling automatic claiming.

    +

    Setting Claim Executors#

    +

    There are two ways to set up automatic claiming: Manual and Registered.

    +

    Manual Claiming#

    +

    With Manual Claiming, rewards are claimed on-chain, but any agreement between users and executors happens off-chain. +Fees are not paid automatically.

    +

    To set one or more executors to claim rewards for a user:

    +
      +
    1. +

      Set a specific executor by calling CSM.setClaimExecutors() and providing the executor's address.

      +

      This method must be called from the user's account, since they are the only ones that can authorize claiming on their behalf.

      +

      This function removes all previously set executors and replaces them with the new set.

      +
    2. +
    +

    Registered Claiming#

    +

    With Registered Claiming, a purpose-built ClaimSetupManager contract handles the on-chain agreement between users and executors, greatly simplifying the process.

    +

    To set one or more registered executors to claim rewards for a user:

    +
      +
    1. +

      Get a list of executors and their fees by calling CSM.getRegisteredExecutors().

      +

      To find the fee of a specific executor, call CSM.getExecutorCurrentFeeValue(). +This fee is deducted from the user’s reward after each claim and sent to the executor.

      +

      You can show this information to the user and let them select which executor to use.

      +
    2. +
    3. +

      Set the selected executors by calling CSM.setClaimExecutors() as shown for Manual Claiming.

      +

      However, when setting registered executors, the call must include a value equal to the executor’s fee (in FLR), which is sent to the executor as an enrollment fee. +If more than one executor is set, the value must equal the sum of all the executor's fees.

      +
    4. +
    +

    Changing Registered Executors#

    +

    To change registered executors, call CSM.setClaimExecutors() with the new list of executors. +This new list overwrites the current list.

    +

    Disabling Automatic Claiming#

    +

    To disable automatic claiming, remove all executors by sending an empty array of executors with CSM.setClaimExecutors().

    +

    Executor Operations#

    +

    This section shows how to perform operations required in an executor-facing application, for example, becoming an executor. +While the main step for manual executors is only claiming rewards, the main steps for registered executors are registering, setting a fee, and claiming rewards. +Other operations like changing the fee, unregistering as an executor, and learning which addresses to claim for are also explained.

    +

    Becoming an Executor#

    +

    There are two ways to become an executor: Manual and Registered.

    +

    Manual Executor#

    +

    Setting an executor manually means doing so off-chain. +Therefore, there is no operation required for executors, besides communicating to the users the address of the executor they need to use.

    +

    Registered Executor#

    +

    The ClaimSetupManager contract contains a list of self-registered executors that users can use to discover executors and their service fees, avoiding the need for off-chain operations as in manual claiming.

    +

    To automatically receive fees for claiming, an executor address must register, set the fee for claiming rewards, and pay the registration fee.

    +

    Register an executor by calling CSM.registerExecutor(uint256 feeValue), where feeValue is the fee in wei that the executor requires to perform this service. +The fee value must be at least CSM.minFeeValueWei, currently 0.1 FLR, and no greater than CSM.maxFeeValueWei, currently 100 FLR. +This transaction must include a registration fee equal to CSM.registerExecutorFeeValueWei, currently 1000 FLR, which is burned.

    +

    Claiming Rewards#

    +

    How to Claim#

    +

    Executors can now only claim FTSO delegation rewards on behalf of users. +As other rewards become available, they will also be claimable by executors without any user intervention.

    +

    Manual and registered executors use the same function, the only difference being that unregistered executors do not receive a fee automatically.

    +

    To claim FTSO rewards for all of a user's unclaimed epochs, call FTSO.autoClaim(address[] rewardOwners, uint256 rewardEpoch).

    +
      +
    • This method can be used to claim for multiple users, since rewardOwners is an array.
    • +
    • +

      The rewardEpoch is the most current one that the executor wants to claim for, typically the one before the current epoch.

      +

      If a user has more unclaimed epochs from the past, the function claims for all of them.

      +
    • +
    +

    The claimed amount gets the executor fee subtracted and is automatically wrapped, so it is sent to the user as $WFLR.

    +

    What to Expect in Fees#

    +

    The executor gets paid a fee for each user for which he claims the FTSO delegation reward. +However, he only gets paid one fee per user regardless of whether he claims for one or more epochs. +The fee is paid in native $FLR tokens.

    +

    If the claimed reward for a user is lower than the executor fee, the transaction is reverted. +To see which users have enough rewards to complete and which would revert, call FTSO.autoClaim with a specific user address.

    +

    Changing the Fee#

    +

    Registered executors can change the fee they charge for the successful execution of claims. +To change the fee, call CSM.updateExecutorFeeValue(). +The new fee value will be in effect after CSM.feeValueUpdateOffset reward epochs have elapsed (currently 3 epochs), where the first epoch is the one that is currently active. +This function returns the reward epoch number when the setting will become effective.

    +

    Unregistering an Executor#

    +

    Registered executors can unregister by calling CSM.unregisterExecutor() and they will be removed from the list of executors. +To help the users adjust to the change, executors will retain the current fee and continue claiming for the next 3 reward epochs (feeValueUpdateOffset). +An executor's best practice is to notify users when unregistering.

    +

    Updating the User List#

    +

    Executors should keep a list of users to claim for, there is no mechanism to retrieve this list from the chain. +There are two ways to keep this list updated:

    +
      +
    • Listen to the CSM.ClaimExecutorsChanged event which is emitted every time a user sets its executors. + This method is suitable for registered executors which might be selected at any time.
    • +
    • If the executor is only interested in a closed list of users, e.g., the ones that enlisted on an application, it can call CSM.isClaimExecutor(address user, address executor) for each user to verify the executor's address is properly configured.
    • +
    +

    User and Executor Reports#

    +

    This section shows how to access information that can help you perform both user and executor functions.

    +

    Executor Fees#

    +

    Get the current fee for each executor on the Registered Executors list by calling CSM.getExecutorCurrentFeeValue(address executor). +For upcoming fee changes, call CSM.getExecutorScheduledFeeValueChanges(address executor).

    +

    Executors by User#

    +

    A user can set more than one executor. +To see a list of current executors for a user, call CSM.claimExecutors(address user), which returns an array of executor addresses. +It is a best practice for users to check this report periodically (at least every 90 days) to make sure their selected executors have not unregistered without notice.

    +

    Executor Status#

    +

    To check if an executor is registered, call CSM.getExecutorInfo(address executor). +It returns whether an executor is registered and its fee.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/reference/coston-testnet/index.html b/dev/reference/coston-testnet/index.html new file mode 100644 index 000000000..18a800eb2 --- /dev/null +++ b/dev/reference/coston-testnet/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/dev/reference/explorers-and-indexers/index.html b/dev/reference/explorers-and-indexers/index.html new file mode 100644 index 000000000..9bb068c2f --- /dev/null +++ b/dev/reference/explorers-and-indexers/index.html @@ -0,0 +1,3883 @@ + + + + + + + + + + + + + + + + + + Block Explorers and Indexers - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Block Explorers and Indexers#

    +

    Flare provides a block explorer for each of the networks in its ecosystem. +All explorers are a fork of Blockscout, adapted to the Flare networks (Blockscout Docs).

    +

    API documentation for each network's explorer:

    + +

    API access to the Coston Explorer is enabled for noncommercial use only.

    + + + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/reference/flare/index.html b/dev/reference/flare/index.html new file mode 100644 index 000000000..18a800eb2 --- /dev/null +++ b/dev/reference/flare/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/dev/reference/index.html b/dev/reference/index.html new file mode 100644 index 000000000..49d99d417 --- /dev/null +++ b/dev/reference/index.html @@ -0,0 +1,3838 @@ + + + + + + + + + + + + + + + + + + Reference Guides - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    + + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/reference/network-config/index.html b/dev/reference/network-config/index.html new file mode 100644 index 000000000..5b4103443 --- /dev/null +++ b/dev/reference/network-config/index.html @@ -0,0 +1,4271 @@ + + + + + + + + + + + + + + + + + + Network Configuration - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Network Configuration#

    +

    Flare Networks#

    +

    These are the values required to configure the different Flare networks:

    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ../../assets/logo-FLR.pngFlare
    Chain ID14
    Asset TickerFLR
    RPC endpointhttps://flare-api.flare.network/ext/C/rpc
    Rosetta APIhttps://flare-rosetta-api.flare.network/
    Block Explorerhttps://flare-explorer.flare.network
    Bootstraping nodes
    • https://flare.flare.network
    • http://mainnet.flare.bdnodes.net
    • http://flare-bootstrap-1.staking.production.figment.io
    • http://flare.senseinode.com
    • http://flare-mainnet.staked.cloud
    +
    +Sample query +

    You can check that you are accessing the RPC endpoint correctly with this sample query:

    +
    curl -s -m 10 --request POST 'https://flare-api.flare.network/ext/C/rpc' \
    +    -H 'Content-Type: application/json' \
    +    -d '{
    +            "jsonrpc":"2.0",
    +            "method":"eth_blockNumber",
    +            "params":[],
    +            "id":1
    +    }'
    +
    +

    It should return the current chain height in a message similar to:

    +
    {"jsonrpc":"2.0","id":1,"result":"0x103384"}
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ../../assets/logo-SGB.pngSongbird
    Chain ID19
    Asset TickerSGB
    RPC endpointhttps://songbird-api.flare.network/ext/C/rpc
    Block Explorerhttps://songbird-explorer.flare.network
    Bootstraping nodeshttps://songbird.flare.network
    +
    +Sample query +

    You can check that you are accessing the RPC endpoint correctly with this sample query:

    +
    curl -s -m 10 --request POST 'https://songbird-api.flare.network/ext/C/rpc' \
    +    -H 'Content-Type: application/json' \
    +    -d '{
    +            "jsonrpc":"2.0",
    +            "method":"eth_blockNumber",
    +            "params":[],
    +            "id":1
    +    }'
    +
    +

    It should return the current chain height in a message similar to:

    +
    {"jsonrpc":"2.0","id":1,"result":"0x103384"}
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    logo-CST.pngCoston
    Chain ID16
    Asset TickerCFLR
    RPC endpointhttps://coston-api.flare.network/ext/C/rpc
    Block Explorerhttps://coston-explorer.flare.network
    Bootstraping nodeshttps://coston.flare.network
    Test Faucethttps://faucet.towolabs.com
    +
    +Sample query +

    You can check that you are accessing the RPC endpoint correctly with this sample query:

    +
    curl -s -m 10 --request POST 'https://coston-api.flare.network/ext/C/rpc' \
    +    -H 'Content-Type: application/json' \
    +    -d '{
    +            "jsonrpc":"2.0",
    +            "method":"eth_blockNumber",
    +            "params":[],
    +            "id":1
    +    }'
    +
    +

    It should return the current chain height in a message similar to:

    +
    {"jsonrpc":"2.0","id":1,"result":"0x103384"}
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    logo-CST2.pngCoston2
    Chain ID114
    Asset TickerC2FLR
    RPC endpointhttps://coston2-api.flare.network/ext/C/rpc
    Block Explorerhttps://coston2-explorer.flare.network
    Bootstraping nodeshttps://coston2.flare.network
    Test Faucethttps://coston2-faucet.towolabs.com
    +
    +Sample query +

    You can check that you are accessing the RPC endpoint correctly with this sample query:

    +
    curl -s -m 10 --request POST 'https://coston2-api.flare.network/ext/C/rpc' \
    +    -H 'Content-Type: application/json' \
    +    -d '{
    +            "jsonrpc":"2.0",
    +            "method":"eth_blockNumber",
    +            "params":[],
    +            "id":1
    +    }'
    +
    +

    It should return the current chain height in a message similar to:

    +
    {"jsonrpc":"2.0","id":1,"result":"0x103384"}
    +
    +
    +
    +
    +
    +
    +

    All public RPC endpoints are experimental and rate-limited to avoid spamming attacks. +For a production-grade option check out Flare's API Portal

    +

    Connected Networks#

    +

    Along with the endpoints listed above to interact with its own networks, Flare offers public RPC nodes for a series of other blockchain networks, to bootstrap development of connected services like attestation providers.

    +

    All public RPC endpoints are experimental and rate-limited to avoid spamming attacks. +For a production-grade option check out Flare's API Portal

    +
    +
    +
    +
    + + + + + + + + + + + + + +
    RPC endpointhttps://bitcoin-api.flare.network
    +
    +Sample query +
    curl -s -X POST -m 10 -H "Content-type: application/json" \
    +-d '{"jsonrpc": "1.0", "id":"hc", "method": "getblockchaininfo", "params":[]}' \
    +-u public:d681co1pe2l3wcj9adrm2orlk0j5r5gr3wghgxt58tvge594co0k1ciljxq9glei \
    +https://bitcoin-api.flare.network | jq
    +
    +
    +
    +
    + + + + + + + + + + + + + +
    RPC endpointhttps://bnb-bsc-api.flare.network/
    +
    +Sample query +
    curl -s -X POST -m 10 -H "Content-Type: application/json" \
    +-d '{"jsonrpc": "2.0", "id":67, "method":"eth_blockNumber", "params":[]}' \
    +https://bnb-bsc-api.flare.network | jq
    +
    +
    +
    +
    + + + + + + + + + + + + + +
    RPC endpointhttps://litecoin-api.flare.network
    +
    +Sample query +
    curl -s -X POST -m 10 -H "Content-type: application/json" \
    +-d '{"jsonrpc": "1.0", "id":"hc", "method": "getblockchaininfo", "params":[]}' \
    +-u public:ntvzi4i1yne499t7vcdjqhhp92m3jvm0bb6dkpr406gkndvuns9sg6th3jd393uc \
    +https://litecoin-api.flare.network | jq
    +
    +
    +
    +
    + + + + + + + + + + + + + +
    RPC endpointhttps://dogecoin-api.flare.network
    +
    +Sample query +
    curl -s -X POST -m 10 -H "Content-type: application/json" \
    +-d '{"jsonrpc": "1.0", "id":"hc", "method": "getblockchaininfo", "params":[]}' \
    +-u public:6r1e5z3w9g6qruvkzkqvz8w67yqrq5js2cmyl2f1cncbp7gpp7tqixqskuub5v70 \
    +https://dogecoin-api.flare.network | jq
    +
    +
    +
    +
    + + + + + + + + + + + + + +
    RPC endpointhttps://xrpl-api.flare.network
    +
    +Sample query +
    curl -s -X POST -m 10 -H "Content-type: application/json" \
    +-d '{"method": "server_info", "params":[{"api_version": 1}]}' \
    +https://xrpl-api.flare.network | jq
    +
    +
    +
    +
    + + + + + + + + + + + + + +
    RPC endpointhttps://algorand-api.flare.network
    +
    +Sample query +
    curl -s -m 10 \
    +-H "X-Algo-API-Token: zl748k3wddvld8cvn64utnslbf7otorkijp84se0f58pmuu0shgm27gttpcjpmuq" \
    +https://algorand-api.flare.network/v2/status | jq
    +
    +
    +
    +
    + + + + + + + + + + + + + +
    RPC endpointhttps://ethereum-api.flare.network/
    +
    +Sample query +
    curl -s -X POST -m 10 -H "Content-Type: application/json" \
    +-d '{"jsonrpc": "2.0", "id":67, "method":"eth_blockNumber", "params":[]}' \
    +https://ethereum-api.flare.network | jq
    +
    +
    +
    +
    +
    +
    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/reference/network-configs/index.html b/dev/reference/network-configs/index.html new file mode 100644 index 000000000..18a800eb2 --- /dev/null +++ b/dev/reference/network-configs/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/dev/reference/personal-delegation-account/index.html b/dev/reference/personal-delegation-account/index.html new file mode 100644 index 000000000..f4065159c --- /dev/null +++ b/dev/reference/personal-delegation-account/index.html @@ -0,0 +1,4065 @@ + + + + + + + + + + + + + + + + + + Personal Delegation Accounts - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    + +
    +
    + + +
    +
    + + + + + + + + + + +

    Personal Delegation Accounts#

    +

    Personal Delegation Accounts (PDAs) temporarily store rewards, such as FTSO delegation rewards, that users do not want to claim to their main accounts as explained in the Concept page.

    +

    This page explains how to manage PDA functionality in applications.

    +

    Required contracts#

    +

    Working with the PDAs requires interacting with these contracts:

    + +

    To find the addresses of these contracts read the Contract Addresses page.

    +

    Enabling a PDA#

    +

    CSM.enableDelegationAccount() returns the address of the PDA associated with the caller's address, creating the PDA in the process if it didn't exist. +A single PDA can be associated with each address and it cannot be destroyed once created, only disabled (see below).

    +

    There exist no private keys to the PDA account so it cannot sign any transactions. +All interaction with the PDA happens through the CSM contract, and is usually triggered by the user's main account.

    +

    Note that this means that a PDA cannot have its own PDA, since no calls to the CSM can be made from the PDA account.

    +

    Once a PDA is created, certain functions like FTSO.autoClaim() automatically send claimed rewards to the PDA account instead of the main account. +See Delegation and Rewards below.

    +

    Disabling a PDA#

    +

    To disable the use of a PDA, call CSM.disableDelegationAccount(). +Any $WFLR tokens that are on the PDA address are transferred back to the user's main account.

    +

    When users disable their PDA, FTSO.autoClaim() claims only the rewards for their main account and to their main account.

    +

    CSM.disableDelegationAccount() disables the PDA contract but does not destroy it: its address is still returned by CSM.getDelegationAccountData(), but the enabled boolean will be false.

    +

    Checking PDA State#

    +

    To check if a user's PDA is enabled, call CSM.getDelegationAccountData(). +It returns both the PDA address and its state:

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    ConditionAddressState
    PDA is enabledPDA addresstrue
    PDA is disabledPDA addressfalse
    PDA has never been created0x000...000false
    +
    +

    Never rely solely on the returned address being non-zero to check if an account has a PDA.

    +
    +

    Delegation and Rewards#

    +

    A PDA is a regular account for which there are no private keys and which must be managed through the CSM contract instead.

    +

    Conveniently, the method signatures to delegate on the CSM are the same as on the WNat contract where delegation is usually performed, for instance CSM.batchDelegate(). +FTSO reward claiming, though, is still performed through the FTSORewardManager, for example using claimReward(address recipient, ...) where recipient allows sending to any address, including a PDA. +For information on how to delegate and claim FTSO rewards, see Delegation and Rewards.

    +

    In addition to the methods used for regular accounts, FTSO.autoClaim() automatically claims for both the main account and the PDA, to the PDA or the main account depending on whether the PDA is enabled or not. +If users disable their PDA, autoClaim() claims rewards for only their main account and to only their main account.

    +
    +

    Note

    +

    The autoClaim() method is unrelated to Automatic Claiming performed by executors.

    +
    +

    Governance Voting#

    +

    Flare network users have a right to vote on proposals that can change the behavior of the network or add new features. +The number of votes an address has is equal to the amount of wrapped Flare tokens ($WFLR) that the address holds.

    +

    PDA addresses cannot vote directly, but their owners can transfer all their votes to another address (e.g., the owner's address) by calling CSM.delegateGovernance(address recipient). +The recipient of the votes can then vote with its own votes as well as with the votes received from other addresses.

    +

    Transferring Funds#

    +

    Because a PDA is a regular account, anyone can send funds to it. +However, FLR tokens transferred to a PDA are automatically converted to $WFLR, making them convenient for delegation.

    +

    Only the owner of the main account and its PDA can transfer funds from the PDA and only to its main account. +To transfer tokens, the owner calls CSM.withdraw() and states the amount to withdraw.

    +

    Since it has no private keys, any token other than $FLR or $WFLR transferred to the PDA cannot be moved out by conventional means. +Instead, CSM.transferExternalToken() must be used to transfer them to another account. +This is useful, for example, to recover airdropped tokens accidentally sent to the PDA.

    +
    +

    Note

    +

    CSM.transferExternalToken() only works on ERC-20 tokens or token contracts that support the transfer function.

    +
    +

    Wallet or Dapp Integration#

    +

    To support personal delegation accounts, a wallet or dapp at a minimum should show its status, including:

    +
      +
    • Checking the user's PDA address and whether it is enabled.
    • +
    • Showing the amount of $WFLR on the user's PDA.
    • +
    +

    Additional integration could support the following actions:

    +
      +
    • Enabling and disabling the PDA.
    • +
    • Allowing the delegation of funds from a PDA to FTSO price providers.
    • +
    • Delegating votes for governance voting.
    • +
    • Claiming rewards to the PDA.
    • +
    • Withdrawing funds from users' PDAs to their main accounts.
    • +
    • Withdrawing custom ERC-20 tokens to the users' main accounts.
    • +
    +

    See the Flare Portal for an example of such integration.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/reference/songbird/index.html b/dev/reference/songbird/index.html new file mode 100644 index 000000000..18a800eb2 --- /dev/null +++ b/dev/reference/songbird/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/dev/reference/the-flaredrop/index.html b/dev/reference/the-flaredrop/index.html new file mode 100644 index 000000000..fbdb59f15 --- /dev/null +++ b/dev/reference/the-flaredrop/index.html @@ -0,0 +1,3986 @@ + + + + + + + + + + + + + + + + + + The FlareDrop - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    The FlareDrop#

    +

    The FlareDrop, previously called the Delegation Incentive Pool in the FIP.01, is a distribution method for the 24.25B remaining $FLR tokens after the original airdrop.

    +

    This page explains how to manage FlareDrop functionality in applications.

    +

    Required Contracts#

    +

    Working with the FlareDrop requires interacting with these contracts:

    + +

    To find their addresses, read the Contract Addresses page.

    +

    Operations#

    +

    Basic Claiming#

    +

    The Dist.claim method allows claiming the FlareDrop one account at a time.

    +
    function claim(
    +    address _rewardOwner,
    +    address _recipient,
    +    uint256 _month,
    +    bool _wrap
    +) external returns(
    +    uint256 _rewardAmount
    +);
    +
    +

    It transfers the FlareDrop rewards accrued by account _rewardOwner during the specified _month to the specified _recipient.

    +

    _wrap controls whether the reward is transferred in native $FLR tokens or wrapped in $WFLR tokens.

    +

    You can use Dist.getCurrentMonth() to find out the current month (starting at 0), or Dist.getClaimableMonths() to get the interval of months which are currently available for claiming. +Use Dist.getClaimableAmount() or Dist.getClaimableAmountOf() to find out if a given address has pending rewards on any given month.

    +

    Dist.claim() returns the amount of claimed rewards.

    +

    Two modes of operation are supported: Self-claiming and claiming on behalf of another account.

    +
      +
    • +

      Self-Claiming:

      +

      When msg.sender matches _rewardOwner, the caller is claiming its own rewards. +In this case _recipient can be any address.

      +
    • +
    • +

      Claiming on behalf of another account:

      +

      When msg.sender does not match _rewardOwner, the caller must be a claim executor, claiming on behalf of _rewardOwner.

      +

      If _msg.sender is not in the authorized list of executors for _rewardOwner, the call will revert. +Authorized executors must be set beforehand by _rewardOwner using CSM.setClaimExecutors().

      +

      The _recipient must either be _rewardOwner, its PDA, or any of the authorized recipients previously set by _rewardOwner using CSM.setAllowedClaimRecipients(). +The call will revert otherwise.

      +
    • +
    +

    Batched Claiming#

    +

    The Dist.autoClaim() method allows claiming the FlareDrop for an arbitrary amount of accounts in a single call, with convenient default values.

    +
    function autoClaim(
    +    address[] calldata _rewardOwners,
    +    uint256 _month
    +) external;
    +
    +

    It claims the rewards accrued by all the accounts in the _rewardOwners array during the specified _month.

    +

    If an account does not have an enabled PDA, the rewards are sent to the same account.

    +

    However, if an account does have an enabled PDA, the rewards are sent to the PDA account. +Any rewards accrued by the PDA account are also claimed and sent to the PDA.

    +

    Rewards claimed with this method are always wrapped.

    +

    If the executor is a registered executor with a nonzero fee, the fee is automatically deducted from each claimed reward and sent to the executor account (unwrapped). +If rewards are claimed for both an address and its PDA, the fee is deducted only once.

    +

    The call reverts if:

    +
      +
    • msg.sender is not in the authorized list of executors for any of the _rewardOwners.
    • +
    • The total claimed rewards for any of the _rewardOwners is not high enough to cover the executor's fee.
    • +
    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/reference/wallets/index.html b/dev/reference/wallets/index.html new file mode 100644 index 000000000..038248560 --- /dev/null +++ b/dev/reference/wallets/index.html @@ -0,0 +1,3910 @@ + + + + + + + + + + + + + + + + + + Wallets - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Wallets#

    +

    Information for wallet developers wanting to integrate with the Flare networks.

    +

    First off, find all basic network information like Chain ID or public RPC endpoints in the Network Configuration page.

    +

    This page then provides a few more pointers specific to wallet development.

    +

    Block Explorers and Indexers#

    +

    For all its networks, Flare offers public block explorers that double down as indexers. +Learn about them in the Block Explorers section.

    +

    Flare's Personal Delegation Accounts#

    +

    See the Integration with a Personal Delegation Account page.

    +

    Address Derivation Paths for HD Wallets#

    +

    Address derivation and format validation on Flare are the same as on Ethereum. +In particular, Flare uses the same coin type as Ethereum, this is, 60. +The BIP-44 paths are therefore m/44’/60’/x’/0/0 (hardened) and m/44’/60’/0’/0/x.

    +

    The same path is used on both the C-chain and the P-chain.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/tools/index.html b/dev/tools/index.html new file mode 100644 index 000000000..fb4d055fd --- /dev/null +++ b/dev/tools/index.html @@ -0,0 +1,3961 @@ + + + + + + + + + + + + + + + + + + Tools and Projects - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Tools and Projects#

    +

    The following tools and projects already support the Flare network.

    +

    Indexing and Querying#

    +

    Blockchains typically store the history of all transactions but not the latest, consolidated state of individual accounts. +The companies below provide fast access to this information

    + +

    Monitoring Tools#

    +

    These tools report information about Flare networks:

    + +

    Node Providers#

    +

    Validator nodes are online servers running a blockchain's client software. +They ensure that stored data is consistent and provide access to this data for applications.

    +

    Applications are encouraged to deploy their own nodes for enhanced reliability. +The companies below offer nodes-as-a-service, greatly simplifying deployment and operational costs.

    + +

    Storage#

    +

    Storing large amounts of data on-chain is typically very expensive. +These are some decentralized storage alternatives.

    + +

    Wallets#

    +

    Please see the Wallet user guides for a list of wallets currently supporting the Flare network.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/tutorials/ftso/getting-data-feeds/index.html b/dev/tutorials/ftso/getting-data-feeds/index.html new file mode 100644 index 000000000..180272e22 --- /dev/null +++ b/dev/tutorials/ftso/getting-data-feeds/index.html @@ -0,0 +1,4405 @@ + + + + + + + + + + + + + + + + + + Getting FTSO Data Feeds - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Getting FTSO Data Feeds#

    +

    This tutorial shows the simplest way to use the FTSO system to retrieve a specific data feed, like the price of Bitcoin.

    +

    The tutorial shows:

    +
      +
    • How to use the Flare periphery packages to simplify working with the Flare API.
    • +
    • How to retrieve the latest price for a given asset from the FTSO system.
    • +
    +

    Code#

    +

    Choose your preferred programming language and ensure you have a working development environment.

    +

    For easy navigation, numbered comments in the source code link to the tutorial sections below.

    +
    +
    +
    +
    GettingDataFeeds.sol
     1
    + 2
    + 3
    + 4
    + 5
    + 6
    + 7
    + 8
    + 9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    // SPDX-License-Identifier: MIT
    +
    +pragma solidity ^0.8.0;
    +
    +// 1. Import dependencies
    +import "@flarenetwork/flare-periphery-contracts/flare/util-contracts/userInterfaces/IFlareContractRegistry.sol";
    +import "@flarenetwork/flare-periphery-contracts/flare/ftso/userInterfaces/IFtsoRegistry.sol";
    +
    +contract GettingDataFeeds {
    +
    +    address private constant FLARE_CONTRACT_REGISTRY =
    +        0xaD67FE66660Fb8dFE9d6b1b4240d8650e30F6019;
    +
    +    function getTokenPriceWei(
    +        string memory _symbol
    +    ) public view returns(
    +        uint256 _price, uint256 _timestamp, uint256 _decimals)
    +    {
    +        // 2. Access the Contract Registry
    +        IFlareContractRegistry contractRegistry = IFlareContractRegistry(
    +            FLARE_CONTRACT_REGISTRY);
    +
    +        // 3. Retrieve the FTSO Registry
    +        IFtsoRegistry ftsoRegistry = IFtsoRegistry(
    +            contractRegistry.getContractAddressByName('FtsoRegistry'));
    +
    +        // 4. Get latest price
    +        (_price, _timestamp, _decimals) =
    +            ftsoRegistry.getCurrentPriceWithDecimals(_symbol);
    +    }
    +
    +}
    +
    +

    Source code license

    +
    +Building with Hardhat +
      +
    1. Create a new folder and move into it.
    2. +
    3. Follow any of the setup guides to create a new project. + For example: +
      npm init
      +npm install hardhat @nomicfoundation/hardhat-toolbox
      +npx hardhat
      +
    4. +
    5. Add Flare's Periphery Package as a dependency with: +
      npm install @flarenetwork/flare-periphery-contracts
      +
    6. +
    7. Copy the code above into a new file called GettingDataFeeds.sol in the contracts folder.
    8. +
    9. Compile with npx hardhat compile.
    10. +
    +
    +
    +
    +
    GettingDataFeeds.js
     1
    + 2
    + 3
    + 4
    + 5
    + 6
    + 7
    + 8
    + 9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    const FLARE_PACKAGE = "@flarenetwork/flare-periphery-contract-artifacts";
    +const FLARE_RPC = "https://flare-api.flare.network/ext/C/rpc";
    +
    +async function GettingDataFeeds_run(_symbol) {
    +    console.log(`Retrieving current price of ${_symbol}...`);
    +
    +    // 1. Import dependencies
    +    var ethers, flare;
    +    if (typeof window === "undefined") {
    +        // Node.js
    +        ethers = await import("ethers");
    +        flare = await import(FLARE_PACKAGE);
    +    } else {
    +        // Browser
    +        ethers = await import("https://esm.run/ethers@6.3");
    +        flare = await import(`https://esm.run/${FLARE_PACKAGE}`);
    +    }
    +
    +    // Node to submit queries to.
    +    const provider = new ethers.JsonRpcProvider(FLARE_RPC);
    +
    +    // 2. Access the Contract Registry
    +    const flareContractRegistry = new ethers.Contract(
    +        "0xaD67FE66660Fb8dFE9d6b1b4240d8650e30F6019",
    +        flare.nameToAbi("FlareContractRegistry", "flare").data,
    +        provider);
    +
    +    // 3. Retrieve the FTSO Registry
    +    const ftsoRegistryAddr = await
    +        flareContractRegistry.getContractAddressByName("FtsoRegistry");
    +    const ftsoRegistry = new ethers.Contract(
    +        ftsoRegistryAddr,
    +        flare.nameToAbi("FtsoRegistry", "flare").data,
    +        provider);
    +
    +    // 4. Get latest price
    +    const [_price, _timestamp, _decimals] =
    +        await ftsoRegistry["getCurrentPriceWithDecimals(string)"](_symbol);
    +
    +    console.log(`${Number(_price) / Math.pow(10, Number(_decimals))} USD`);
    +    console.log(`Calculated at ${new Date(Number(_timestamp) * 1000)}`);
    +}
    +
    +GettingDataFeeds_run("BTC");
    +
    +

    Source code license

    +

    +
    +Run with Node.js +

    This tutorial has been tested with npm v9.5 and Node.js v18.16.

    +
      +
    1. Create a new folder and move into it.
    2. +
    3. Copy & paste the code above into a new file called GettingDataFeeds.js.
    4. +
    5. Install dependencies with: +
      npm init
      +npm install ethers @flarenetwork/flare-periphery-contract-artifacts
      +
    6. +
    7. Run the program with: +
      node GettingDataFeeds.js
      +
    8. +
    +
    +

    +Run in browser +
    
    +
    +

    +
    +
    +
    + + +
    +

    Tutorial#

    +

    1. Import Dependencies#

    +

    The tutorial uses the following dependencies:

    + +
    +
    +
    +
    6
    +7
    import "@flarenetwork/flare-periphery-contracts/flare/util-contracts/userInterfaces/IFlareContractRegistry.sol";
    +import "@flarenetwork/flare-periphery-contracts/flare/ftso/userInterfaces/IFtsoRegistry.sol";
    +
    +
    +
    +
     8
    + 9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
        var ethers, flare;
    +    if (typeof window === "undefined") {
    +        // Node.js
    +        ethers = await import("ethers");
    +        flare = await import(FLARE_PACKAGE);
    +    } else {
    +        // Browser
    +        ethers = await import("https://esm.run/ethers@6.3");
    +        flare = await import(`https://esm.run/${FLARE_PACKAGE}`);
    +    }
    +
    +
    +
    +
    +

    The Periphery Packages simplify working with the Flare smart contracts significantly. +If you remove this dependency, you must manually provide the signatures for all the methods you want to use.

    +

    2. Access the Contract Registry#

    +

    The FlareContractRegistry contains the current addresses for all Flare smart contracts, and it is the only recommended way to retrieve them.

    +

    Its address is the same on all of Flare's networks, and it is the only Flare address that needs to be hard-coded into any program.

    +
    +
    +
    +
    20
    +21
            IFlareContractRegistry contractRegistry = IFlareContractRegistry(
    +            FLARE_CONTRACT_REGISTRY);
    +
    +
    +
    +
    23
    +24
    +25
    +26
        const flareContractRegistry = new ethers.Contract(
    +        "0xaD67FE66660Fb8dFE9d6b1b4240d8650e30F6019",
    +        flare.nameToAbi("FlareContractRegistry", "flare").data,
    +        provider);
    +
    +
    +
    +
    +

    3. Retrieve the FTSO Registry#

    +

    Prices for all assets tracked by the FTSO system are recovered through the FtsoRegistry contract.

    +

    Use the getContractAddressByName() method from the FlareContractRegistry to retrieve the address of the FtsoRegistry.

    +
    +
    +
    +
    24
    +25
            IFtsoRegistry ftsoRegistry = IFtsoRegistry(
    +            contractRegistry.getContractAddressByName('FtsoRegistry'));
    +
    +
    +
    +
    29
    +30
    +31
    +32
    +33
    +34
        const ftsoRegistryAddr = await
    +        flareContractRegistry.getContractAddressByName("FtsoRegistry");
    +    const ftsoRegistry = new ethers.Contract(
    +        ftsoRegistryAddr,
    +        flare.nameToAbi("FtsoRegistry", "flare").data,
    +        provider);
    +
    +
    +
    +
    +

    This address can be retrieved in the initialization phase of your program and used afterward. +There is no need to fetch it every time it must be used.

    +

    4. Get Latest Price#

    +

    Finally, the asset's price is fetched from the FtsoRegistry using getCurrentPriceWithDecimals.

    +
    +
    +
    +
    28
    +29
            (_price, _timestamp, _decimals) =
    +            ftsoRegistry.getCurrentPriceWithDecimals(_symbol);
    +
    +
    +
    +
    37
    +38
    +39
    +40
    +41
        const [_price, _timestamp, _decimals] =
    +        await ftsoRegistry["getCurrentPriceWithDecimals(string)"](_symbol);
    +
    +    console.log(`${Number(_price) / Math.pow(10, Number(_decimals))} USD`);
    +    console.log(`Calculated at ${new Date(Number(_timestamp) * 1000)}`);
    +
    +
    +
    +
    +
      +
    • +

      The only parameter of this method is the symbol for the asset being queried, like "FLR" or "BTC". + You can use getSupportedSymbols() to retrieve the list of all supported symbols.

      +
    • +
    • +

      Given that Solidity does not support numbers with decimals, this method returns the requested price as an integer and the number of decimal places by which the comma must be shifted.

      +

      For example, if it returns 1234 for the price and 2 for the decimals, the actual price of the asset in USD is 12.34.

      +
    • +
    • +

      It also returns the time when the price was calculated by the FTSO system as a UNIX timestamp. + You can use an online tool like EpochConverter to turn the timestamp into a human-readable form, + or use Date as in the JavaScript example.

      +
    • +
    +
    +JavaScript note on overloaded methods +

    The call to the getCurrentPriceWithDecimals method is a bit cumbersome in JavaScript:

    +
    37
    +38
        const [_price, _timestamp, _decimals] =
    +        await ftsoRegistry["getCurrentPriceWithDecimals(string)"](_symbol);
    +
    +

    The call needs to be like this because this method is overloaded. +getCurrentPriceWithDecimals has two versions: one accepting a string for the symbol and another one accepting an integer for the asset's index in the FTSO system. +Therefore, the call needs to disambiguate both versions.

    +

    The vast majority of methods are not overloaded and allow a more natural call format. +For example:

    +
    await ftsoRegistry.getSupportedSymbols();
    +
    +
    +
    +

    Conclusion#

    +

    This tutorial served as the Hello World program for the FTSO system. +It has shown:

    +
      +
    • How to use the Flare Periphery Package, both from Solidity and from JavaScript.
    • +
    • How to retrieve the latest price for a given asset from the FTSO system.
    • +
    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/tutorials/ftso/index.html b/dev/tutorials/ftso/index.html new file mode 100644 index 000000000..bb4515829 --- /dev/null +++ b/dev/tutorials/ftso/index.html @@ -0,0 +1,3835 @@ + + + + + + + + + + + + + + + + + + FTSO Tutorials - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    FTSO Tutorials#

    +

    These code samples and explanations show how to use the FTSO system.

    +

    Tutorials#

    + + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/tutorials/index.html b/dev/tutorials/index.html new file mode 100644 index 000000000..eecb4c252 --- /dev/null +++ b/dev/tutorials/index.html @@ -0,0 +1,3834 @@ + + + + + + + + + + + + + + + + + + Tutorials - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Tutorials#

    +

    The Flare developer tutorials are divided into the following topics.

    +

    Topics#

    + + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/tutorials/network-access/index.html b/dev/tutorials/network-access/index.html new file mode 100644 index 000000000..dcc938660 --- /dev/null +++ b/dev/tutorials/network-access/index.html @@ -0,0 +1,3837 @@ + + + + + + + + + + + + + + + + + + Accessing the Network - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    + + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/tutorials/network-access/obtaining-revert-reason/index.html b/dev/tutorials/network-access/obtaining-revert-reason/index.html new file mode 100644 index 000000000..ce3aa8519 --- /dev/null +++ b/dev/tutorials/network-access/obtaining-revert-reason/index.html @@ -0,0 +1,3857 @@ + + + + + + + + + + + + + + + + + + Obtaining a Transaction's Revert Reason - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Obtaining a Transaction's Revert Reason#

    +

    Sometimes contract calls revert and throw a generic "Transaction has been reverted" exception which is not very helpful, since it does not contain the revert reason.

    +

    In this case, simulating the call in the EVM without sending any transaction, using the .call() syntax, can provide the missing information, assuming the blockchain's state has not changed much between calls.

    +

    The whole process is:

    +
      +
    • Catch the exception, and check if the revert reason is part of the exception data.
    • +
    +

    If not:

    +
      +
    • Repeat the same contract call using .call() syntax and parse the revert reason.
    • +
    +

    Note that the second step should be performed as soon as possible, to ensure that the chain has a similar state in both calls.

    +

    The function below demonstrates this process.

    +
    async function contractCall(account, to, gas, gasPrice, fnToEncode, nonce) {
    +  let tx = {from: account.address, to, gas, gasPrice, data: fnToEncode.encodeABI(), nonce};
    +  let signedTx = await account.signTransaction(tx);
    +  try {
    +    return await web3.eth.sendSignedTransaction(signedTx.rawTransaction);
    +  } catch (e) {
    +    if (e.message.indexOf("Transaction has been reverted by the EVM") >= 0) {
    +      // This call should throw a new exception containing the revert reason
    +      await fnToEncode.call({ from: account.address });
    +    }
    +    // Otherwise, either revert reason was already part of the original error or
    +    // we failed to get any additional information.
    +    throw e;
    +  }
    +}
    +
    +

    Where account and fnToEncode are obtained, for example, as follows:

    +
    let account = web3.eth.accounts.privateKeyToAccount(privateKey);
    +let fnToEncode = web3Contract.methods.someMethodOnContract(param1, param2);
    +
    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/tutorials/network-access/reliable-event-reading/index.html b/dev/tutorials/network-access/reliable-event-reading/index.html new file mode 100644 index 000000000..33f9e2bb3 --- /dev/null +++ b/dev/tutorials/network-access/reliable-event-reading/index.html @@ -0,0 +1,3831 @@ + + + + + + + + + + + + + + + + + + Reliable Event Reading - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Reliable Event Reading#

    +

    Subscription to events, for example using listeners, has proved to be unreliable, especially when high traffic exists on the network.

    +

    To reliably read events it is recommended to use the getPastEvents function on web3 contracts.

    +

    This function has parameters fromBlock and toBlock so the caller has to keep track of which blocks have already been requested.

    +

    The number of blocks the user can request in a single RPC call depends on the configuration of the RPC node being used. +In particular, if the node is run with the environment variable WEB3_API set to debug (a so-called "full node"), usually 100 blocks of events can be read in one call. +On the other hand, if WEB3_API is set to enabled (a "light node") only 1 block of events can be read.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/tutorials/network-access/transaction-finalization/index.html b/dev/tutorials/network-access/transaction-finalization/index.html new file mode 100644 index 000000000..1c8ab3805 --- /dev/null +++ b/dev/tutorials/network-access/transaction-finalization/index.html @@ -0,0 +1,3846 @@ + + + + + + + + + + + + + + + + + + Checking Transaction Finalization - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Checking Transaction Finalization#

    +

    On Flare and Songbird, obtaining the receipt of a submitted transaction does not guarantee that the transaction is finalized. +One has to wait until the sender's account nonce (the total number of sent transactions) increases.

    +

    The following function shows how to send a signed transaction and wait for its finalization.

    +

    The function polls the current nonce up to 8 times before giving up, using an exponential backoff. +This means that the time spent between successive polls of the nonce is increased exponentially to avoid taxing the network too much.

    +
    async function sendAndFinalize(senderAddress, signedTx, delay = 1000) {
    +  let oldNonce = await web3.eth.getTransactionCount(senderAddress);
    +  let receipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction)
    +  let backoff = 1.5;
    +  let maxRetries = 8;
    +  while ((await web3.eth.getTransactionCount(senderAddress)) == oldNonce) {
    +    await new Promise((resolve) => {setTimeout(()=>{resolve()}, delay)})
    +    maxRetries--;
    +    if(maxRetries == 0) {
    +      throw new Error("Response timeout");
    +    }
    +    delay = Math.floor(delay * backoff);
    +  }
    +  return receipt;
    +}
    +
    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/state-connector/index.html b/en/state-connector/index.html new file mode 100644 index 000000000..109d47cb7 --- /dev/null +++ b/en/state-connector/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/exchange-icon.svg b/exchange-icon.svg new file mode 100644 index 000000000..86b54447e --- /dev/null +++ b/exchange-icon.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/exchange/architecture/index.html b/exchange/architecture/index.html new file mode 100644 index 000000000..9b34b122e --- /dev/null +++ b/exchange/architecture/index.html @@ -0,0 +1,4135 @@ + + + + + + + + + + + + + + + + + + Architecture of an Exchange - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + + + + +
    +
    + + + + + + + + + + +

    Architecture of an Exchange#

    +

    What follows is the suggested architecture for a centralized Exchange. Even if your Exchange does not adopt this exact design, it defines the concepts that are used throughout the other pages in this section.

    +

    General Structure#

    +

    The suggested architecture uses a Central Exchange wallet with multiple User reception wallets controlled by the Exchange.

    +
    +

    General structure of an Exchange +

    +
    General structure of an Exchange.
    +
    +

    Exchange's Central Wallet (Hot)#

    +

    This account contains the Exchange's funds required to perform user operations: Users' deposits are ultimately routed here, and users' withdrawals are taken from here.

    +

    The private keys to this account need to be on an online machine (the Exchange server) so this is considered a hot wallet. For security reasons, it is recommended that the hot wallet only contains enough funds to perform daily operations, whereas the bulk of the funds are kept in the cold wallet.

    +

    Exchange's Central Wallet (Cold)#

    +

    The private keys to this account are kept in an offline machine so it is less vulnerable to attacks. Moreover, it is recommended that this is a multi-signature account so the approval of more than one administrator is required to move funds from it.

    +

    Periodically (e.g., once a day) funds are transferred from or to the hot wallet so it can continue operating while the bulk of the funds are protected in the cold wallet.

    +

    Users' Reception Wallets#

    +

    When users sign up with the Exchange, a reception wallet is created for them in order to perform deposits. The reception wallets are usually empty: as soon as they receive funds these are transferred to the Exchange's hot wallet.

    +

    The private keys to the reception wallets always remain under the Exchange's control; these wallets are offered to users as a convenience only. Users cannot perform any operation on these wallets other than deposits.

    +

    User's Wallet#

    +

    This is the origin of deposits made to the Exchange and the receiver of withdrawals made from the Exchange. It can be a wallet in control of the user (the user holds its private key), a custodial wallet or another Exchange, for example.

    +

    Exchange Server#

    +

    This is an online server, part of the Exchange's infrastructure, that receives withdrawal requests from users and monitors the reception wallets to detect incoming deposits. It holds the private keys to the hot wallet and to all the reception wallets so it can move funds from them in response to user's requests.

    +
    +

    Caution

    +

    This server must be available 24/7 so it is a clear target for malicious actors.

    +
    +

    Balances DB#

    +

    This database keeps track of every user's funds, since the actual tokens from all users are pooled together in the hot and cold wallets.

    +

    The Exchange server updates this DB in response to user's deposits and withdrawals.

    +

    Flare Observer Node#

    +

    An observer node is a regular Flare node that does not partake in consensus but is still aware of the current state of the blockchain and allows submitting transactions. It is highly recommended that Exchanges deploy their own observer nodes to access the network, instead of relying on third-party services. Read the Deploying an Observer Node guide to learn how to do this.

    +

    Detecting Deposits#

    +

    The Exchange server must be continuously monitoring transfers into ALL reception wallets to detect incoming deposits. Here's a summary of the process:

    +
    +

    Depositing to an Exchange +

    +
    Depositing to an Exchange.
    +
    +
      +
    1. +

      The user deposits (transfers) funds to their assigned reception wallet.

      +
    2. +
    3. +

      The transaction is detected by the Exchange server monitoring the wallets.

      +

      The server can discover a new transaction as soon as it is submitted by subscribing to the pendingTransactions event. This allows showing the transaction as "pending" in the UI, but there is still a chance that it is reverted.

      +

      To avoid problems, the Exchange should only act on transactions appearing on blocks old enough for the chance of them being reverted to be negligible. This can be done by subscribing to the newBlockHeaders event and examining the transactions in a previous block (for example, 5 blocks behind).

      +

      The code below exemplifies this process (See the web3.js documentation for the API details):

      +
      // https://web3js.readthedocs.io
      +const Web3 = require('web3');
      +
      +// Use your own node URL
      +// https://docs.flare.network/dev/reference/coston-testnet/
      +const web3 = new Web3("wss://coston-api.flare.network/ext/bc/C/ws");
      +
      +// Use your receiving wallet address
      +const receivingAddress = "0x947c76694491d3fD67a73688003c4d36C8780A97";
      +
      +web3.eth.subscribe("pendingTransactions")
      +.on("data", async (transactionHash) => {
      +    // New transaction hash received.
      +    // Retrieve the actual transaction.
      +    let tx = await web3.eth.getTransaction(transactionHash);
      +    // If it is directed to our address...
      +    if (tx.to === receivingAddress) {
      +        // Mark it as pending.
      +        console.log("Transaction", tx.hash, "is pending");
      +    }
      +}).on("error", console.error);
      +
      +web3.eth.subscribe("newBlockHeaders")
      +.on("data", async (blockHeader) => {
      +    // New block has been produced.
      +    // Retrieve a block old enough to be considered confirmed.
      +    let block = await web3.eth.getBlock(blockHeader.number - 5);
      +
      +    // Get all its transactions.
      +    block.transactions.forEach(async (transactionHash) => {
      +        // Retrieve the actual transaction.
      +        let tx = await web3.eth.getTransaction(transactionHash);
      +        // If it is directed to our address...
      +        if (tx.to === receivingAddress) {
      +            // Mark it as confirmed.
      +            console.log("Transaction", tx.hash,
      +                "is confirmed in block", block.number);
      +        }
      +    });
      +}).on("error", console.error);
      +
      +
      +

      Caution

      +

      Note that all transactions from a block are retrieved simultaneously and this can easily trigger a rate limit on the node. A proper implementation should avoid this by serializing requests or managing the request rate manually.

      +
      +
    4. +
    5. +

      The server then checks the wallet address to find which user account it belongs to, and adds the received amount to the user's balance.

      +
    6. +
    7. +

      The server announces a transaction to the network (through the Exchange's own observer node) to move the received funds to the hot wallet.

      +

      See a JavaScript example in the Ethereum documentation. Since you will be using your own node, you can skip the Alchemy part and directly use the web3 package as in the example above.

      +
    8. +
    9. +

      The received funds are transferred to the hot wallet when the transaction is approved by the network. The reception wallets always remain empty.

      +
    10. +
    +

    Performing Withdrawals#

    +

    Users must request withdrawals directly to the Exchange server through its user interface. After checking that the user has the required balance, the funds are transferred from the Exchange's hot wallet directly to the user's wallet. Here's a summary of the process:

    +
    +

    Withdrawing from an Exchange +

    +
    Withdrawing from an Exchange.
    +
    +
      +
    1. +

      The user requests a withdrawal to the Exchange server. The request includes some kind of user ID, the requested amount and the destination wallet's address.

      +
    2. +
    3. +

      The server checks that the user has the required balance to perform the withdrawal.

      +
    4. +
    5. +

      The server announces a transaction to the network (through the Exchange's own observer node) to move the requested funds from the hot wallet to the requested destination address.

      +

      See a JavaScript example in the Ethereum documentation. Since you will be using your own node, you can skip the Alchemy part and directly use the web3 package as in the example above.

      +
      +

      Caution

      +

      Please make sure you sign the transaction before submitting it, as shown in the example. +Unsigned transactions are ignored by the network.

      +
      +
    6. +
    7. +

      The requested funds are transferred to the user's wallet when the transaction is approved by the network.

      +
    8. +
    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/exchange/delegation/index.html b/exchange/delegation/index.html new file mode 100644 index 000000000..73b858ddd --- /dev/null +++ b/exchange/delegation/index.html @@ -0,0 +1,3929 @@ + + + + + + + + + + + + + + + + + + Delegating on the User's Behalf - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Delegating on the User's Behalf#

    +

    Delegation is one of the multiple ways in which the Flare blockchain rewards participants of the ecosystem. +In particular, delegation allows token holders to put their stake behind an FTSO data provider to increase its relative weight (See the FTSO page for more information). +In return, each time a data provider submits useful information it shares its reward with all the token holders that delegated to it.

    +

    The Delegation Guide details this process for users. +However, since Exchanges keep user's tokens, only Exchanges can perform delegation. +If you are an Exchange and want to offer your users the ability to earn rewards by delegation, this page summarizes the process and explains how to perform it on the user's behalf.

    +

    Introduction#

    +

    Flare (and Songbird) accounts can delegate any percentage they choose of their tokens to one or two FTSO data providers.

    +

    This limitation means that, if your Exchange keeps all users' tokens in a single wallet (as described in the Architecture of an Exchange page), you cannot give your users the option to select the data provider they want to delegate to: The wallet containing all tokens can only delegate to one (or two) data providers.

    +

    Keeping this in mind, this page explains how to delegate the users' tokens and collect the rewards.

    +
    +

    Reward Epochs

    +

    As shown later, several features of the delegation mechanism are timed in Reward Epochs.

    +
      +
    • On Songbird, these epochs last 7 days and start every Saturday at around 8:40AM UTC.
    • +
    • On Flare, they last 3.5 days and start roughly every Monday at 7:00 UTC and Thursday at 19:00 UTC.
    • +
    +
    +

    Selecting a Data Provider#

    +

    It is the Exchange that must select the FTSO data provider upon which to delegate, so the first step is to choose the one you are most confident to provide consistently good data (and therefore higher rewards).

    +

    Anyone can become an FTSO data provider, but only the ones that had the most voting power during the previous reward epoch are available for delegation.

    +

    The list of available data providers for the current reward epoch can be retrieved from the VoterWhitelister smart contract, method getFtsoWhitelistedPriceProviders. +There exist a number of websites like flaremetrics.io or ftso-signal-providers that display this information in a far more convenient way.

    +
    +

    Note

    +

    Data providers take a fee before sharing their rewards with their delegators. +An Exchange can decide to run its own data provider to avoid paying this fee to an external entity, at the cost of having to develop a good price prediction algorithm.

    +

    Keep in mind that FTSO data providing is already a very competitive business, and only the most successful algorithms are being rewarded.

    +
    +

    Lastly, delegations can be changed at any time, but they are only taken into account once per reward epoch (See more details in the FTSO page). +Therefore, depending on the time it is submitted, a new delegation will not take effect until the beginning of the next reward epoch, or the one after that. +Furthermore, rewards cannot be collected until another reward epoch has elapsed.

    +

    Delegation Process#

    +

    See Manual Delegation and Claiming in the FTSO page.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/exchange/index.html b/exchange/index.html new file mode 100644 index 000000000..ac8a28e18 --- /dev/null +++ b/exchange/index.html @@ -0,0 +1,3960 @@ + + + + + + + + + + + + + + + + + + Exchange Guides - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    + + + + + + + + + +

    Exchange Guides#

    +

    This section contains information and bits of advice for Exchanges willing to support the Flare blockchain.

    +

    The first thing you should know is that:

    +
    +

    Flare is used just like Ethereum!

    +

    Even though the node code is different, Flare offers the same API as Ethereum so you can integrate with it in the same way.

    + +
    +

    Quick Information about Flare#

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Website addressflare.network
    Brand assetsGoogle Drive
    Rosetta API endpointhttps://flare-rosetta-api.flare.network/
    Node source codegithub.com/flare-foundation/flare
    Node installation documentationdocs.flare.network/infra/observation/deploying
    Node requirements8 CPU, 16 GB RAM, 2 TB disk space
    Maximum block rate1 block/second.
    Token namesFLARE, SONGBIRD
    TickersFLR, SGB
    Tokens precision18 decimal places
    Supported walletsdocs.flare.network/user/wallets
    +

    Network configuration information, including:

    + +
    +

    Note

    +

    The $FLR and $SGB tokens are not ERC-20 tokens: they are the native currency of Flare (the Main network) and Songbird (The Canary network) respectively. As such, these tokens are handled the same way $ETH is handled on the Ethereum blockchain.

    +
    +

    Select one of the topics below:

    + + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/exchange/troubleshooting/index.html b/exchange/troubleshooting/index.html new file mode 100644 index 000000000..6c9e52a39 --- /dev/null +++ b/exchange/troubleshooting/index.html @@ -0,0 +1,3833 @@ + + + + + + + + + + + + + + + + + + Troubleshooting Guide - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    + + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/google3bfa582f85e44cb8.html b/google3bfa582f85e44cb8.html new file mode 100644 index 000000000..496895756 --- /dev/null +++ b/google3bfa582f85e44cb8.html @@ -0,0 +1 @@ +google-site-verification: google3bfa582f85e44cb8.html \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 000000000..291e743e1 --- /dev/null +++ b/index.html @@ -0,0 +1,4019 @@ + + + + + + + + + + + + + + + + + + Welcome to the Flare Network Technical Documentation - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + + + + + + + + + + + + +
    +
    + + + + + + + + + + +

    Welcome to the Flare Network Technical Documentation#

    +

    New here? Start with What Is Flare?

    + +

    These pages are a Work In Progress. +Use the contact buttons at the bottom of the page if there is anything you cannot find here!

    + + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/infra-icon.svg b/infra-icon.svg new file mode 100644 index 000000000..190843e43 --- /dev/null +++ b/infra-icon.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/infra/attestation/index.html b/infra/attestation/index.html new file mode 100644 index 000000000..25ec0121b --- /dev/null +++ b/infra/attestation/index.html @@ -0,0 +1,3817 @@ + + + + + + + + + + + + + + + + + + Attestation Providers - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    + + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/infra/attestation/operating/index.html b/infra/attestation/operating/index.html new file mode 100644 index 000000000..c1a95e2b7 --- /dev/null +++ b/infra/attestation/operating/index.html @@ -0,0 +1,3826 @@ + + + + + + + + + + + + + + + + + + Operating an Attestation Provider - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Operating an Attestation Provider#

    +

    Anyone may operate an attestation provider without any capital requirement (see the attestation-client repository for deployment information), which can readily be used as a local provider on validators that trust it.

    +

    To be included in the default set, though, the same operator must run one of the top-performing FTSO data providers to prove its commitment to the network's well-being. +More details will be added soon.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/infra/data/deploying/index.html b/infra/data/deploying/index.html new file mode 100644 index 000000000..c3d047f1a --- /dev/null +++ b/infra/data/deploying/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/infra/data/index.html b/infra/data/index.html new file mode 100644 index 000000000..27dbfb59d --- /dev/null +++ b/infra/data/index.html @@ -0,0 +1,3819 @@ + + + + + + + + + + + + + + + + + + FTSO Data Providers - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    + + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/infra/data/managing-ecosystem/exploring-collusion/index.html b/infra/data/managing-ecosystem/exploring-collusion/index.html new file mode 100644 index 000000000..0b2d36103 --- /dev/null +++ b/infra/data/managing-ecosystem/exploring-collusion/index.html @@ -0,0 +1,4049 @@ + + + + + + + + + + + + + + + + + + Exploring Collusion - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Exploring Collusion#

    +

    Members of the FTSO Management Group are responsible for monitoring the FTSO ecosystem for malicious behaviors, such as collusion. +Collusion in the FTSO ecosystem is a problem for several reasons:

    +
      +
    • It artificially raises the power of the colluding data providers, which endangers the quality of the FTSO data.
    • +
    • It is specifically forbidden by FIP.02.
    • +
    +

    In a healthy ecosystem, submissions from data providers are chasing the median, and they are close to the reward band. Collusion is possibly evident in this environment when multiple data providers submit similar data that is relatively distant from the median. +To explore possible collusion between data providers in the ecosystem, use the collusion tool in the Flare FTSO Monitor.

    +

    Collusion Tool Dashboard#

    +

    The following image shows the dashboard of the collusion tool:

    +
    +

    FTSO Monitor Collusion Tool

    +
    FTSO Monitor Collusion Tool.
    +
    +

    The elements of the collusion tool are:

    +
      +
    • Threshold: Scans for the percentage of similarity that you want to see between the data providers for which you search. + Details about how to specify the percentage are in step 2 of the procedure to identify data providers.
    • +
    • Search: Locates data providers within the FTSO ecosystem. + Details about how to specify names of data providers are in step 3 of the procedure to identify data providers.
    • +
    • End time: Sets the date you want to view.
    • +
    • Cluster map of data providers: Illustrates data providers that might be colluding by linking them with weighted connectors. +The map is generated based on the data submitted during 00:00 - 24:00 UTC on the date you select in the End time field. +Heavier weights suggest more potential for collusion than lighter weights.
    • +
    +

    For example, the following image of part of the cluster map shows a pair of data providers weighted heavily enough to suggest a case of collusion.

    +
    +

    Heavily Weighted Data Providers

    +
    Heavily Weighted Data Providers.
    +
    +

    Identifying Colluding Data Providers#

    +
    +

    For exploratory purposes only

    +

    Use this tool only for exploratory purposes. +Do not exclusively rely on this tool to infer that collusion has occurred.

    +
    +
      +
    1. Open the collusion tool in the FTSO Monitor. + The collusion tool dashboard is displayed.
    2. +
    3. In the Threshold field, specify the percentage of similarity you want to see. + For example, if you specify .98, 98% of the weakest similarities are omitted, and the strongest 2% of the similarities are displayed.
    4. +
    5. +

      Use one of the following search methods:

      +
        +
      • If you know the names of the data providers you want to compare, specify them in a comma-separated series in the Search field. The field is case-sensitive and accepts partial names of providers. For example, if you specify FTSO, the tool selects all providers that have FTSO in their names, regardless of case.
      • +
      • In the cluster map, locate data provider nodes linked with heavily weighted connectors by zooming in. +Zoom in and out by using the appropriate method on your device, such as spinning a mouse wheel. +After you zoom in, you can center a node or a group of them on the screen by clicking the map and dragging it. +Select at least two providers you want to compare by pressing and holding the Control key while you click each data provider node.
      • +
      +
    6. +
    7. +

      Optional: Explore a previous date by changing the End time option to a date other than the current date.

      +
    8. +
    9. Click Compare. + As shown in the following image, the Prices tab opens, displaying a line graph that shows the data submitted by each specified data provider during the most recent 30-minute interval on the date you selected in the End time field.
    10. +
    +
    +

    Price History

    +
    Price History.
    +
    +

    Comparing Price History#

    +

    In the price history, analyze the data for multiple providers consistently submitting prices that are distant from the median but near each other.

    +

    In your analysis, consider anomalous situations, such as an exchange going offline, a vast region of the internet becoming disconnected, or a stablecoin depegging from its reference asset. +In these situations, submitted data from providers is expected to be wildly different. If multiple providers still manage to submit similar data, carefully examine them.

    +

    Although a depegged stablecoin should not affect FTSO prices, because price pairs use USD instead of a stablecoin, prices have been affected in the past, and the evidence is noticeable in the line graph. This situation reveals data providers who were using a stablecoin instead of USD in their submissions.

    +

    As shown in the image in each tab below, additional details about the data providers and the submitted data are provided beneath the price-history dashboard. +The details on Songbird are different from the details on Flare because of the secondary reward band implemented by STP.02.

    +

    Use these details to more deeply explore the similarities between the data submitted by the providers you selected.

    +
    +
    +
    +

    + Details About Specified Data Providers +
    Details About Specified Data Providers.
    +

    +
      +
    • Address: The hexadecimal identifier of the data provider. + The circle beside the address corresponds with the address in the graph. + The correspondence between the circle and the address works for up to five addresses.
    • +
    • Number of cases: The quantity of data samples during the specified interval.
    • +
    • High: The percentage of samples above the reward band.
    • +
    • Low: The percentage of samples below the reward band.
    • +
    • Out: The total percentage of high combined with low.
    • +
    • Border: The percentage of samples on the border of the reward band.
    • +
    • Inner: The percentage of samples inside the reward band.
    • +
    • Expected: The success rate of the data. + The value is represented as a percentage and calculated by the formula Inner + 0.5(Border).
    • +
    +
    +
    +

    In the following image, the percentage of samples are color-coded in the following ways:

    +
      +
    • IQR reward band: Interquartile range percentages are blue.
    • +
    • Pct reward band: Percentage range percentages are red.
    • +
    +

    + Details About Specified Data Providers +
    Details About Specified Data Providers.
    +

    +
      +
    • Address: The hexadecimal identifier of the data provider. + The circle beside the address corresponds with the address in the graph. + The correspondence between the circle and the address works for up to five addresses.
    • +
    • Number of cases: The quantity of data samples during the specified interval.
    • +
    • High: The percentage of samples above the reward bands.
    • +
    • Low: The percentage of samples below the reward bands.
    • +
    • Out: The total percentage of high combined with low.
    • +
    • Border: The percentage of samples on the borders of the reward bands.
    • +
    • Inner: The percentage of samples inside the reward bands.
    • +
    • Expected: The success rate of the data. + The value is represented as a percentage and calculated by the formula Inner + 0.5(Border).
    • +
    +
    +
    +
    +

    The Similarity Metric#

    +

    This section describes the similarity metric used to obtain the cluster map. +To estimate collusion, the similarity metric assigns a value of similarity between data submitted by pairs of data providers. +As previously stated, collusion between data providers is evident when they submit similar data that is relatively distant from the median because similar algorithms will make similar mistakes.

    +

    For data providers DP1 and DP2 during a given range of price epoch for comparison, the prices P1 and P2 submitted for each cryptocurrency pair and epoch are checked. +If both prices are available alongside the median price M, the contribution to the collusion metric is calculated in the following way:

    +
    diff = abs(P2 - P1)
    +diff1 = abs(P1 - M)
    +diff2 = abs(P2 - M)
    +
    +relativePriceDiff = max(diff / M, threshold)
    +relativeOffset = scale(min(diff1, diff2) / M)
    +
    +contribution = relativeOffset / relativePriceDiff
    +
    +

    where

    +
    threshold = 0.00000001
    +scale(x) = 20000 x + 1, if x < 0.0001 and 3 otherwise
    +
    +

    The threshold is selected to avoid a division by zero when the two providers submit exactly the same data, and scale displays the data more clearly.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/infra/data/managing-ecosystem/index.html b/infra/data/managing-ecosystem/index.html new file mode 100644 index 000000000..c0be5d7bd --- /dev/null +++ b/infra/data/managing-ecosystem/index.html @@ -0,0 +1,4189 @@ + + + + + + + + + + + + + + + + + + Managing the Ecosystem - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + + + + +
    +
    + + + + + + + + + + +

    Managing the Ecosystem#

    +

    The following information explains how to manage the FTSO ecosystem by participating in the FTSO Management Group, as described in FIP.02, which was accepted on March 6, 2023.

    +

    To prevent malicious behaviors that impair the FTSO ecosystem, the FTSO Management Group reports possible infractions committed by FTSO data providers and determines whether to punish them.

    +

    Punished data providers are chilled, which means they are removed from the whitelist, either temporarily or permanently, depending on the quantity of infractions they have committed.

    +

    Any address can request to be a member of the group, but only upstanding FTSO data providers are accepted.

    +

    As a security measure to be used only when absolutely necessary, the Flare Foundation reserves the right to add and remove members on its own accord.

    +

    Management Process#

    +

    The group adheres to the following management process. +For complete details about each step in the process, click each hyperlink.

    +
      +
    1. Discuss possible infractions (section 2.2.1).
    2. +
    3. Submit a chill proposal (section 2.2.2).
    4. +
    5. Vote on the proposal (sections 2.2.2 - 2.2.4).
    6. +
    +

    Depending on the outcome of the vote, the provider might be chilled (section 2.3).

    +

    Discussing Infractions#

    +

    When you suspect a data provider is harming the ecosystem, you must discuss the malicious behavior with other group members in the Flare FTSO Self-Policing Forum to inform the FTSO community about the problem and gather the necessary quorum for a potential vote. +It facilitates the decision about whether to submit a formal proposal to chill the attacker. +The discussion is not binding.

    +

    Retrieving the PollingFtso contract#

    +

    The PollingFtso contract handles interactions such as managing group members, submitting proposals, voting, and more. +The following procedure explains how to interact directly with this contract. +However, if you prefer a simpler interface, the Flare community is developing front-ends to facilitate the interactions, such as Flaremetrics.

    +
      +
    1. Open a block explorer for the appropriate network.
    2. +
    3. Follow the Retrieval from Blockchain procedure to find and open the PollingFtso contract. + The Contract Address Details page is displayed.
    4. +
    5. Optional: If you need to call a method in the Write tab, click the Write Contract tab, click Connect Wallet, and complete the steps to connect your wallet.
    6. +
    +

    After the PollingFtso contract is open in the explorer, you can complete operations to manage members and chill proposals.

    +

    Managing Group Members#

    +

    To be a member you need to be an upstanding data provider, which means:

    +
      +
    • You have received FTSO rewards for the last 20 reward epochs.
    • +
    • You have not been chilled in the last 20 reward epochs.
    • +
    • You have not been removed from the group in the last week.
    • +
    +

    After the PollingFtso contract is open in the explorer, you can do the following operations, among others.

    +

    Adding Members#

    +

    Anyone can request to become a member of the FTSO Management Group.

    +
      +
    1. In the Write tab, locate the addMember method, and click Write to call it.
    2. +
    3. +

      Follow the steps to complete the transaction in your wallet.

      +

      Your request to be added to the group is submitted. +If you meet the conditions of an upstanding data provider, you are automatically added to the group.

      +
    4. +
    +

    Removing Members#

    +

    Anyone can ask for a member of the FTSO Management Group to be removed.

    +
      +
    1. +

      In the Write tab, locate the removeMember method, and specify a value for this parameter:

      +
        +
      • _account(address): The address of the member you want to remove from the group.
      • +
      +
    2. +
    3. +

      Click Write to call the removeMember method.

      +
    4. +
    5. +

      Follow the steps to complete the transaction in your wallet.

      +

      Your request to remove a member from the group is submitted. +If the member no longer meets the conditions of an upstanding data provider, the member is immediately removed.

      +
    6. +
    +

    Managing Chill Proposals#

    +

    After the PollingFtso contract is open in the explorer, you can do the following operations, among others.

    +

    Submitting a Proposal#

    +

    If you are a member of the FTSO Management Group or a member's proxy, you can submit a chill proposal.

    +
      +
    1. +

      In the Write tab, locate the propose method, and specify values for these parameters:

      +
        +
      • _description(string): A free-form description of the problem to be voted on. + It does not have a fixed structure, but it must contain at least the URL for the discussion in the forum (section 2.2.2.d)
      • +
      • value(FLR or SGB): The cost to call the propose method to submit the proposal, which you must specify as the value. +The current cost is 100 $FLR or $SGB. +Because this cost can fluctuate, retrieve the current cost by locating the proposalFeeValueWei method in the Read tab, which automatically displays the cost.
      • +
      +
    2. +
    3. +

      Click Write to call the propose method.

      +
    4. +
    5. +

      Follow the steps to complete the transaction in your wallet.

      +

      Your proposal is submitted, and the proposalId is returned.

      +
    6. +
    7. +

      Post the proposalId in the discussion thread so that members of the group can use it to vote on the proposal.

      +
    8. +
    +

    Voting on a Proposal#

    +

    You can vote on a proposal when the following conditions are met:

    +
      +
    • You are a member of the FTSO Management Group or a member's proxy.
    • +
    • The proposal is active.
    • +
    +

    To vote on a proposal:

    +
      +
    1. +

      In the Write tab, locate the castVote method, and specify values for these parameters:

      +
        +
      • _proposalId(uint256): The proposal ID posted by the proponent in the discussion thread. + This ID was obtained by proponent when the proposal was submitted. +If you specify nonexistent IDs or IDs for proposals that have completed, the transaction reverts, and the explorer returns empty results.
      • +
      • +

        _support(uint8): Specify one of the following values.

        +
          +
        • 0: Vote against the proposal.
        • +
        • 1: Vote in favor of the proposal.
        • +
        +

        If you specify values other than 0 or 1, the transaction reverts.

        +
      • +
      +
    2. +
    3. +

      Click Write to call the castVote method.

      +
    4. +
    5. +

      Follow the steps to complete the transaction in your wallet.

      +

      Your vote is cast.

      +
    6. +
    +

    Setting a Proxy Voter#

    +

    If you are a member of the group, you can declare one address that can manage proposals and vote on them on your behalf. +This address is known as your proxy. +Your proxy can submit proposals and vote on them.

    +
      +
    1. +

      In the Write tab, locate the setProxyVoter method, and specify the value for this parameter:

      +
        +
      • _proxyVoter(address): The address you want to declare as your proxy.
      • +
      +
    2. +
    3. +

      Click Write to call the setProxyVoter method.

      +
    4. +
    5. +

      Follow the steps to complete the transaction in your wallet.

      +

      The specified address is set as your proxy voter.

      +
    6. +
    +

    Removing a Proxy Voter#

    +
      +
    1. +

      In the Write tab, locate the setProxyVoter method, and specify the value for this parameter:

      +
        +
      • _proxyVoter(address): Specify the zero address 0x0000000000000000000000000000000000000000.
      • +
      +
    2. +
    3. +

      Click Write to call the setProxyVoter method.

      +
    4. +
    5. +

      Follow the steps to complete the transaction in your wallet.

      +

      The previously specified proxy address is revoked.

      +
    6. +
    +

    Determining Your Proxy Voter's Address#

    +
      +
    1. +

      In the Read tab, locate the providerToProxy method, and specify the value for this parameter:

      +
        +
      • (address): The address that declared the proxy.
      • +
      +
    2. +
    3. +

      Click Query to call the providerToProxy method.

      +

      The address of the proxy voter is returned.

      +
    4. +
    +

    Retrieving the Last Proposal#

    +

    In the Read tab, locate the getLastProposal method.

    +

    The number of the most recent proposal and its description are displayed.

    +

    Retrieving a List of Group Members#

    +

    In the Read tab, locate the getManagementGroupMembers method.

    +

    A list of the addresses of members is displayed.

    +

    Retrieving a Proposal Description#

    +
      +
    1. +

      In the Read tab, locate the getProposalDescription method, and specify the value for this parameter:

      +
        +
      • proposalId(uint256): The ID of the proposal whose description you want. + If you don't know the proposal ID, refer to the proposal's discussion thread.
      • +
      +
    2. +
    3. +

      Click Query to call the getProposalDescription method.

      +

      The description of the specified proposal ID is returned. +If you specified a nonexistent ID for the proposalId parameter, an empty string is returned.

      +
    4. +
    +

    Retrieving a Vote Count#

    +
      +
    1. +

      In the Read tab, locate the getProposalVotes method, and specify the value for this parameter:

      +
        +
      • proposalId(uint256): The ID of the proposal whose vote count you want. + Proposal IDs are posted in its corresponding discussion thread.
      • +
      +
    2. +
    3. +

      Click Query to call the getProposalVotes method.

      +

      The number of votes in favor of the proposal and the number of votes against it are returned. +If you specified a nonexistent ID for the proposalId parameter, 0 is returned as the number of votes for the proposal and as the number of votes against it.

      +
    4. +
    +

    Determining a Member's Vote Status#

    +
      +
    1. +

      In the Read tab, locate the hasVoted method, and specify the value for these parameters:

      +
        +
      • proposalId(uint256): The ID of the proposal for which you want to determine a member's vote status.
      • +
      • voter(address): The address of the member. +If you do not know the address, refer to the list of addresses for all group members.
      • +
      +
    2. +
    3. +

      Click Query to call the hasVoted method.

      +

      A boolean value indicating whether the member has voted is returned. +If you specified a nonexistent ID for the proposalId parameter, false is returned.

      +
    4. +
    + + + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/infra/data/managing-ecosystem/monitoring-price-history/index.html b/infra/data/managing-ecosystem/monitoring-price-history/index.html new file mode 100644 index 000000000..76cb2bfc7 --- /dev/null +++ b/infra/data/managing-ecosystem/monitoring-price-history/index.html @@ -0,0 +1,3942 @@ + + + + + + + + + + + + + + + + + + Monitoring Price History - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Monitoring Price History#

    +
    +

    Work in Progress

    +

    Some functions for monitoring price history are works in progress.

    +
    +

    In the FTSO system, price histories show the evolution of submitted and calculated prices over time on a line graph. +The data plotted on the line graph enables you to study in detail the relationship between suspicious data providers, which you can first observe by using the collusion tool. +The data on the graph includes:

    +
      +
    • Median prices.
    • +
    • Quantity of votes. + This information helps you locate outage periods in which a large-enough number of providers failed to submit data to impact the graph.
    • +
    • Reward bands. + This information indicates the dispersion of the submitted values.
    • +
    +

    Additionally, if the price history is displayed because you selected data providers by using the collusion tool, the graph includes submissions by those providers, enabling you to see:

    +
      +
    • Whether a submission is inside or outside of the reward band and by how much.
    • +
    • Whether multiple providers were chasing each other instead of the median, which could imply collusion.
    • +
    +

    Price-History Dashboard#

    +
    +

    Price-History Dashboard

    +
    Price-History Dashboard.
    +
    +

    The elements of the dashboard are:

    +
      +
    • Navigation Bar: The main functions of the Flare FTSO Monitor.
    • +
    • Network Selector: Toggles between FTSO Monitors for other Flare networks.
    • +
    • Line Graph: Displays the price history and the number of votes when you are not comparing specific data providers.
    • +
    • Cryptocurrency Selector: Toggles between supported cryptocurrencies.
    • +
    • Exchange Selector: Feature is currently not enabled.
    • +
    • Date and Time Selector: Isolates the price history for the date and time you specify.
    • +
    • View Selector: Toggles to relative view, which typically makes reward bands on the graph more apparent.
    • +
    • Time Frame Slider: Changes the time frame displayed in the graph based on selections you make by moving the slider.
    • +
    • Interval Selector: Toggles the interval during which you want to view price history.
    • +
    +

    The default settings are:

    +
      +
    • Cryptocurrency symbol: XRP
    • +
    • Time frame: 30m
    • +
    • End time: The current date and time when you opened the Prices tab.
    • +
    +

    Comparing Price History#

    +
      +
    1. Open the price-history dashboard in the FTSO Monitor. +The price-history dashboard, which is based on the default settings, is displayed.
    2. +
    3. Optional: If you need to monitor the FTSO ecosystem on a different network, click the Network Selector, as shown in the price-history dashboard, and select a different network.
    4. +
    5. +

      For more specific comparisons, change the default settings by using the various elements in the dashboard to further express the data:

      +
        +
      • Toggle the currencies and interval.
      • +
      • Adjust the date and time.
      • +
      • Add or remove from the graph some data, such as an address, a currency's median price, the voter count, and the award area.
      • +
      +
    6. +
    +

    If the price-history dashboard opened because you compared data providers using the collusion tool, the list of data providers is also displayed below the dashboard.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/infra/data/operating/index.html b/infra/data/operating/index.html new file mode 100644 index 000000000..881f8f8a7 --- /dev/null +++ b/infra/data/operating/index.html @@ -0,0 +1,4258 @@ + + + + + + + + + + + + + + + + + + Operating a Data Provider - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + + + + +
    +
    + + + + + + + + + + +

    Operating a Data Provider#

    +

    Introduction#

    + +

    Data providers play an essential role in the decentralized oracle system by submitting data to on-chain contracts deployed on the Flare and Songbird networks. +Operating a data provider generates rewards in $FLR, $SGB, or both for you and the people who delegate tokens to you. +To maximize your rewards, your data provider needs to be constantly available and operating. +If your data provider is unavailable and doesn't send data during a specific epoch, you and your delegators won't earn rewards during that epoch.

    +

    If all the submission and reveal transactions are successful, the cost is approximately 3 - 4 $FLR or $SGB per day.

    +

    Data providers consist of the following code components, and you can write them in any language:

    +
      +
    • FTSO interface: The code that submits data to the FTSO. + This code is all the necessary logic to determine which data epoch you want to submit data in and to assess when and what to submit throughout all reward epochs.
    • +
    • Data algorithm: The code that runs the algorithm that collects and processes data. + The more efficient this code is the better advantage over competing data providers you will have. + Consider these tips for maximizing your advantage.
    • +
    +

    The rest of this guide explains how to deploy and operate a data provider.

    +

    Prerequisites#

    +

    While none of the listed prerequisites are required, you will be more successful if you have them before you try to deploy an FTSO data provider:

    +
      +
    • Familiarity with smart contracts, signal processing, game theory, and prompt data submission on blockchains
    • +
    • +

      Experience with a coding language that has a web3 library, for example:

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      LanguageWeb3 Library
      Gogo-web3
      Javaweb3.j
      JavaScriptethers.js, web3.js
      Node.jsethers.js, web3.js
      Pythonweb3.py
      Rustrust-web3
      +
    • +
    +

    Getting Started#

    +

    To start building your data provider, use the npm kick-off package. +It showcases the main contracts related to whitelisting a data provider and submitting data, and it enables you to deploy FTSO mock contracts in a local setup and submit data to those contracts.

    +

    Providing data by using this package is like providing data on-chain. +The following aspects work identically in the package and on-chain:

    +
      +
    • Smart-contract APIs
    • +
    • Events
    • +
    +

    Timing aspects in the package work similarly but not identically to timing aspects on-chain. +The package does not run the weighted-median algorithm or do calculations to distribute rewards like the FTSO smart contract deployed on-chain does.

    +

    The Flare Network price provider repository shows an example of a data-provider implementation. +This implementation shows the FTSO interface and a sample data algorithm. +To earn rewards, you must write your own data algorithm.

    +

    Interacting with Smart Contracts#

    +

    Data providers interact primarily with the PriceSubmitter contract and the different FTSO contracts. +Other useful contracts are:

    +
      +
    • FtsoRegistry: Holds information about specific FTSOs, their symbols, indices, and addresses. + To see supported tickers, query the getSupportedSymbols method. + New tickers can be added by a governance vote.
    • +
    • FtsoManager: Holds epoch and voting-related configuration data, oversees all FTSOs, and gives access to additional useful contracts, such as the Inflation and Supply contracts.
    • +
    • VoterWhitelister: Accepts the names of data providers that list themselves to submit data.
    • +
    +

    Find these contract's addresses in the Contract Addresses page.

    +

    Generating Random Numbers#

    +

    The data-providing process is structured as a commit-and-reveal scheme to prevent users from copying another user's submitted data. +The commit-and-reveal phases are restricted to only a few minutes in duration. +With each reveal the data provider also provides a random number. +The random number is used first as a salt in the commit-and-reveal scheme and later during the reward calculation process.

    +

    Strong random numbers are important for network security because they are the only true source of randomness on the network, and they make the commit-and-reveal scheme resilient to attacks. Random numbers below 2128 are considered weak and unsafe, and they are rejected when they are revealed.

    +

    To provide strong, cryptographically secure, random numbers with high entropy and sufficient range, consider implementing the following strategies:

    +
      +
    • Use available random-number generators, such as the csprng library for Node.js applications or the web3.utils.toBN(web3.utils.randomHex(32)) function in the web3.utils package for JavaScript.
    • +
    • Submit 256-bit random numbers.
    • +
    +

    Calculating Hash for the Commit-and-Reveal Scheme#

    +

    The FTSO price provider shows the complete specification for the commit-and-reveal scheme.

    +

    The following code snippets show how to generate hashes in Typescript and Python using publicly available web3 libraries:

    +
    +
    +
    +
    import BN from "bn.js";
    +import {
    +    BigNumber
    +} from "ethers";
    +import {
    +    ethers
    +} from "hardhat";
    +const MIN_RANDOM = web3.utils.toBN(2).pow(web3.utils.toBN(128));
    +
    +function submitHash(ftsoIndices: (number | BN | BigNumber)[],
    +    prices: (number | BN | BigNumber)[],
    +    random: number | BN | BigNumber,
    +    address: string): string {
    +
    +    return ethers.utils.keccak256(web3.eth.abi.encodeParameters(
    +        ["uint256[]", "uint256[]", "uint256", "address"],
    +        [ftsoIndices, prices, random, address]));
    +}
    +const ftsoIndices = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    +const randoms = [MIN_RANDOM, MIN_RANDOM.addn(5), MIN_RANDOM.addn(1059),
    +    MIN_RANDOM.addn(10682), MIN_RANDOM.addn(159726)
    +];
    +const prices = [0, 1, 2, 3, 5, 10, 50, 100, 101, 10 ** 5 + 1, 10 ** 8];
    +const addrs = [accounts[10], accounts[11], accounts[12], accounts[13]];
    +
    +console.log(`Prices: ${prices}`);
    +for(let addr of addrs) {
    +    console.log(`Address: ${addr}`);
    +    for(let random of randoms) {
    +        console.log(`\tRandom: ${random}`)
    +        const hash = submitHash(ftsoIndices, prices, random, addr);
    +        console.log(`\t\t${hash}`);
    +    }
    +}
    +
    +
    +
    +
    from typing import List
    +from web3 import Web3
    +import eth_abi
    +
    +minimal_random = 2 ** 128
    +
    +def submit_price_hash(
    +    ftsoIndices: List[int], prices: List[int], random: int, address: str
    +) -> str:
    +    assert len(ftsoIndices) == len(prices)
    +    assert list(sorted(ftsoIndices)) == ftsoIndices and len(
    +        set(ftsoIndices)
    +    ) == len(ftsoIndices), "Indices are non increasing"
    +    return Web3.keccak(
    +        eth_abi.encode_abi(
    +            ["uint256[]", "uint256[]", "uint256", "address"],
    +            [ftsoIndices, prices, random, address],
    +        )
    +    ).hex()
    +
    +
    +def test_fun(
    +    prices: List[int],
    +    random: int,
    +    address="0xD7de703D9BBC4602242D0f3149E5fFCD30Eb3ADF",
    +) -> List[str]:
    +    return submit_price_hash(list(range(len(prices))), prices, random, address)
    +
    +
    +addrs = [
    +    "0xD7de703D9BBC4602242D0f3149E5fFCD30Eb3ADF",
    +    "0xEa960515F8b4C237730F028cBAcF0a28E7F45dE0",
    +    "0x3d91185a02774C70287F6c74Dd26d13DFB58ff16",
    +]
    +prices = [0, 1, 2, 3, 5, 10, 50, 100, 101, 10 ** 5 + 1, 10 ** 8]
    +randoms = [
    +     min_random + r for r in
    +     [0, 1, 100, 101, 100000000000000000000]
    +]
    +for addr in addrs:
    +    print(f"Address: {addr}")
    +    for rand in randoms:
    +        print(f"  Random: {rand}")
    +        print("    hash:", test_fun(prices, rand, addr))
    +    print()
    +
    +
    +
    +
    +
    +

    Info

    +

    To see sample code for calculating submit hashes using the web3.py library, see the hasher.py gist.

    +
    +

    Retrieving Information About Rewarded Data#

    +

    Listen for PriceFinalized events, which contain information about calculated median data and rewarding bounds. +Each FTSO emits these events.

    +

    Managing Vote Power#

    +
      +
    • +

      To check your vote power in a specific vote power block, use the votePowerOfAt method in the WNat contract.

      +
    • +
    • +

      To find the vote-power block of the current reward epoch, use the getCurrentRewardEpoch method in the FtsoManager contract. + Then, use the getRewardEpochVotePowerBlock method in the same contract.

      +
    • +
    • +

      Vote power delegated to you belongs to only you; you cannot redelegate it. + To retrieve information about delegations you receive, listen to Delegate events because this information is not contained in any on-chain structure.

      +
    • +
    +

    Retrieving Price Epoch Information#

    +

    Use the getPriceEpochConfiguration method in the FtsoManager contract to retrieve:

    +
      +
    • When the first price epoch started, as a UNIX timestamp.
    • +
    • The duration of every price epoch, in seconds.
    • +
    • The duration of every reveal phase, in seconds.
    • +
    +

    These numbers allow you to calculate the price epoch number from any timestamp.

    +

    The duration of price epochs is fixed and can only change through a governance decision.

    +

    Submitting Data On-Chain#

    +

    After you feel comfortable running the local npm package, you can start submitting your data on the real network.

    +

    To run on the real network, you need to:

    +
      +
    • Gain vote power: You can whitelist yourself as a data provider only if you have enough vote power.
    • +
    • Optimize your timing:
        +
      • Align with the on-chain time data. + Because the network is decentralized, the on-chain timestamp might skew up to 30 - 40 seconds from the real-world time. + To avoid missing commit-and-reveal periods, synchronize local time with global time through the Network Time Protocol (NTP).
      • +
      • The later you submit, the more time you have to gather data. + However, if you submit too late, you might miss the epoch window. + Find the balance that works best for you.
      • +
      +
    • +
    • Claim rewards: Ensure you regularly claim your rewards and wrap them to earn more vote power. Each FTSO emits a PriceFinalized event that contains information about calculated median data and rewarding bounds.
    • +
    • Set the gas limit of your commit-and-reveal transactions to around 2'500'000 gwei so that you provide enough gas.
    • +
    +

    Maximizing Your Data Algorithm's Performance#

    +

    Use the following tips:

    +
      +
    • Run your own observer node and submit all your data through it. + This will allow you to more efficiently and securely operate your data provider.
    • +
    • Gather your data directly from each source instead of using APIs provided by data aggregators.
    • +
    • Write your own code instead of relying entirely on third-party code.
    • +
    • Keep an open mind, and try new strategies to find your advantage over other data providers and keep it.
    • +
    +

    If your submissions are reverted, ensure the node you submit them through is healthy and has enough peers, and review the above tips.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/infra/data/whitelisting/index.html b/infra/data/whitelisting/index.html new file mode 100644 index 000000000..279cd313e --- /dev/null +++ b/infra/data/whitelisting/index.html @@ -0,0 +1,3955 @@ + + + + + + + + + + + + + + + + + + Working with Whitelists - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Working with Whitelists#

    +

    Introduction#

    +

    To be a data provider, you must be whitelisted. +Only the top 100 data providers with the most vote power per FTSO can submit data. +No minimum amount of vote power is required. +Per FTSO, a data provider's vote power is based on its balance of $WFLR or $WSGB. +When a data provider tries to whitelist itself, its vote power is calculated by the vote-power block of the current reward epoch. +Increased vote power on a different block will not enable your address to be whitelisted. +Vote power is only read and whitelists updated once per reward epoch. +Reward epochs start roughly on Saturdays at 8:40AM UTC on Songbird, and on Monday at 7:00 UTC and Thursday at 19:00 UTC on Flare. +Whitelisting a data provider is a fully decentralized process facilitated by the VoterWhitelister contract. +To retrieve this contract, see Contract Addresses.

    +

    To be added to the whitelist, submit a request for your address by using one of the functions listed in the next section. +When the whitelist is not full, your address is immediately added to it. +If both the list is full and your vote power is greater than the data provider with the lowest vote power, your address replaces that data provider's address on the whitelist.

    +

    If the number of spaces for data providers is ever reduced by governance, addresses will be removed from the whitelist one by one, beginning with the address with the lowest vote power.

    +

    Events are emitted to notify providers about changes of their status on the whitelist. +Once an address is delisted, submissions will also start reverting.

    +

    Requesting to be Added to the Whitelist or Relisted#

    +

    Use the following methods in the VoterWhitelister contract:

    +
      +
    • requestWhitelistingVoter(): Requests whitelisting for a specific asset index.
    • +
    • requestFullVoterWhitelisting(): Requests whitelisting for all assets.
    • +
    +

    Ensure you have more delegations and vote power than the data provider that has the lowest amount before the vote power block is chosen and before you submit the request to be relisted.

    +

    Reading Whitelists#

    +

    Each FTSO contains an array of whitelisted addresses. +Use the functions in the following contracts to determine whether you are on the list and eligible to submit data:

    +
      +
    • +

      VoterWhitelister contract

      +

      The getFtsoWhitelistedPriceProviders function returns a list of addresses for all data providers on the whitelist. +Specify the required index, run the query, and search for your address.

      +
    • +
    • +

      PriceSubmitter contract

      +

      The voterWhitelistBitmap function returns a bitmap corresponding to allowed FTSO indices in big-endian format. +Specify your address, run the query and examine the returned bitmap. +E.g., if you were allowed to submit prices for FTSOs with indices 0, 2 and 3, the returned bitmap would be 13 (1101 in binary).

      +
    • +
    +

    Monitoring Your Whitelist Status#

    +

    When you are added to a whitelist, the VoterWhitelisted event is emitted from the VoterWhitelister contract. +When you are removed from a whitelist, the VoterRemovedFromWhitelist event is emitted, and your subsequent submissions fail. +To stay aware of your whitelist status, consider listening to events that notify you about additions and removals when they happen.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/infra/index.html b/infra/index.html new file mode 100644 index 000000000..4133150a5 --- /dev/null +++ b/infra/index.html @@ -0,0 +1,3847 @@ + + + + + + + + + + + + + + + + + + Infrastructure Guides - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + +

    + + + + + + + + + + + + + + + + + + + + + + + + + +

    + + + + + + + + + +

    Infrastructure Guides#

    +

    This section contains step-by-step guides on how to deploy the different components that make up the Flare ecosystem, and be rewarded for it.

    +

    Select one of the topics below:

    + + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/infra/observation/deploying/index.html b/infra/observation/deploying/index.html new file mode 100644 index 000000000..8d23bef9c --- /dev/null +++ b/infra/observation/deploying/index.html @@ -0,0 +1,4413 @@ + + + + + + + + + + + + + + + + + + Deploying an Observer Node - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Deploying an Observer Node#

    +

    Introduction#

    +

    Observer nodes enable anyone to observe the network and submit transactions. +Unlike validator nodes, which provide state consensus and add blocks, observer nodes remain outside the network and have no effect on consensus or blocks.

    +

    Running an observer node is optional. +However, submitting transactions through your own node offers a number of benefits:

    +
      +
    • Transactions are sent directly to the network instead of through a third party, removing a potential security risk.
    • +
    • Public nodes are usually rate-limited (the amount of requests they accept per second is restricted). + Your own node does not have such restriction.
    • +
    • The time savings described above allow FTSO data providers to submit their data a few seconds later, thus having more time to gather data before submitting.
    • +
    +

    This guide explains how to deploy your own observer node so you can reap these benefits.

    +

    Prerequisites#

    +

    This guide contains different instructions depending on which Flare network you want to deploy to, so make sure you are aware of the available networks.

    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    HardwareSoftware
    CPU cores8Operating SystemUbuntu (18.04 or 20.04) or macOS (>= 10.15 Catalina)
    RAM32 GBDependenciesGo (>= 1.18.5)
    Disk space1 TB SSDgcc
    Disk growth2.5 TB/yearg++
    jq
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    HardwareSoftware
    CPU cores8Operating SystemUbuntu (18.04 or 20.04) or macOS (>= 10.15 Catalina)
    RAM32 GBDependenciesGo (>= 1.16.8)
    Disk space3.5 TB SSDgcc
    Disk growth2.5 TB/yearg++
    jq
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    HardwareSoftware
    CPU cores4Operating SystemUbuntu (18.04 or 20.04) or macOS (>= 10.15 Catalina)
    RAM16 GBDependenciesGo (>= 1.16.8)
    Disk space500 GB SSDgcc
    Disk growth250 GB/yearg++
    jq
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    HardwareSoftware
    CPU cores4Operating SystemUbuntu (18.04 or 20.04) or macOS (>= 10.15 Catalina)
    RAM16 GBDependenciesGo (>= 1.18.5)
    Disk space500 GB SSDgcc
    Disk growth250 GB/yearg++
    jq
    +
    +
    +
    +

    Plus a reliable IPv4 or IPv6 network connection, with an open public port.

    +

    Keep in mind that enabling pruning as described below can reduce the required disk space by as much as 60%.

    +

    Guide#

    +

    1. Installation#

    +
    +
    +
    +

    Clone the go-flare repository and run the build.sh script:

    +
    git clone https://github.com/flare-foundation/go-flare.git
    +cd go-flare/avalanchego
    +./scripts/build.sh
    +
    +

    The resulting executable will be build/avalanchego.

    +
    +

    Note

    +

    You can verify the installation by running:

    +
    go test $(go list ./... | grep -v /tests/) # avalanchego unit tests
    +cd ../coreth
    +go test ./... # coreth unit tests
    +cd ../avalanchego
    +
    +
    +
    +
    +

    Clone the go-songbird repository and run the build.sh script:

    +
    git clone https://github.com/flare-foundation/go-songbird.git
    +cd go-songbird/avalanchego
    +./scripts/build.sh
    +
    +

    The resulting executable will be build/flare.

    +
    +

    Note

    +

    You can verify the installation by running:

    +
    go test $(go list ./... | grep -v /tests/) # avalanchego unit tests
    +cd coreth
    +go test ./... # coreth unit tests
    +cd ..
    +
    +
    +
    +
    +
    +

    2. Songbird Node Whitelisting#

    +

    While Songbird network is being tested, all nodes wanting to peer with it (including observer nodes) need to have their IP address whitelisted.

    +

    To do this, please contact Tom T. over Discord (Tom T#7603), Telegram (@TampaBay7) or email (tom@flare.network) and request to be whitelisted.

    +
    +Checking the status of your Songbird whitelisting request +
    curl -m 10 -sX POST \
    +--data '{ "jsonrpc":"2.0", "id":1, "method":"info.getNodeIP" }' \
    +-H 'content-type:application/json;' \
    +https://songbird.flare.network/ext/info
    +
    +

    If your IP address is whitelisted, this command returns a JSON response. +Otherwise you will get a 403 error ("Forbidden").

    +
    +

    Please note that whitelisting is not needed on the Flare network or any of the Coston networks.

    +

    3. Run the Node#

    +

    This is the minimum command to quickly get your node up and running. +To understand each parameter read the following step before launching the node.

    +
    +
    +
    +
    ./build/avalanchego --network-id=flare --http-host= \
    +  --bootstrap-ips="$(curl -m 10 -sX POST \
    +    --data '{ "jsonrpc":"2.0", "id":1, "method":"info.getNodeIP" }' \
    +    -H 'content-type:application/json;' https://flare.flare.network/ext/info \
    +    | jq -r ".result.ip")" \
    +  --bootstrap-ids="$(curl -m 10 -sX POST \
    +    --data '{ "jsonrpc":"2.0", "id":1, "method":"info.getNodeID" }' \
    +    -H 'content-type:application/json;' https://flare.flare.network/ext/info \
    +    | jq -r ".result.nodeID")"
    +
    +
    +
    +
    ./build/flare --network-id=songbird --http-host= \
    +  --bootstrap-ips="$(curl -m 10 -sX POST \
    +    --data '{ "jsonrpc":"2.0", "id":1, "method":"info.getNodeIP" }' \
    +    -H 'content-type:application/json;' https://songbird.flare.network/ext/info \
    +    | jq -r ".result.ip")" \
    +  --bootstrap-ids="$(curl -m 10 -sX POST \
    +    --data '{ "jsonrpc":"2.0", "id":1, "method":"info.getNodeID" }' \
    +    -H 'content-type:application/json;' https://songbird.flare.network/ext/info \
    +    | jq -r ".result.nodeID")"
    +
    +
    +
    +
    ./build/flare --network-id=coston --http-host= \
    +  --bootstrap-ips="$(curl -m 10 -sX POST \
    +    --data '{ "jsonrpc":"2.0", "id":1, "method":"info.getNodeIP" }' \
    +    -H 'content-type:application/json;' https://coston.flare.network/ext/info \
    +    | jq -r ".result.ip")" \
    +  --bootstrap-ids="$(curl -m 10 -sX POST \
    +    --data '{ "jsonrpc":"2.0", "id":1, "method":"info.getNodeID" }' \
    +    -H 'content-type:application/json;' https://coston.flare.network/ext/info \
    +    | jq -r ".result.nodeID")"
    +
    +
    +
    +
    ./build/avalanchego --network-id=costwo --http-host= \
    +  --bootstrap-ips="$(curl -m 10 -sX POST \
    +    --data '{ "jsonrpc":"2.0", "id":1, "method":"info.getNodeIP" }' \
    +    -H 'content-type:application/json;' https://coston2.flare.network/ext/info \
    +    | jq -r ".result.ip")" \
    +  --bootstrap-ids="$(curl -m 10 -sX POST \
    +    --data '{ "jsonrpc":"2.0", "id":1, "method":"info.getNodeID" }' \
    +    -H 'content-type:application/json;' https://coston2.flare.network/ext/info \
    +    | jq -r ".result.nodeID")"
    +
    +
    +
    +
    +

    After a lot of log messages the node should start synchronizing with the network, which might take a long time (currently about 4 hours for Flare, over a week for Songbird, depending on network speed and machine specs).

    +

    You can stop the node at any time by pressing Ctrl-C. +Use the same command line as before to restart the node. +Synchronization will resume where it left if it is interrupted.

    +

    You will know your node is fully booted and accepting transactions when the output of this command:

    +
    curl http://127.0.0.1:9650/ext/health
    +
    +

    Contains the field "healthy":true in the returned JSON object.

    +
    +

    Note

    +

    If the node gets stuck during bootstrap (it takes far longer than the estimates given above), try to add the parameter --bootstrap-retry-enabled=false.

    +
    +

    4. Additional Configuration#

    +

    These are some of the most relevant command line parameters you can use. +You can read about all of them in the Avalanche documentation.

    +
      +
    • +

      --bootstrap-ips, + --bootstrap-ids: + IP address and node ID of the peer used to connect to the rest of the network for bootstrapping.

      +

      You can use Flare's public nodes for this, as shown in the quick start command given above:

      +
      +
      +
      +

      Peer's IP address:

      +
      curl -m 10 -sX POST \
      +--data '{ "jsonrpc":"2.0", "id":1, "method":"info.getNodeIP" }' \
      +-H 'content-type:application/json;' \
      +https://flare.flare.network/ext/info | jq -r ".result.ip"
      +
      +

      Peer's node ID:

      +
      curl -m 10 -sX POST \
      +--data '{ "jsonrpc":"2.0", "id":1, "method":"info.getNodeID" }' \
      +-H 'content-type:application/json;' \
      +https://flare.flare.network/ext/info | jq -r ".result.nodeID"
      +
      +
      +
      +

      Peer's IP address:

      +
      curl -m 10 -sX POST \
      +--data '{ "jsonrpc":"2.0", "id":1, "method":"info.getNodeIP" }' \
      +-H 'content-type:application/json;' \
      +https://songbird.flare.network/ext/info | jq -r ".result.ip"
      +
      +

      Peer's node ID:

      +
      curl -m 10 -sX POST \
      +--data '{ "jsonrpc":"2.0", "id":1, "method":"info.getNodeID" }' \
      +-H 'content-type:application/json;' \
      +https://songbird.flare.network/ext/info | jq -r ".result.nodeID"
      +
      +
      +
      +

      Peer's IP address:

      +
      curl -m 10 -sX POST \
      +--data '{ "jsonrpc":"2.0", "id":1, "method":"info.getNodeIP" }' \
      +-H 'content-type:application/json;' \
      +https://coston.flare.network/ext/info | jq -r ".result.ip"
      +
      +

      Peer's node ID:

      +
      curl -m 10 -sX POST \
      +--data '{ "jsonrpc":"2.0", "id":1, "method":"info.getNodeID" }' \
      +-H 'content-type:application/json;' \
      +https://coston.flare.network/ext/info | jq -r ".result.nodeID"
      +
      +
      +
      +

      Peer's IP address:

      +
      curl -m 10 -sX POST \
      +--data '{ "jsonrpc":"2.0", "id":1, "method":"info.getNodeIP" }' \
      +-H 'content-type:application/json;' \
      +https://coston2.flare.network/ext/info | jq -r ".result.ip"
      +
      +

      Peer's node ID:

      +
      curl -m 10 -sX POST \
      +--data '{ "jsonrpc":"2.0", "id":1, "method":"info.getNodeID" }' \
      +-H 'content-type:application/json;' \
      +https://coston2.flare.network/ext/info | jq -r ".result.nodeID"
      +
      +
      +
      +
      +

      Remember that you need to whitelist your node's IP address or your queries will always be answered with 403 error codes.

      +
    • +
    • +

      --http-host: + Use --http-host= (empty) to allow connections from other machines. + Otherwise, only connections from localhost are accepted.

      +
    • +
    • +

      --http-port: + The port through which the node will listen to API requests. + The default value is 9650.

      +
    • +
    • +

      --staking-port: + The port through which the network peers will connect to this node externally. + Having this port accessible from the internet is required for correct node operation. + The default value is 9651.

      +
    • +
    • +

      --db-dir: + Directory where the database is stored. + Make sure to use a disk with enough space as recommended in the Hardware prerequisites section. + It defaults to ~/.avalanchego/db on Flare and Coston 2, and to ~/.flare/db on Songbird and Coston.

      +

      You can use this option to store the database on an external drive, for example.

      +
    • +
    • +

      --chain-config-dir: + Optional JSON configuration file, in case you want to use lots of non-default values.

      +
      +Sample configuration file for observer nodes +

      These are the most common configuration options. +Put them in a file in the {chain-config-dir}/C/config.json folder.

      +
      {
      +    "snowman-api-enabled": false,
      +    "coreth-admin-api-enabled": false,
      +    "eth-apis": [
      +        "public-eth",
      +        "public-eth-filter",
      +        "net",
      +        "web3",
      +        "internal-public-eth",
      +        "internal-public-blockchain",
      +        "internal-public-transaction-pool"
      +    ],
      +    "rpc-gas-cap": 50000000,
      +    "rpc-tx-fee-cap": 100,
      +    "pruning-enabled": true,
      +    "local-txs-enabled": false,
      +    "api-max-duration": 0,
      +    "api-max-blocks-per-request": 0,
      +    "allow-unfinalized-queries": false,
      +    "allow-unprotected-txs": false,
      +    "remote-tx-gossip-only-enabled": false,
      +    "log-level": "info"
      +}
      +
      +
      +
    • +
    +

    Archival nodes: An archival node keeps the whole history of the blockchain, instead of pruning old transactions which is the default setting. +Use the pruning-enabled configuration setting to control whether your node performs pruning or not. +Archival nodes have significantly increased disk requirements.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/infra/observation/faq/index.html b/infra/observation/faq/index.html new file mode 100644 index 000000000..449c8f07f --- /dev/null +++ b/infra/observation/faq/index.html @@ -0,0 +1,4013 @@ + + + + + + + + + + + + + + + + + + FAQ - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + + + + +
    +
    + + + + + + + + + + +

    FAQ#

    +

    Do I need to re-whitelist my peering node IP?#

    +

    No, you do not need to re-whitelist the IP address.

    +

    I want to have greater redundancy and would like to whitelist multiple nodes, can I do that?#

    +

    Yes, you can whitelist multiple IPs per single provider.

    +

    Can an unhealthy node cause my transactions to revert?#

    +

    Yes, at times, not enough connected peers can cause your transactions to revert. +Make sure your node state is healthy and that it has enough connected peers.

    +

    How do I check the number of connected peers?#

    +
    curl http://127.0.0.1:9650/ext/health | jq
    +
    +

    And look for the line containing connectedPeers.

    +

    If you want to automate the process you can use:

    +
    curl -s http://127.0.0.1:9650/ext/health | \
    +    jq -r ".checks.network.message.connectedPeers"
    +
    +

    What is the required number of connected peers?#

    +

    If the number of peers falls below 16, chances are your node will not work correctly.

    +

    While the network is being decentralized, any number below 20 is indication of a problem.

    +

    In any case, try restarting the node.

    +

    The node does not sync after a long time and dies abruptly, what should I do?#

    +

    Make sure, that the database location has sufficient disk space (database size might change a lot during bootstrapping).

    +

    I am getting strange errors on submission and revert messages are cryptic#

    +

    This might be a symptom of a node connection error. +Try to restart the node and make sure you have enough disk space.

    + +
    failed to send GetAcceptedFrontier(MtF8bVH241hetCQJgsKEdKyJBs8vhp1BC, 11111111111111111111111111111111LpoYY, NUMBER)
    +
    +

    It looks like your node got disconnected during bootstrapping. +Try restarting the node.

    +

    I have synced the node but it does not become healthy. What can I do?#

    +

    It often happens that a new node gets synced but stays unhealthy for no apparent reason. +A restart usually helps.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/infra/observation/index.html b/infra/observation/index.html new file mode 100644 index 000000000..571493be0 --- /dev/null +++ b/infra/observation/index.html @@ -0,0 +1,3818 @@ + + + + + + + + + + + + + + + + + + Observer Nodes - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    + + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/infra/validation/deploying/index.html b/infra/validation/deploying/index.html new file mode 100644 index 000000000..c53b3bc22 --- /dev/null +++ b/infra/validation/deploying/index.html @@ -0,0 +1,4168 @@ + + + + + + + + + + + + + + + + + + Deploying a Validator Node - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Deploying a Validator Node#

    +

    Introduction#

    +

    As explained in the Validator Nodes page, these servers fulfill a critical role in securing the network:

    +
      +
    • They check that all received transactions are valid.
    • +
    • They run a consensus algorithm so that all validators in the network agree on the transactions to add to the blockchain.
    • +
    • Finally, they add the agreed-upon transactions to their copy of the ledger.
    • +
    +

    Additionally, all blockchains must employ measures against Sybil attacks and the Flare network is planning two such measures:

    +
      +
    • Validators will need to stake native tokens, just like in regular Proof of Stake.
    • +
    • Validators will also need to be FTSO Data Providers, and their performance in this role will have an impact on their validation rewards, leading to a meritocratic system.
    • +
    +

    However, given the importance of the validator role and the novelty of the meritocratic approach, these measures are being implemented in phases:

    +
    +

    Implementation phases

    +
      +
    • +

      Phase 0:

      +

      Only validators with preregistered keys can be deployed.

      +

      Some users will receive preregistered validator keys, this is, the keys required to launch a node which has already been registered as a validator. +This is the only way to deploy a validator node during this phase.

      +
    • +
    • +

      Phase 1:

      +

      Candidate FTSO validators.

      +

      FTSO data providers that wish to become validators need to undergo a KYC process (Contact Tom T. over Discord (Tom T#7603), Telegram (@TampaBay7) or email) and operate an Observer node.

      +

      Random security scans will be performed on the node, and if all of them are successful (see Mandatory security measures below) validator rewards will be accrued. +Validator rewards are split evenly among all candidate validators that passed the security scans.

      +
    • +
    +

    More phases will be added as the process is refined.

    +

    Information affecting only specific phases is indicated in this guide with colored boxes like this one.

    +
    +

    This guide explains how to deploy your own validator node so you can participate in the consensus and collect the rewards that the network provides to those who help secure it.

    +
    +

    The following instructions apply to the Flare network only.

    +
    +

    Prerequisites#

    +

    Validators run the same software as regular observer nodes, therefore, this guide assumes you have already read the Deploying an Observer Node guide.

    +

    The requirements to deploy a validator node are the same as for observer nodes, except on the CPU and RAM front which are heavier due to the extra work required:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    HardwareSoftware
    CPU cores16Operating SystemUbuntu (18.04 or 20.04) or macOS (>= 10.15 Catalina)
    RAM64 GBDependenciesGo (>= 1.18.5)
    Disk space1 TB SSDgcc
    Disk growth2.5 TB/yearg++
    jq
    npm (>= 8.11)
    +

    Guide#

    +

    1. Configure the Node#

    +

    A validator node is deployed like an observer node, but there are some additional considerations.

    +

    Firstly, validators do more work than plain observer nodes so please consider the recommended hardware specifications above.

    +

    And secondly, validator security impacts the whole network. +Please consider the following items carefully:

    +

    Mandatory security measures#

    +
      +
    • +

      Ensure port 9650 is not externally reachable. + This is the port used to answer API requests and validators should not be doing that.

      +
    • +
    • +

      Disallow password authentication over SSH.

      +
    • +
    • +

      Don't run any non-validator services on the same IP (website, mail server, etc).

      +
    • +
    +
    +

    Warning

    +

    A monitoring tool run by Flare periodically checks that the above measures are followed by all validators.

    +

    Failure to comply impacts the validator's rewards.

    +
    +
    +

    Phase 1 exemption

    +

    To ease the deployment of candidate validators during phase 1 port 9650, used to answer API requests, might be left open.

    +

    This allows running the candidate validator on the same machine currently running the observer node used to submit FTSO data.

    +
    +

    Suggested security measures#

    +
      +
    • +

      Disallow any ICMP traffic.

      +
    • +
    • +

      Have the machine firewalled. + Only the ports required for validator operation should be open (i.e. only the staking port, which defaults to 9651).

      +

      If you use a virtual server, use only its web interface for management and close the SSH port.

      +

      If the SSH port must be open, it should ideally be restricted to a private IP (i.e. only accessible through VPN) or only temporarily open to the operator's office/home static IP or a bastion SSH VM that can be turned off between use.

      +
    • +
    • +

      The node should only act as a validator, and not accept RPC API calls.

      +

      You should deploy a separate observer node for tasks requiring RPC API access. +Additionally, this observer node can point to your validator for peering and bootstrapping.

      +
    • +
    • +

      The validator should only enable the minimum set of EVM APIs by adding this line to a configuration file:

      +
      "eth-apis": [
      +    "web3"
      +]
      +
      +
      +Sample configuration file for validator nodes +
      {
      +    "snowman-api-enabled": false,
      +    "coreth-admin-api-enabled": false,
      +    "coreth-admin-api-dir": "",
      +    "eth-apis": [
      +        "web3"
      +    ],
      +    "continuous-profiler-dir": "",
      +    "continuous-profiler-frequency": 900000000000,
      +    "continuous-profiler-max-files": 5,
      +    "rpc-gas-cap": 50000000,
      +    "rpc-tx-fee-cap": 100,
      +    "preimages-enabled": false,
      +    "pruning-enabled": false,
      +    "snapshot-async": true,
      +    "snapshot-verification-enabled": false,
      +    "metrics-enabled": true,
      +    "metrics-expensive-enabled": false,
      +    "local-txs-enabled": false,
      +    "api-max-duration": 30000000000,
      +    "ws-cpu-refill-rate": 0,
      +    "ws-cpu-max-stored": 0,
      +    "api-max-blocks-per-request": 30,
      +    "allow-unfinalized-queries": false,
      +    "allow-unprotected-txs": false,
      +    "keystore-directory": "",
      +    "keystore-external-signer": "",
      +    "keystore-insecure-unlock-allowed": false,
      +    "remote-tx-gossip-only-enabled": false,
      +    "tx-regossip-frequency": 60000000000,
      +    "tx-regossip-max-size": 15,
      +    "log-level": "info",
      +    "offline-pruning-enabled": false,
      +    "offline-pruning-bloom-filter-size": 512,
      +    "offline-pruning-data-directory": ""
      +}
      +
      +
      +
    • +
    +

    2. Run the Node#

    +

    After taking the above considerations into account, you can now start up your node by following the Deploying an Observation Node guide.

    +
    +

    Preregistered validator keys

    +

    Some users have received preregistered validator keys, this is, the keys required to deploy a node which has already been registered as a validator.

    +

    If that is your case, you just need to add these parameters to the launch command line:

    +
    --staking-tls-cert-file=<NODE_CRT_PATH> \
    +--staking-tls-key-file=<NODE_KEY_PATH>
    +
    +
    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/infra/validation/index.html b/infra/validation/index.html new file mode 100644 index 000000000..d6af5e2bd --- /dev/null +++ b/infra/validation/index.html @@ -0,0 +1,3818 @@ + + + + + + + + + + + + + + + + + + Validator Nodes - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    + + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/infra/validation/staking-cli/index.html b/infra/validation/staking-cli/index.html new file mode 100644 index 000000000..72a581a20 --- /dev/null +++ b/infra/validation/staking-cli/index.html @@ -0,0 +1,4616 @@ + + + + + + + + + + + + + + + + + + Staking on a Validator - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    + +
    +
    + + +
    +
    + + + + + + + + + + +

    Staking on a Validator#

    +

    Flare has a command-line interface (CLI) tool called Flare Stake CLI, which allows performing stake operations on validator nodes from a terminal.

    +

    A staking app with a graphical user interface (GUI) is also being developed to simplify the staking process. +Still, a CLI tool has other advantages, like allowing it to be part of automated processes.

    +
    +

    Table of Contents

    + +
    +

    Staking Overview#

    +

    If you already know how staking on validators works on the Flare network, skip this section.

    +
    +

    Note

    +

    Proof of stake is being implemented in phases. +Ensure that you have read the Validators page to learn about them.

    +
    +

    Staking works by locking funds for a period of time to support a specific network validator. +When validator owners stake to their own nodes they self-bond, whereas all other participants are said to delegate their stake to that validator.

    +

    Participants choose how much to stake and for how long their stake will be locked. +The minimum values are:

    + + + + + + + + + + + + + + + + + + + + +
    Self-bondDelegation
    Minimum amount1M $FLR50K $FLR
    Minimum duration60 days14 days
    +

    At the end of every reward epoch, participants are rewarded according to how well their chosen validator performed in that period. +The deployment phases summary shows other rewards that staked funds can still earn while they are locked.

    +

    Given that the Flare network uses two independent underlying chains, there is one extra step that must be considered. +Funds must be transferred from the C-chain, where smart contracts run, to the P-chain, where staking happens. +After the staking period expires and funds are unlocked, they can be transferred back to the C-chain.

    +

    This guide explains how to perform the above operations using the Flare Stake CLI tool.

    +

    Installing the Flare Stake CLI#

    +

    This tool is open source, so it can be installed from its source code. +However, it is more convenient to use the prepackaged npm version.

    +

    The Flare Stake CLI works on Windows, Mac, and Linux.

    +
    +

    Note

    +

    It is not recommended to run this tool using the Windows Subsystem for Linux (WSL), as it might have issues accessing hardware wallets through USB ports. +On Windows, use the standard Windows command prompt or terminal instead.

    +
    +

    Prerequisites#

    +

    Install the npm package manager. +This guide has been tested with Node.js v18.16.0 and npm v9.5.1.

    +

    Installation#

    +

    After npm is available, type this command into a terminal to make the tool available from any folder:

    +
    npm install @flarenetwork/flare-stake-tool -g
    +
    +

    Check that the tool has been correctly installed by running:

    +
    flare-stake-tool
    +
    +

    The tool's banner is displayed:

    +
      _____ _                  ____  _        _           ____ _     ___
    + |  ___| | __ _ _ __ ___  / ___|| |_ __ _| | _____   / ___| |   |_ _|
    + | |_  | |/ _` | '__/ _ \ \___ \| __/ _` | |/ / _ \ | |   | |    | |
    + |  _| | | (_| | | |  __/  ___) | || (_| |   <  __/ | |___| |___ | |
    + |_|   |_|\__,_|_|  \___| |____/ \__\__,_|_|\_\___|  \____|_____|___|
    +
    +Version: 3.0.2
    +
    +

    Make sure at least version 3.0.0 has been installed.

    +

    Configuration#

    +

    You can specify the account from which staking will take place in different ways.

    +

    Choose one of the following two options.

    +

    Note that using a Ledger hardware wallet is the only recommended way.

    +
    +Ledger Configuration +

    Your device must be configured before it can be used:

    +
      +
    1. +

      Install the Avalanche application:

      +
        +
      1. Connect the device to your computer and unlock it using your PIN code.
      2. +
      3. Open the Ledger Live application. + Go to the My Ledger tab and make sure the device is using the latest firmware.
      4. +
      5. +

        In the App catalog tab, search for "Avalanche" and click on the Install button.

        +

        Note that this app requires all available space on a Ledger Nano S device (138 KB). +You might need to remove other apps first to free up space.

        +
      6. +
      +
    2. +
    3. +

      Select your desired account:

      +
        +
      1. Exit the Ledger Live application and make sure the device is not connected to any other application like MetaMask.
      2. +
      3. Open the Avalanche app on the Ledger. The screen should show "Avalanche Ready".
      4. +
      5. +

        From a terminal, enter:

        +
        flare-stake-tool interactive
        +
        +

        This command starts the staking tool in interactive mode. +In this mode the tool asks questions until it has enough information to execute a command.

        +
      6. +
      7. +

        Then, after the welcome banner:

        +
        ? How do you want to connect your wallet? (Use arrow keys)
        +> Ledger
        +  Public Key
        +  Private Key (not recommended)
        +
        +

        Select Ledger with the cursor keys and press Enter.

        +
      8. +
      9. +

        The next question is:

        +
        ? Which network do you want to connect to? (Use arrow keys)
        +> Flare (Mainnet)
        +  Coston2 (Testnet)
        +  LocalHost (for development only)
        +
        +

        Select Flare (Mainnet) and press Enter.

        +

        This message shows for a few seconds:

        +
        Fetching Addresses...
        +
        +
      10. +
      11. +

        Eventually a list of addresses is shown. + These are the addresses that can be used from this device.

        +

        Choose the one you want to stake from and press Enter.

        +

        Keep in mind that this address needs to have a positive $FLR balance to pay for transaction fees and be able to stake. +You can transfer funds to it later on.

        +
      12. +
      13. +

        Finally the main menu appears:

        +
        ? What do you want to do? (Use arrow keys)
        +  View chain addresses
        +> Check on-chain balance
        +  Get network info
        +  Get validator info
        +  Move assets from C-chain to P-chain
        +  Move assets from P-chain to C-chain
        +  Add a validator node
        +
        +

        As an example, choose Check on-chain balance and press Enter.

        +

        The balance of your selected account is shown for both the C-chain and the P-chain and the tool exits.

        +
      14. +
      +

      At this point, a ctx.json file has been created in the current folder containing the selected account. +When you run the tool from the same folder again, you will be given the option to use the same account. +Using the same account saves you the inconvenience of repeating the above steps every time.

      +
    4. +
    +
    +
    +Private Key Configuration +

    If you have a Ledger device and you have already configured it, skip this step.

    +

    If you do not have access to a Ledger device, you can still provide your account's private key in a plain text file, but this method is significantly less secure.

    +
      +
    1. Create a text file in a secure folder, i.e., one that is visible only to you. + Give it any name you want.
    2. +
    3. +

      Inside, add one of the following two lines, depending on the format of your private key:

      +
      PRIVATE_KEY_CB58=""
      +PRIVATE_KEY_HEX=""
      +
      +

      If your key is in CB58 format, use the CB58 line. +If your key is 64 hexadecimal characters, use the HEX line. +Put the key inside the quotes.

      +
    4. +
    5. +

      Enter this command on a terminal to check that the key works correctly:

      +
      flare-stake-tool interactive
      +
      +

      This command starts the staking tool in interactive mode. +In this mode the tool asks questions until it has enough information to execute a command.

      +
    6. +
    7. +

      After the welcome banner you see:

      +
      ? How do you want to connect your wallet? (Use arrow keys)
      +  Ledger
      +  Public Key
      +> Private Key (not recommended)
      +
      +

      Select Private Key with the cursor keys and press Enter.

      +
    8. +
    9. +

      The next question is:

      +
      Warning: You are connecting using your private key which is not recommended
      +? Enter Path to Private Key file (E.g. /home/wallet/pvtKeyFile):
      +
      +

      Enter the name and path to the file you and created in step 1 and press Enter.

      +
    10. +
    11. +

      Then:

      +
      ? Which network do you want to connect to? (Use arrow keys)
      +> Flare (Mainnet)
      +  Coston2 (Testnet)
      +  LocalHost (for development only)
      +
      +

      Select Flare (Mainnet) and press Enter.

      +
    12. +
    13. +

      Finally the main menu appears:

      +
      ? What do you want to do? (Use arrow keys)
      +  View chain addresses
      +> Check on-chain balance
      +  Get network info
      +  Get validator info
      +  Move assets from C-chain to P-chain
      +  Move assets from P-chain to C-chain
      +  Add a validator node
      +
      +

      As an example, choose Check on-chain balance, and press Enter.

      +

      The balance of your selected account is shown for both the C-chain and the P-chain and the tool exits.

      +
    14. +
    +

    You can follow the rest of this guide by selecting the Private Key option when prompted.

    +
    +

    Staking Guide#

    +

    To stake on a validator node, you need to:

    +
      +
    1. Check your current P-chain balance.
    2. +
    3. Move funds from the C-chain to the P-chain.
    4. +
    5. Stake them on a validator.
    6. +
    7. Optionally, check that the request has been recorded.
    8. +
    9. Optionally, move the staked funds back to the C-chain once they become unlocked.
    10. +
    +
    +

    Before you start

    +

    During the process you will need three pieces of information. +Take note of them before you start so you can follow the rest of the steps uninterrupted.

    +
      +
    • +

      The node ID of the validator you want to stake to.

      +

      If you created the validator, its nodeID was shown to you during the deployment process.

      +

      If you want to stake to somebody else's validator, you can:

      +
        +
      • See the list of current validators on flaremetrics.io. + Remember to add NodeID- before the ID shown on the page.
      • +
      • Use flare-stake-tool info validators to get a JSON list of all validators.
      • +
      +
    • +
    • +

      The desired staking start time and end time.

      +

      When staking to an existing validator, both these times must be inside the period when the validator is active, +which you can find on flaremetrics.io or again using flare-stake-tool info validators.

      +

      You need to provide these times as a UNIX timestamp, +so you might need to use an online conversion tool like Epoch Converter or the Linux date command.

      +

      As an example, the 1693185095 timestamp corresponds to Monday, August 28, 2023 1:11:35 AM.

      +
    • +
    +
    +

    1. Check your Balances#

    +

    Check your balance by executing flare-stake-tool interactive and selecting the Check on-chain balance option:

    +
    ? How do you want to connect your wallet? Ledger
    +You already have an existing Ctx file with the following parameters -
    +Public Key: ●●●●●●●●●●●●●●●●
    +Network: flare
    +Eth Address: 0x●●●●●●●●
    +? Do you wish to continue with this? yes
    +? What do you want to do? Check on-chain balance
    +Using network: flare
    +Balances on the network "flare"
    +C-chain 0x●●●●●●●●: 100000.0 FLR
    +P-chain P-flare●●●●●●●●: 50000.0 FLR
    +
    +

    Your currently available funds on the C-chain and P-chain are shown in the last lines.

    +

    Funds currently staked are locked and are not reflected in the P-chain balance. +They will become automatically available when the staking period expires.

    +

    2. Move Funds to P-Chain#

    +

    If your funds are already on the P-Chain, skip this step.

    +

    Move the funds by executing flare-stake-tool interactive again and selecting the Move assets from C-chain to P-chain option. +You are asked the amount of $FLR you want to transfer:

    +
    ? What do you want to do? Move assets from C-chain to P-chain
    +? Enter amount (in FLR): 50000
    +
    +
    +

    Transaction Fees

    +

    When transferring from the C-chain to the P-chain, transaction fees are wholly paid from the C-chain. +Make sure you leave enough funds on the C-chain after the transfer, or it will fail.

    +
    +

    Transfers between chains are made of two operations: an export from the C-chain followed by an import to the P-chain. +Therefore, you are asked to confirm TWO transactions on your hardware wallet.

    +
    Please approve export transaction
    +Using network: flare
    +Fetching account from ledger...
    +Creating export transaction...
    +Using fee of 0.00028075 FLR
    +Please review and sign the transaction on your ledger device...
    +Sending transaction to the node...
    +Transaction with id ●●●●●●●● sent to the node
    +Please approve import transaction
    +Using network: flare
    +Fetching account from ledger...
    +Creating export transaction...
    +Please review and sign the transaction on your ledger device...
    +Sending transaction to the node...
    +Transaction with id ●●●●●●●● sent to the node
    +Finished execution
    +
    +

    You can check your balances again to verify that the transfer was successful.

    +

    If you encounter any problem, see the Troubleshooting section.

    +

    3. Stake#

    +

    After you have funds on the P-chain, execute flare-stake-tool interactive again and select the appropriate option: +If you are going to delegate to your own node (self-bonding), select Add a validator node. +Otherwise, if you are going to stake to another node (delegation), select Delegate to a validator node. +Press the down key a few times for this last option to show.

    +
    +

    First-time Address Registration

    +

    The first time you use the Add a validator node or Delegate to a validator node options you are asked to sign an additional transaction.

    +

    This step is required so that staking rewards accrued on the P-chain can be claimed on the C-chain and participate in the wider ecosystem.

    +

    This procedure only needs to be done once per P-chain address and it progresses like this:

    +
    Checking Address Registration...
    +No address found for key 0x●●●●●●●●
    +Note: You need to register your wallet address before you can delegate your funds
    +Please complete this registration transaction to proceed
    +Submitting txn to the chain
    +
    +
    +Cryptographical Background +

    Both your P-chain and C-chain addresses are derived from the same public key, but the process is not symmetrical: +public keys cannot be derived from addresses.

    +

    Therefore, smart contracts have no way of knowing the P-chain address that corresponds to a given C-chain address, unless they are both provided by their owner.

    +

    This step performs exactly this operation, allowing a C-chain address to claim rewards that were accrued by its P-chain counterpart.

    +
    +
    +Manual Address Registration +

    Should automatic registration through the Flare Stake CLI tool fail, you can still register your addresses manually using the Block Explorer:

    +
      +
    1. +

      Retrieve the public key that generated the accounts you want to use. + From a terminal, run flare-stake-tool info addresses and copy the long hexadecimal string starting with 0x in the last line.

      +
      Using network: flare
      +Addresses on the network "flare"
      +P-chain address: P-flare●●●●●●●●
      +C-chain address hex: 0x●●●●●●●●
      +secp256k1 public key: 0x●●●●●●●●●●●●●●●●
      +
      +
    2. +
    3. +

      You need to interact with the AddressBinder smart contract, so you must retrieve its address from the FlareContractRegistry as explained in the retrieving Contract Addresses page.

      +
    4. +
    5. Enter the address of the AddressBinder contract in the Block Explorer, and go to the Write Contract tab.
    6. +
    7. Click on Connect Wallet. + You do not need to use the same account as the one you are binding.
    8. +
    9. Locate the registerPublicKey method and paste the public key from step 1 into the _publicKey field.
    10. +
    11. Click on Write and confirm the transaction from your wallet.
    12. +
    +

    If the transaction is successful, your account's P and C-chain addresses are now bound.

    +
    +
    +

    You then need to provide the following information:

    + +

    If you selected Add a validator node, you have one more question to answer:

    +
      +
    • +

      Delegation fee: This is the percentage of all rewards that the node owner keeps. + The rest is split proportionally between the self-bond and all delegators that contributed stake.

      +

      10 means 10%, so the maximum value is 100.

      +
    • +
    +
    ? What do you want to do? Add a validator node
    +? Enter amount (in FLR): 50000
    +? Enter Node NodeId (E.g. NodeID-FQKTLuZHEsjCxPeFTFgsojsucmdyNDsz1): NodeID-●●●●●●●●
    +? Enter start time(E.g. 1693185095): ●●●●●●●●
    +? Enter end time(E.g. 1693185095): ●●●●●●●●
    +? Enter delegation fee(E.g. 10): 10
    +
    +

    You are then asked to confirm the staking transaction on your hardware wallet.

    +
    Using network: flare
    +Fetching account from ledger...
    +Creating export transaction...
    +Please review and sign the transaction on your ledger device...
    +Sending transaction to the node...
    +Transaction with id ●●●●●●●● sent to the node
    +Finished execution
    +
    +

    Your stake is now locked and will start accruing rewards after the configured start time arrives. +When the end time arrives, the funds will be automatically unlocked.

    +

    If you encounter any problem, see the Troubleshooting section.

    +

    4. Check Stake#

    +

    You can double-check that the operation has been properly registered by looking at the current list of validators:

    +
    flare-stake-tool info validators > validators.txt
    +
    +

    This creates a file called validators.txt. +Open it and search for the line containing the P-chain address of your account. +If you don't know it, use flare-stake-tool info addresses.

    +

    If your account has stake on any node, you will find a section similar to:

    +
    {
    +  "txID": "28Yf5yQ3xt9yaMvfZ1RP5jkCkT4y2pfD86UheZUHFVng2tFcWd",
    +  "startTime": "1688569201",
    +  "endTime": "1696345201",
    +  "stakeAmount": "16750000000000000",
    +  "nodeID": "NodeID-C6i8mruq11VdxGQ7tiUBgrRqoLBot86df",
    +  "rewardOwner": {
    +    "locktime": "0",
    +    "threshold": "1",
    +    "addresses": [
    +      "P-flare19c8zfml39x6efnw5j90nl85dmwdqhluwhrxz9g"
    +    ]
    +  },
    +},
    +
    +

    Check that the stakeAmount (in wei), nodeID, startTime, and endTime match the values you configured.

    +

    If you have multiple active stakes, your address can show multiple times.

    +

    5. Move funds back to C-Chain#

    +

    Finally, you also have the option to move your P-chain funds back to the C-chain where they can participate in the wider ecosystem.

    +

    You can only transfer P-chain funds that are not currently locked in any stake.

    +

    Execute flare-stake-tool interactive and select the Move assets from P-chain to C-chain option. +You are asked the amount of $FLR you want to transfer:

    +
    ? What do you want to do? Move assets from P-chain to C-chain
    +? Enter amount (in FLR): 50000
    +
    +
    +

    Transaction Fees

    +

    When transferring from the P to the C-chain, transaction fees are paid from BOTH chains. +Make sure you leave enough funds on both chains after the transfer, or it will fail.

    +
    +

    Again, the transfer between the two chains require you to confirm TWO transactions on your hardware wallet.

    +
    Please approve export transaction
    +Using network: flare
    +Fetching account from ledger...
    +Creating export transaction...
    +Please review and sign the transaction on your ledger device...
    +Sending transaction to the node...
    +Transaction with id ●●●●●●●● sent to the node
    +Please approve import transaction
    +Using network: flare
    +Fetching account from ledger...
    +Creating export transaction...
    +Using fee of 0.00028075 FLR
    +Please review and sign the transaction on your ledger device...
    +Sending transaction to the node...
    +Transaction with id ●●●●●●●● sent to the node
    +Finished execution
    +
    +

    You can check your balances again to verify that the transfer was successful.

    +

    If you encounter any problem, see the Troubleshooting section.

    +

    Claiming Guide#

    +

    At the end of every reward epoch, participants are rewarded according to how well their chosen validator performed in that period.

    +

    Rewards are accumulated in a dedicated smart contract and can be claimed from the Flare Stake CLI tool:

    +

    Execute flare-stake-tool interactive and select the Claim Rewards option. +Press the down key a few times for this option to show.

    +

    You are shown the amount of pending rewards (in wei) and are asked how much you want to claim (in FLR):

    +
    ? What do you want to do? Claim Rewards
    +Checking your Rewards status...
    +You have unclaimed rewards worth 1000000000000000000
    +? Enter amount to claim (in FLR): 1
    +
    +

    Next, select Receive with another wallet and enter the C-chain address where you want the rewards to be sent. +This can be the same address from where you are staking.

    +
    ? Where do you want to receive your rewards? Receive with another wallet
    +? Please enter the C-address where you want to receive your rewards: 0x●●●●●●●●
    +
    +

    You are then asked to confirm the staking transaction on your hardware wallet.

    +
    Please sign the transaction on your ledger
    +Submitting txn to the chain
    +Rewards successfully claimed
    +Finished execution
    +
    +
    +Manual Reward Claiming +

    Rewards can also be claimed directly from the ValidatorRewardManager contract that accumulates them:

    +
      +
    1. You need to interact with the ValidatorRewardManager smart contract, so you must retrieve its address from the FlareContractRegistry as explained in the retrieving Contract Addresses page.
    2. +
    3. Enter the address of the ValidatorRewardManager contract in the Block Explorer, and go to the Write Contract tab.
    4. +
    5. Click on Connect Wallet. + You need to connect the account for which you are claiming.
    6. +
    7. +

      Locate the claim method and enter the following information:

      +
        +
      • _rewardOwner: C-chain address that accrued the rewards.
      • +
      • _recipient: Address where the rewards must be sent.
      • +
      • _rewardAmount: Amount to claim. + Find the pending amount using the getStateOfRewards method in the Read Contract tab.
      • +
      • _wrap: Whether the rewards should be also wrapped, as a convenience.
      • +
      +
    8. +
    9. +

      Click on Write and confirm the transaction from your wallet.

      +
    10. +
    +

    If the transaction is successful, the reward is transferred to the specified recipient.

    +
    +

    Troubleshooting#

    +
    +Cannot connect to Ledger device, No Device, Cannot retrieve addresses, or similar +

    Make sure:

    +
      +
    • +

      The device is connected, the Avalanche app is opened, and it shows the "Avalanche Ready" message.

      +
    • +
    • +

      No other application like Ledger Live or MetaMask is connected to the device.

      +
    • +
    • +

      The device is not in stand-by mode.

      +
    • +
    • +

      You are not running on Windows from a Linux terminal (WSL). + Use a native Windows console instead.

      +
    • +
    +
    +
    +Insufficient funds +

    Make sure enough funds will remain after a transaction to pay for the transaction fees.

    +

    If too much time has elapsed between the transaction's creation and its confirmation on the Ledger, the calculated fee might be incorrect. +Try the operation again.

    +

    The network might be congested and the calculated fees might not be high enough. +Try the operation again after a while.

    +
    +
    +Import transaction failed and the funds have vanished +

    Transfer operations require an export and an import transaction. +If the export succeeds, but then the import fails, it looks like the funds have disappeared from both chains, but they are still retrievable.

    +

    Repeat the failed import operation manually:

    +
      +
    • +

      If you are moving funds from the C-chain to the P-chain:

      +
      flare-stake-tool transaction importCP --ledger --blind
      +
      +
    • +
    • +

      If you are moving funds from the P-chain to the C-chain:

      +
      flare-stake-tool transaction importPC --ledger --blind
      +
      +
    • +
    +
    +
    +Unsupported digital routines +

    If you get the following error message:

    +
    E: Error: error:0308010C:digital envelope routines::unsupported
    +
    +

    Make sure you are using the correct Node.js version, as advised in the Prerequisites section.

    +

    You can find out the version of Node.js you are running with the following command:

    +
    node --version
    +
    +
    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/logo.svg b/logo.svg new file mode 100644 index 000000000..e5c6fb447 --- /dev/null +++ b/logo.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/networks/coston-testnet/index.html b/networks/coston-testnet/index.html new file mode 100644 index 000000000..11c81c9fb --- /dev/null +++ b/networks/coston-testnet/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/networks/songbird/index.html b/networks/songbird/index.html new file mode 100644 index 000000000..11c81c9fb --- /dev/null +++ b/networks/songbird/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/search/search_index.json b/search/search_index.json new file mode 100644 index 000000000..3d890a504 --- /dev/null +++ b/search/search_index.json @@ -0,0 +1 @@ +{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"Welcome to the Flare Network Technical Documentation # New here? Start with What Is Flare? Flare Fundamentals Descriptions of Flare's key concepts, technology and tools. User Guides Step-by-step guides for tools like the Explorer or the different wallets. Infrastructure Guides Step-by-step guides to deploy your own Flare network components. Exchange Guides Advice for exchanges willing to support the Flare blockchain. Developer Docs Programming tutorials to help you build your app using Flare's tech. API Reference Guides API documentation and access RPC nodes. These pages are a Work In Progress . Use the contact buttons at the bottom of the page if there is anything you cannot find here! /*Special centered title for the Home page*/ h1 { text-align: center; } /*Remove the \"Last updated\" text at the bottom*/ .md-source-file { display: none; }","title":"Welcome to the Flare Network Technical Documentation"},{"location":"#welcome-to-the-flare-network-technical-documentation","text":"New here? Start with What Is Flare? Flare Fundamentals Descriptions of Flare's key concepts, technology and tools. User Guides Step-by-step guides for tools like the Explorer or the different wallets. Infrastructure Guides Step-by-step guides to deploy your own Flare network components. Exchange Guides Advice for exchanges willing to support the Flare blockchain. Developer Docs Programming tutorials to help you build your app using Flare's tech. API Reference Guides API documentation and access RPC nodes. These pages are a Work In Progress . Use the contact buttons at the bottom of the page if there is anything you cannot find here! /*Special centered title for the Home page*/ h1 { text-align: center; } /*Remove the \"Last updated\" text at the bottom*/ .md-source-file { display: none; }","title":"Welcome to the Flare Network Technical Documentation"},{"location":"apis/","text":"APIs # Select one of the topics below: Flare API Documentation # Smart Contracts API (Work in progress) External Documentation # web3.js API ethers.js API Access Nodes Public RPC nodes for Flare, Songbird and Coston. Public RPC nodes for connected chains Flare API Portal (private nodes)","title":"APIs"},{"location":"apis/#apis","text":"Select one of the topics below:","title":"APIs"},{"location":"apis/#flare-api-documentation","text":"Smart Contracts API (Work in progress)","title":"Flare API Documentation"},{"location":"apis/#external-documentation","text":"web3.js API ethers.js API Access Nodes Public RPC nodes for Flare, Songbird and Coston. Public RPC nodes for connected chains Flare API Portal (private nodes)","title":"External Documentation"},{"location":"apis/smart-contracts/","text":"Smart Contracts API # List of Flare smart contracts. Contracts # Name Description AddressUpdatable Abstract base class for contracts that depend on other contracts whose addresses can change. AddressUpdater Keeps track of the current address for all unique and special platform contracts. CheckPointable Check-Pointable ERC20 Behavior. ClaimSetupManager Manages automation of operations related to reward claiming. CleanupBlockNumberManager Token history cleanup manager. CloneFactory Simple clone contract factory. Delegatable Delegatable ERC20 behavior. FlareContractRegistry The Flare contract registry. FlareDaemon Flare Daemon contract. Ftso Flare Time Series Oracle contract. FtsoManager FTSO Manager contract. FtsoRegistry Handles registration of assets to the FTSO system . FtsoRewardManager Handles reward distribution and claiming related to the FTSO system. GovernanceSettings A special contract that holds the Flare governance address and its timelock. GovernanceVotePower Contract managing governance vote power and its delegation. Governed Defines behaviors for governed contracts that must have a governor set at construction-time. GovernedAndFlareDaemonized Base class for contracts that are governed and triggered from the FlareDaemon . GovernedAtGenesis Defines behaviors for governed contracts that have their governor set at genesis. GovernedBase Abstract base class that defines behaviors for governed contracts. Inflation Recognizes, authorizes, mints, and funds native tokens to Flare services that are rewardable through inflation. PriceSubmitter Receives prices from FTSO data providers . RevertErrorTracking Revert error tracking contract. VoterWhitelister Manager of the FTSO whitelist . VPContract Helper contract handling all the vote power and delegation functionality for an associated VPToken . VPToken Vote power token. WNat Wrapped native token. Interfaces # Name Description IClaimSetupManager Public interface for the ClaimSetupManager contract. IFlareContractRegistry Interface for the FlareContractRegistry . IFlareDaemonize Interface for contracts that receive triggers from the FlareDaemon contract. IFtso Interface for each of the FTSO contracts that handles an asset. IFtsoGenesis Portion of the IFtso interface that is available to contracts deployed at genesis. IFtsoManager Interface for the FtsoManager contract. IFtsoManagerGenesis Portion of the IFtsoManager interface that is available to contracts deployed at genesis. IFtsoRegistry Interface for the FtsoRegistry contract. IFtsoRegistryGenesis Portion of the IFtsoRegistry interface that is available to contracts deployed at genesis. IFtsoRewardManager Interface for the FtsoRewardManager contract. IGovernanceSettings Interface for the GovernanceSettings that hold the Flare governance address and its timelock. IGovernanceVotePower Interface for contracts delegating their governance vote power. IInflationGenesis Portion of the Inflation contract that is available to contracts deployed at genesis. IPriceSubmitter Interface for the PriceSubmitter contract. IVoterWhitelister Interface for managers of the FTSO whitelist . IVPContractEvents Events interface for vote-power related operations. IVPToken Vote power token interface. IWNat Wrapped native token interface. Internal Interfaces # For platform development, not application. Name Description IIAddressUpdatable Internal interface for contracts that depend on other contracts whose addresses can change. IIAddressUpdater Internal interface for AddressUpdater . IIClaimSetupManager Internal interface for the ClaimSetupManager contract. IICleanable Internal interface for entities that can have their block history cleaned. IIFtso Internal interface for each of the FTSO contracts that handles an asset. IIFtsoManager Internal interface for the FtsoManager contract. IIFtsoRegistry Internal interface for the FtsoRegistry contract. IIFtsoRewardManager Internal interface for the FtsoRewardManager . IIGovernanceVotePower Internal interface for contracts delegating their governance vote power. IIInflationReceiver Internal interface for contracts that can receive inflation. IIPriceSubmitter Internal interface for the PriceSubmitter contract. IITokenPool Internal interface for token pools. IIVoterWhitelister Internal interface for managers of the FTSO whitelist . IIVPContract Internal interface for helper contracts handling functionality for an associated VPToken . IIVPToken Vote power token internal interface. td:first-child {white-space: nowrap;}","title":"Smart Contracts API"},{"location":"apis/smart-contracts/#smart-contracts-api","text":"List of Flare smart contracts.","title":"Smart Contracts API"},{"location":"apis/smart-contracts/#contracts","text":"Name Description AddressUpdatable Abstract base class for contracts that depend on other contracts whose addresses can change. AddressUpdater Keeps track of the current address for all unique and special platform contracts. CheckPointable Check-Pointable ERC20 Behavior. ClaimSetupManager Manages automation of operations related to reward claiming. CleanupBlockNumberManager Token history cleanup manager. CloneFactory Simple clone contract factory. Delegatable Delegatable ERC20 behavior. FlareContractRegistry The Flare contract registry. FlareDaemon Flare Daemon contract. Ftso Flare Time Series Oracle contract. FtsoManager FTSO Manager contract. FtsoRegistry Handles registration of assets to the FTSO system . FtsoRewardManager Handles reward distribution and claiming related to the FTSO system. GovernanceSettings A special contract that holds the Flare governance address and its timelock. GovernanceVotePower Contract managing governance vote power and its delegation. Governed Defines behaviors for governed contracts that must have a governor set at construction-time. GovernedAndFlareDaemonized Base class for contracts that are governed and triggered from the FlareDaemon . GovernedAtGenesis Defines behaviors for governed contracts that have their governor set at genesis. GovernedBase Abstract base class that defines behaviors for governed contracts. Inflation Recognizes, authorizes, mints, and funds native tokens to Flare services that are rewardable through inflation. PriceSubmitter Receives prices from FTSO data providers . RevertErrorTracking Revert error tracking contract. VoterWhitelister Manager of the FTSO whitelist . VPContract Helper contract handling all the vote power and delegation functionality for an associated VPToken . VPToken Vote power token. WNat Wrapped native token.","title":"Contracts"},{"location":"apis/smart-contracts/#interfaces","text":"Name Description IClaimSetupManager Public interface for the ClaimSetupManager contract. IFlareContractRegistry Interface for the FlareContractRegistry . IFlareDaemonize Interface for contracts that receive triggers from the FlareDaemon contract. IFtso Interface for each of the FTSO contracts that handles an asset. IFtsoGenesis Portion of the IFtso interface that is available to contracts deployed at genesis. IFtsoManager Interface for the FtsoManager contract. IFtsoManagerGenesis Portion of the IFtsoManager interface that is available to contracts deployed at genesis. IFtsoRegistry Interface for the FtsoRegistry contract. IFtsoRegistryGenesis Portion of the IFtsoRegistry interface that is available to contracts deployed at genesis. IFtsoRewardManager Interface for the FtsoRewardManager contract. IGovernanceSettings Interface for the GovernanceSettings that hold the Flare governance address and its timelock. IGovernanceVotePower Interface for contracts delegating their governance vote power. IInflationGenesis Portion of the Inflation contract that is available to contracts deployed at genesis. IPriceSubmitter Interface for the PriceSubmitter contract. IVoterWhitelister Interface for managers of the FTSO whitelist . IVPContractEvents Events interface for vote-power related operations. IVPToken Vote power token interface. IWNat Wrapped native token interface.","title":"Interfaces"},{"location":"apis/smart-contracts/#internal-interfaces","text":"For platform development, not application. Name Description IIAddressUpdatable Internal interface for contracts that depend on other contracts whose addresses can change. IIAddressUpdater Internal interface for AddressUpdater . IIClaimSetupManager Internal interface for the ClaimSetupManager contract. IICleanable Internal interface for entities that can have their block history cleaned. IIFtso Internal interface for each of the FTSO contracts that handles an asset. IIFtsoManager Internal interface for the FtsoManager contract. IIFtsoRegistry Internal interface for the FtsoRegistry contract. IIFtsoRewardManager Internal interface for the FtsoRewardManager . IIGovernanceVotePower Internal interface for contracts delegating their governance vote power. IIInflationReceiver Internal interface for contracts that can receive inflation. IIPriceSubmitter Internal interface for the PriceSubmitter contract. IITokenPool Internal interface for token pools. IIVoterWhitelister Internal interface for managers of the FTSO whitelist . IIVPContract Internal interface for helper contracts handling functionality for an associated VPToken . IIVPToken Vote power token internal interface. td:first-child {white-space: nowrap;}","title":"Internal Interfaces"},{"location":"apis/smart-contracts/AddressUpdatable/","text":"AddressUpdatable # Source | Inherits from IIAddressUpdatable Abstract base class for contracts that depend on other contracts whose addresses can change. The AddressUpdater contract keeps a list of addresses for all unique and special platform contracts. By inheriting from AddressUpdatable a contract will receive updates if any of the platform contract addresses change. A contract's address changes when it is redeployed, so AddressUpdatable offers a way to keep up to date with the latest address for all dependencies. Functions # getAddressUpdater # Defined in AddressUpdatable ( Docs , Source ). function getAddressUpdater ( ) public view returns ( address _addressUpdater ); Returns the configured address updater. Returns Type Description _addressUpdater address The AddresUpdater contract that can update our contract address list, as a response to a governance call. updateContractAddresses # Defined in AddressUpdatable ( Docs , Source ). function updateContractAddresses ( bytes32 [] _contractNameHashes , address [] _contractAddresses ) external ; External method called from AddressUpdater only. Modifiers # onlyAddressUpdater # Defined in AddressUpdatable ( Docs , Source ). modifier onlyAddressUpdater () Only the AdressUpdater contract can call this method. Its address is set at construction time but it can also update itself. Variables #","title":"AddressUpdatable"},{"location":"apis/smart-contracts/AddressUpdatable/#ct_addressupdatable","text":"Source | Inherits from IIAddressUpdatable Abstract base class for contracts that depend on other contracts whose addresses can change. The AddressUpdater contract keeps a list of addresses for all unique and special platform contracts. By inheriting from AddressUpdatable a contract will receive updates if any of the platform contract addresses change. A contract's address changes when it is redeployed, so AddressUpdatable offers a way to keep up to date with the latest address for all dependencies.","title":"AddressUpdatable"},{"location":"apis/smart-contracts/AddressUpdatable/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/AddressUpdatable/#fn_getaddressupdater_5267a15d","text":"Defined in AddressUpdatable ( Docs , Source ). function getAddressUpdater ( ) public view returns ( address _addressUpdater ); Returns the configured address updater. Returns Type Description _addressUpdater address The AddresUpdater contract that can update our contract address list, as a response to a governance call.","title":"getAddressUpdater"},{"location":"apis/smart-contracts/AddressUpdatable/#fn_updatecontractaddresses_b00c0b76","text":"Defined in AddressUpdatable ( Docs , Source ). function updateContractAddresses ( bytes32 [] _contractNameHashes , address [] _contractAddresses ) external ; External method called from AddressUpdater only.","title":"updateContractAddresses"},{"location":"apis/smart-contracts/AddressUpdatable/#modifiers","text":"","title":"Modifiers"},{"location":"apis/smart-contracts/AddressUpdatable/#md_onlyaddressupdater","text":"Defined in AddressUpdatable ( Docs , Source ). modifier onlyAddressUpdater () Only the AdressUpdater contract can call this method. Its address is set at construction time but it can also update itself.","title":"onlyAddressUpdater"},{"location":"apis/smart-contracts/AddressUpdatable/#variables","text":"","title":"Variables"},{"location":"apis/smart-contracts/AddressUpdater/","text":"AddressUpdater # Source | Inherits from IIAddressUpdater , Governed Keeps track of the current address for all unique and special platform contracts. This contract keeps a list of addresses that gets updated by governance every time any of the tracked contracts is redeployed. This list is then used by the FlareContractRegistry , and also by AddressUpdatable to inform all dependent contracts of any address change. Functions # addOrUpdateContractNamesAndAddresses # Defined in AddressUpdater ( Docs , Source ). function addOrUpdateContractNamesAndAddresses ( string [] _contractNames , address [] _contractAddresses ) external ; Add or update contract names and addresses that are later used in updateContractAddresses calls. Can only be called by governance . Parameters Type Description _contractNames string[] Contracts names. _contractAddresses address[] Addresses of corresponding contracts names. cancelGovernanceCall # Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector. constructor # Defined in AddressUpdater ( Docs , Source ). constructor ( address _governance ) public ; constructor # Defined in Governed ( Docs , Source ). constructor ( address _governance ) public ; Parameters Type Description _governance address Governance contract. Must not be zero. executeGovernanceCall # Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored). getContractAddress # Defined in AddressUpdater ( Docs , Source ). function getContractAddress ( string _name ) external view returns ( address ); Returns contract address for the given name, which might be address(0). Parameters Type Description _name string Name of the contract to query. Returns Type Description [0] address Current address for the queried contract. getContractAddressByHash # Defined in AddressUpdater ( Docs , Source ). function getContractAddressByHash ( bytes32 _nameHash ) external view returns ( address ); Returns contract address for the given name hash, which might be address(0). Parameters Type Description _nameHash bytes32 Hash of the contract name: keccak256(abi.encode(name)) Returns Type Description [0] address Current address for the queried contract. getContractAddresses # Defined in AddressUpdater ( Docs , Source ). function getContractAddresses ( string [] _names ) external view returns ( address []); Returns contract addresses for the given names, which might be address(0). Parameters Type Description _names string[] Names of the contracts to query. Returns Type Description [0] address[] Current addresses for the queried contracts. getContractAddressesByHash # Defined in AddressUpdater ( Docs , Source ). function getContractAddressesByHash ( bytes32 [] _nameHashes ) external view returns ( address []); Returns contract addresses for the given name hashes, which might be address(0). Parameters Type Description _nameHashes bytes32[] Hashes of the contract names: keccak256(abi.encode(name)) Returns Type Description [0] address[] Current addresses for the queried contracts. getContractNamesAndAddresses # Defined in AddressUpdater ( Docs , Source ). function getContractNamesAndAddresses ( ) external view returns ( string [] _contractNames , address [] _contractAddresses ); Returns all contract names and corresponding addresses currently being tracked. Returns Type Description _contractNames string[] Array of contract names. _contractAddresses address[] Array of contract addresses. governance # Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address. removeContracts # Defined in AddressUpdater ( Docs , Source ). function removeContracts ( string [] _contractNames ) external ; Remove contracts with given names. Can only be called by governance . Parameters Type Description _contractNames string[] Contract names. switchToProductionMode # Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered . update # Defined in AddressUpdater ( Docs , Source ). function update ( string [] _contractNames , address [] _contractAddresses , contract IIAddressUpdatable [] _contractsToUpdate ) external ; Set or update contract names and addresses, and then apply changes to specific contracts. This is a combination of addOrUpdateContractNamesAndAddresses and updateContractAddresses . Can only be called by governance . Parameters Type Description _contractNames string[] Contracts names. _contractAddresses address[] Addresses of corresponding contracts names. _contractsToUpdate contract IIAddressUpdatable[] Contracts to be updated. updateContractAddresses # Defined in AddressUpdater ( Docs , Source ). function updateContractAddresses ( contract IIAddressUpdatable [] _contractsToUpdate ) external ; Updates contract addresses on specific contracts. Can only be called by governance . Parameters Type Description _contractsToUpdate contract IIAddressUpdatable[] Contracts to be updated, which must implement the IIAddressUpdatable interface. Variables # governanceSettings # Defined in GovernedBase ( Docs , Source ). contract IGovernanceSettings governanceSettings Governance Settings. productionMode # Defined in GovernedBase ( Docs , Source ). bool productionMode When true, governance is enabled and cannot be disabled. See switchToProductionMode . timelockedCalls # Defined in GovernedBase ( Docs , Source ). mapping ( bytes4 => struct GovernedBase . TimelockedCall ) timelockedCalls List of pending timelocked governance calls.","title":"AddressUpdater"},{"location":"apis/smart-contracts/AddressUpdater/#ct_addressupdater","text":"Source | Inherits from IIAddressUpdater , Governed Keeps track of the current address for all unique and special platform contracts. This contract keeps a list of addresses that gets updated by governance every time any of the tracked contracts is redeployed. This list is then used by the FlareContractRegistry , and also by AddressUpdatable to inform all dependent contracts of any address change.","title":"AddressUpdater"},{"location":"apis/smart-contracts/AddressUpdater/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/AddressUpdater/#fn_addorupdatecontractnamesandaddresses_8246e467","text":"Defined in AddressUpdater ( Docs , Source ). function addOrUpdateContractNamesAndAddresses ( string [] _contractNames , address [] _contractAddresses ) external ; Add or update contract names and addresses that are later used in updateContractAddresses calls. Can only be called by governance . Parameters Type Description _contractNames string[] Contracts names. _contractAddresses address[] Addresses of corresponding contracts names.","title":"addOrUpdateContractNamesAndAddresses"},{"location":"apis/smart-contracts/AddressUpdater/#fn_cancelgovernancecall_67fc4029","text":"Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector.","title":"cancelGovernanceCall"},{"location":"apis/smart-contracts/AddressUpdater/#fn_constructor_undefined","text":"Defined in AddressUpdater ( Docs , Source ). constructor ( address _governance ) public ;","title":"constructor"},{"location":"apis/smart-contracts/AddressUpdater/#fn_constructor_undefined","text":"Defined in Governed ( Docs , Source ). constructor ( address _governance ) public ; Parameters Type Description _governance address Governance contract. Must not be zero.","title":"constructor"},{"location":"apis/smart-contracts/AddressUpdater/#fn_executegovernancecall_5ff27079","text":"Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored).","title":"executeGovernanceCall"},{"location":"apis/smart-contracts/AddressUpdater/#fn_getcontractaddress_04433bbc","text":"Defined in AddressUpdater ( Docs , Source ). function getContractAddress ( string _name ) external view returns ( address ); Returns contract address for the given name, which might be address(0). Parameters Type Description _name string Name of the contract to query. Returns Type Description [0] address Current address for the queried contract.","title":"getContractAddress"},{"location":"apis/smart-contracts/AddressUpdater/#fn_getcontractaddressbyhash_159354a2","text":"Defined in AddressUpdater ( Docs , Source ). function getContractAddressByHash ( bytes32 _nameHash ) external view returns ( address ); Returns contract address for the given name hash, which might be address(0). Parameters Type Description _nameHash bytes32 Hash of the contract name: keccak256(abi.encode(name)) Returns Type Description [0] address Current address for the queried contract.","title":"getContractAddressByHash"},{"location":"apis/smart-contracts/AddressUpdater/#fn_getcontractaddresses_ee6f63c3","text":"Defined in AddressUpdater ( Docs , Source ). function getContractAddresses ( string [] _names ) external view returns ( address []); Returns contract addresses for the given names, which might be address(0). Parameters Type Description _names string[] Names of the contracts to query. Returns Type Description [0] address[] Current addresses for the queried contracts.","title":"getContractAddresses"},{"location":"apis/smart-contracts/AddressUpdater/#fn_getcontractaddressesbyhash_5e11e2d1","text":"Defined in AddressUpdater ( Docs , Source ). function getContractAddressesByHash ( bytes32 [] _nameHashes ) external view returns ( address []); Returns contract addresses for the given name hashes, which might be address(0). Parameters Type Description _nameHashes bytes32[] Hashes of the contract names: keccak256(abi.encode(name)) Returns Type Description [0] address[] Current addresses for the queried contracts.","title":"getContractAddressesByHash"},{"location":"apis/smart-contracts/AddressUpdater/#fn_getcontractnamesandaddresses_2f26c5c3","text":"Defined in AddressUpdater ( Docs , Source ). function getContractNamesAndAddresses ( ) external view returns ( string [] _contractNames , address [] _contractAddresses ); Returns all contract names and corresponding addresses currently being tracked. Returns Type Description _contractNames string[] Array of contract names. _contractAddresses address[] Array of contract addresses.","title":"getContractNamesAndAddresses"},{"location":"apis/smart-contracts/AddressUpdater/#fn_governance_5aa6e675","text":"Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address.","title":"governance"},{"location":"apis/smart-contracts/AddressUpdater/#fn_removecontracts_70d44f28","text":"Defined in AddressUpdater ( Docs , Source ). function removeContracts ( string [] _contractNames ) external ; Remove contracts with given names. Can only be called by governance . Parameters Type Description _contractNames string[] Contract names.","title":"removeContracts"},{"location":"apis/smart-contracts/AddressUpdater/#fn_switchtoproductionmode_f5a98383","text":"Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered .","title":"switchToProductionMode"},{"location":"apis/smart-contracts/AddressUpdater/#fn_update_9933dba6","text":"Defined in AddressUpdater ( Docs , Source ). function update ( string [] _contractNames , address [] _contractAddresses , contract IIAddressUpdatable [] _contractsToUpdate ) external ; Set or update contract names and addresses, and then apply changes to specific contracts. This is a combination of addOrUpdateContractNamesAndAddresses and updateContractAddresses . Can only be called by governance . Parameters Type Description _contractNames string[] Contracts names. _contractAddresses address[] Addresses of corresponding contracts names. _contractsToUpdate contract IIAddressUpdatable[] Contracts to be updated.","title":"update"},{"location":"apis/smart-contracts/AddressUpdater/#fn_updatecontractaddresses_1b0e2960","text":"Defined in AddressUpdater ( Docs , Source ). function updateContractAddresses ( contract IIAddressUpdatable [] _contractsToUpdate ) external ; Updates contract addresses on specific contracts. Can only be called by governance . Parameters Type Description _contractsToUpdate contract IIAddressUpdatable[] Contracts to be updated, which must implement the IIAddressUpdatable interface.","title":"updateContractAddresses"},{"location":"apis/smart-contracts/AddressUpdater/#variables","text":"","title":"Variables"},{"location":"apis/smart-contracts/AddressUpdater/#va_governancesettings","text":"Defined in GovernedBase ( Docs , Source ). contract IGovernanceSettings governanceSettings Governance Settings.","title":"governanceSettings"},{"location":"apis/smart-contracts/AddressUpdater/#va_productionmode","text":"Defined in GovernedBase ( Docs , Source ). bool productionMode When true, governance is enabled and cannot be disabled. See switchToProductionMode .","title":"productionMode"},{"location":"apis/smart-contracts/AddressUpdater/#va_timelockedcalls","text":"Defined in GovernedBase ( Docs , Source ). mapping ( bytes4 => struct GovernedBase . TimelockedCall ) timelockedCalls List of pending timelocked governance calls.","title":"timelockedCalls"},{"location":"apis/smart-contracts/CheckPointable/","text":"CheckPointable # Source Check-Pointable ERC20 Behavior. ERC20 behavior that adds balance check-point features. Events # CreatedTotalSupplyCache # Defined in CheckPointable ( Docs , Source ). event CreatedTotalSupplyCache ( uint256 _blockNumber ) Emitted when a total supply cache entry is created. Allows history cleaners to track total supply cache cleanup opportunities off-chain. Functions # balanceHistoryCleanup # Defined in CheckPointable ( Docs , Source ). function balanceHistoryCleanup ( address _owner , uint256 _count ) external returns ( uint256 ); Delete balance checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _owner address balance owner account address _count uint256 maximum number of checkpoints to delete Returns Type Description [0] uint256 the number of checkpoints deleted totalSupplyCacheCleanup # Defined in CheckPointable ( Docs , Source ). function totalSupplyCacheCleanup ( uint256 _blockNumber ) external returns ( uint256 ); Delete total supply cache entry that expired (i.e. is before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _blockNumber uint256 the block number for which total supply value was cached Returns Type Description [0] uint256 the number of cache entries deleted (always 0 or 1) totalSupplyHistoryCleanup # Defined in CheckPointable ( Docs , Source ). function totalSupplyHistoryCleanup ( uint256 _count ) external returns ( uint256 ); Delete total supply checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _count uint256 maximum number of checkpoints to delete Returns Type Description [0] uint256 the number of checkpoints deleted Modifiers # notBeforeCleanupBlock # Defined in CheckPointable ( Docs , Source ). modifier notBeforeCleanupBlock ( uint256 _blockNumber ) This method cannot be called for _blockNumber lower than the current cleanup block number. onlyCleaner # Defined in CheckPointable ( Docs , Source ). modifier onlyCleaner () Only the cleanerContract can call this method. Variables # cleanerContract # Defined in CheckPointable ( Docs , Source ). address cleanerContract Address of the contract that is allowed to call methods for history cleaning.","title":"CheckPointable"},{"location":"apis/smart-contracts/CheckPointable/#ct_checkpointable","text":"Source Check-Pointable ERC20 Behavior. ERC20 behavior that adds balance check-point features.","title":"CheckPointable"},{"location":"apis/smart-contracts/CheckPointable/#events","text":"","title":"Events"},{"location":"apis/smart-contracts/CheckPointable/#ev_createdtotalsupplycache","text":"Defined in CheckPointable ( Docs , Source ). event CreatedTotalSupplyCache ( uint256 _blockNumber ) Emitted when a total supply cache entry is created. Allows history cleaners to track total supply cache cleanup opportunities off-chain.","title":"CreatedTotalSupplyCache"},{"location":"apis/smart-contracts/CheckPointable/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/CheckPointable/#fn_balancehistorycleanup_f0e292c9","text":"Defined in CheckPointable ( Docs , Source ). function balanceHistoryCleanup ( address _owner , uint256 _count ) external returns ( uint256 ); Delete balance checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _owner address balance owner account address _count uint256 maximum number of checkpoints to delete Returns Type Description [0] uint256 the number of checkpoints deleted","title":"balanceHistoryCleanup"},{"location":"apis/smart-contracts/CheckPointable/#fn_totalsupplycachecleanup_43ea370b","text":"Defined in CheckPointable ( Docs , Source ). function totalSupplyCacheCleanup ( uint256 _blockNumber ) external returns ( uint256 ); Delete total supply cache entry that expired (i.e. is before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _blockNumber uint256 the block number for which total supply value was cached Returns Type Description [0] uint256 the number of cache entries deleted (always 0 or 1)","title":"totalSupplyCacheCleanup"},{"location":"apis/smart-contracts/CheckPointable/#fn_totalsupplyhistorycleanup_f62f8f3a","text":"Defined in CheckPointable ( Docs , Source ). function totalSupplyHistoryCleanup ( uint256 _count ) external returns ( uint256 ); Delete total supply checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _count uint256 maximum number of checkpoints to delete Returns Type Description [0] uint256 the number of checkpoints deleted","title":"totalSupplyHistoryCleanup"},{"location":"apis/smart-contracts/CheckPointable/#modifiers","text":"","title":"Modifiers"},{"location":"apis/smart-contracts/CheckPointable/#md_notbeforecleanupblock","text":"Defined in CheckPointable ( Docs , Source ). modifier notBeforeCleanupBlock ( uint256 _blockNumber ) This method cannot be called for _blockNumber lower than the current cleanup block number.","title":"notBeforeCleanupBlock"},{"location":"apis/smart-contracts/CheckPointable/#md_onlycleaner","text":"Defined in CheckPointable ( Docs , Source ). modifier onlyCleaner () Only the cleanerContract can call this method.","title":"onlyCleaner"},{"location":"apis/smart-contracts/CheckPointable/#variables","text":"","title":"Variables"},{"location":"apis/smart-contracts/CheckPointable/#va_cleanercontract","text":"Defined in CheckPointable ( Docs , Source ). address cleanerContract Address of the contract that is allowed to call methods for history cleaning.","title":"cleanerContract"},{"location":"apis/smart-contracts/ClaimSetupManager/","text":"ClaimSetupManager # Source | Inherits from IIClaimSetupManager , Governed , AddressUpdatable , CloneFactory , ReentrancyGuard Manages automation of operations related to reward claiming. Rewards include FTSO rewards and airdrops . Managed operations include Automatic Claiming and Personal Delegation Accounts . Functions # accountToDelegationAccount # Defined in ClaimSetupManager ( Docs , Source ). function accountToDelegationAccount ( address _owner ) external view returns ( address ); Gets the PDA of an account. Parameters Type Description _owner address Account to query. Returns Type Description [0] address Address of its PDA or address(0) if it has not been created yet. allowedClaimRecipients # Defined in ClaimSetupManager ( Docs , Source ). function allowedClaimRecipients ( address _owner ) external view returns ( address []); Gets the addresses of recipients allowed to receive rewards on behalf of an account. Beside these, the owner of the rewards is always authorized. See setAllowedClaimRecipients . Parameters Type Description _owner address Returns Type Description [0] address[] Addresses of all set authorized recipients. batchDelegate # Defined in ClaimSetupManager ( Docs , Source ). function batchDelegate ( address [] _delegatees , uint256 [] _bips ) external ; Undelegates all percentage delegations from the caller's PDA and then delegate to a list of accounts. See delegate . Parameters Type Description _delegatees address[] The addresses of the new recipients. _bips uint256[] The percentage of voting power to be delegated to each delegatee, expressed in basis points (1/100 of one percent). Total of all _bips values must be lower than 10000. cancelGovernanceCall # Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector. checkExecutorAndAllowedRecipient # Defined in ClaimSetupManager ( Docs , Source ). function checkExecutorAndAllowedRecipient ( address _executor , address _claimFor , address _recipient ) external view ; Checks if an executor can claim on behalf of a given account and send funds to a given recipient address. Reverts if claiming is not possible, does nothing otherwise. Parameters Type Description _executor address The executor to query. _claimFor address _recipient address The address where the reward would be sent. claimExecutors # Defined in ClaimSetupManager ( Docs , Source ). function claimExecutors ( address _owner ) external view returns ( address []); Gets the addresses of executors authorized to claim for an account. See setClaimExecutors . Parameters Type Description _owner address The account to query. Returns Type Description [0] address[] Addresses of all set executors. constructor # Defined in ClaimSetupManager ( Docs , Source ). constructor ( address _governance , address _addressUpdater , uint256 _feeValueUpdateOffset , uint256 _minFeeValueWei , uint256 _maxFeeValueWei , uint256 _registerExecutorFeeValueWei ) public ; constructor # Defined in Governed ( Docs , Source ). constructor ( address _governance ) public ; Parameters Type Description _governance address Governance contract. Must not be zero. delegate # Defined in ClaimSetupManager ( Docs , Source ). function delegate ( address _to , uint256 _bips ) external ; Delegates a percentage of the caller's PDA 's voting power to another address. Parameters Type Description _to address The address of the recipient. _bips uint256 The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: Every call resets the delegation value. A value of 0 revokes delegation. delegateGovernance # Defined in ClaimSetupManager ( Docs , Source ). function delegateGovernance ( address _to ) external ; Delegates all the governance vote power of the caller's PDA to another account. Parameters Type Description _to address Address of the recipient of the delegation. disableDelegationAccount # Defined in ClaimSetupManager ( Docs , Source ). function disableDelegationAccount ( ) external ; Disables the Personal Delegation Account (PDA). When using automatic claiming, all airdrops and FTSO rewards will be sent to the owner's account. Rewards accrued by the PDA will no longer be automatically claimed. Reverts if there is no PDA. enableDelegationAccount # Defined in ClaimSetupManager ( Docs , Source ). function enableDelegationAccount ( ) external returns ( contract IDelegationAccount ); Enables (or creates) a Personal Delegation Account (PDA). When using automatic claiming, all airdrops and FTSO rewards will be sent to the PDA, and any rewards accrued by the PDA will be claimed too. Returns Type Description [0] contract IDelegationAccount Address of the delegation account contract. executeGovernanceCall # Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored). getAddressUpdater # Defined in AddressUpdatable ( Docs , Source ). function getAddressUpdater ( ) public view returns ( address _addressUpdater ); Returns the configured address updater. Returns Type Description _addressUpdater address The AddresUpdater contract that can update our contract address list, as a response to a governance call. getAutoClaimAddressesAndExecutorFee # Defined in ClaimSetupManager ( Docs , Source ). function getAutoClaimAddressesAndExecutorFee ( address _executor , address [] _owners ) external view returns ( address [] _recipients , uint256 _executorFeeValue ); Gets the Personal Delegation Account (PDA) for a list of accounts for which an executor is claiming. Returns owner address instead if the PDA is not created yet or not enabled. Parameters Type Description _executor address Executor to query. _owners address[] Array of reward owners which must have set _executor as their executor. Returns Type Description _recipients address[] Addresses which will receive the claimed rewards. Can be the reward owners or their PDAs. _executorFeeValue uint256 Executor's fee value, in wei. getDelegationAccountData # Defined in ClaimSetupManager ( Docs , Source ). function getDelegationAccountData ( address _owner ) external view returns ( contract IDelegationAccount _delegationAccount , bool _enabled ); Gets PDA data for an account. Parameters Type Description _owner address Account to query. Returns Type Description _delegationAccount contract IDelegationAccount Account's PDA address or address(0) if it has not been created yet. _enabled bool Whether the PDA is enabled. getExecutorCurrentFeeValue # Defined in ClaimSetupManager ( Docs , Source ). function getExecutorCurrentFeeValue ( address _executor ) public view returns ( uint256 ); Returns the current fee of a registered executor. Reverts if the executor is not registered. Parameters Type Description _executor address The executor to query. Returns Type Description [0] uint256 Fee in wei. getExecutorFeeValue # Defined in ClaimSetupManager ( Docs , Source ). function getExecutorFeeValue ( address _executor , uint256 _rewardEpoch ) external view returns ( uint256 ); Returns the fee of an executor at a given reward epoch. Parameters Type Description _executor address The executor to query. _rewardEpoch uint256 Reward Epoch ID to query. Returns Type Description [0] uint256 Fee in wei at that reward epoch. getExecutorInfo # Defined in ClaimSetupManager ( Docs , Source ). function getExecutorInfo ( address _executor ) external view returns ( bool _registered , uint256 _currentFeeValue ); Returns information about an executor. Parameters Type Description _executor address The executor to query. Returns Type Description _registered bool Whether the executor is registered. _currentFeeValue uint256 Executor's current fee value, if registered. getExecutorScheduledFeeValueChanges # Defined in ClaimSetupManager ( Docs , Source ). function getExecutorScheduledFeeValueChanges ( address _executor ) external view returns ( uint256 [] _feeValue , uint256 [] _validFromEpoch , bool [] _fixed ); Returns the currently scheduled fee changes of an executor. Parameters Type Description _executor address Executor to query. Returns Type Description _feeValue uint256[] Array of scheduled fees. _validFromEpoch uint256[] Array of reward epochs ID where the scheduled fees will become effective. _fixed bool[] Array of booleans indicating if an scheduled fee change is fixed or it might still be changed. getRegisteredExecutors # Defined in ClaimSetupManager ( Docs , Source ). function getRegisteredExecutors ( uint256 _start , uint256 _end ) external view returns ( address [] _registeredExecutors , uint256 _totalLength ); Returns the list of executors registered through registerExecutor . Supports paging. Parameters Type Description _start uint256 First executor to return. _end uint256 Last executor to return. Returns Type Description _registeredExecutors address[] Addresses of the registered executors. _totalLength uint256 Total amount of executors. governance # Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address. isClaimExecutor # Defined in ClaimSetupManager ( Docs , Source ). function isClaimExecutor ( address _owner , address _executor ) external view returns ( bool ); Returns whether an executor is authorized to claim on behalf of a reward owner. See setClaimExecutors . Parameters Type Description _owner address The reward owner to query. _executor address The executor to query. registerExecutor # Defined in ClaimSetupManager ( Docs , Source ). function registerExecutor ( uint256 _feeValue ) external payable returns ( uint256 ); Registers the caller as an executor and sets its initial fee value. If the executor was already registered, this method only updates the fee, which will take effect after feeValueUpdateOffset reward epochs have elapsed. Executor must pay a fee in order to register. See registerExecutorFeeValueWei . Parameters Type Description _feeValue uint256 Desired fee, in wei. Must be between minFeeValueWei and maxFeeValueWei . 0 means no fee. Returns Type Description [0] uint256 Reward epoch ID when the changes become effective. revokeDelegationAt # Defined in ClaimSetupManager ( Docs , Source ). function revokeDelegationAt ( address _who , uint256 _blockNumber ) external ; Revokes all delegation from the caller's PDA to a given account at a given block. Only affects the reads via votePowerOfAtCached() in the specified block. This method should be used only to prevent rogue delegate voting in the current voting block. To stop delegating use delegate with percentage of 0 or undelegateAll . Parameters Type Description _who address The account to revoke. _blockNumber uint256 Block number where the revoking will take place. Must be in the past. setAllowedClaimRecipients # Defined in ClaimSetupManager ( Docs , Source ). function setAllowedClaimRecipients ( address [] _recipients ) external ; Set the addresses of allowed recipients. The reward owner is always an allowed recipient. Parameters Type Description _recipients address[] The new allowed recipients. All old recipients will be deleted and replaced by these. setAutoClaiming # Defined in ClaimSetupManager ( Docs , Source ). function setAutoClaiming ( address [] _executors , bool _enableDelegationAccount ) external payable ; Sets the addresses of executors and optionally enables (creates) a Personal Delegation Account (PDA). If any of the executors is a registered executor, some fee needs to be paid. Parameters Type Description _executors address[] The new executors. All old executors will be deleted and replaced by these. _enableDelegationAccount bool Whether the PDA should be enabled. setClaimExecutors # Defined in ClaimSetupManager ( Docs , Source ). function setClaimExecutors ( address [] _executors ) external payable ; Sets the addresses of executors. If any of the executors is a registered executor, some fee needs to be paid. Parameters Type Description _executors address[] The new executors. All old executors will be deleted and replaced by these. setLibraryAddress # Defined in ClaimSetupManager ( Docs , Source ). function setLibraryAddress ( address _libraryAddress ) external ; Sets new library address. Only governance can call this. setMaxFeeValueWei # Defined in ClaimSetupManager ( Docs , Source ). function setMaxFeeValueWei ( uint256 _maxFeeValueWei ) external ; Sets maximum fee allowed for executors, in wei. Only governance can call this. setMinFeeValueWei # Defined in ClaimSetupManager ( Docs , Source ). function setMinFeeValueWei ( uint256 _minFeeValueWei ) external ; Sets minimum fee allowed for executors, in wei. Only governance can call this. setRegisterExecutorFeeValueWei # Defined in ClaimSetupManager ( Docs , Source ). function setRegisterExecutorFeeValueWei ( uint256 _registerExecutorFeeValueWei ) external ; Sets the fee required to register an executor, which must be higher than 0. Only governance can call this. switchToProductionMode # Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered . transferExternalToken # Defined in ClaimSetupManager ( Docs , Source ). function transferExternalToken ( contract IERC20 _token , uint256 _amount ) external ; Allows the caller to transfer ERC-20 tokens from their PDA to the owner account. The main use case is to move ERC-20 tokes received by mistake (by an airdrop, for example) out of the PDA and into the main account, where they can be more easily managed. Reverts if the target token is the WNat contract: use method withdraw for that. Parameters Type Description _token contract IERC20 Target token contract address. _amount uint256 Amount of tokens to transfer. undelegateAll # Defined in ClaimSetupManager ( Docs , Source ). function undelegateAll ( ) external ; Removes all delegations from the caller's PDA . undelegateGovernance # Defined in ClaimSetupManager ( Docs , Source ). function undelegateGovernance ( ) external ; Undelegates all governance vote power currently delegated by the caller's PDA . unregisterExecutor # Defined in ClaimSetupManager ( Docs , Source ). function unregisterExecutor ( ) external returns ( uint256 _validFromEpoch ); Unregisters the caller as an executor. Returns Type Description _validFromEpoch uint256 Reward epoch ID when the change becomes effective. updateContractAddresses # Defined in AddressUpdatable ( Docs , Source ). function updateContractAddresses ( bytes32 [] _contractNameHashes , address [] _contractAddresses ) external ; External method called from AddressUpdater only. updateExecutorFeeValue # Defined in ClaimSetupManager ( Docs , Source ). function updateExecutorFeeValue ( uint256 _feeValue ) external returns ( uint256 ); Sets the caller's executor fee. The caller must be an executor registered through registerExecutor . When called multiple times inside the same reward epoch, only the last value remains. Parameters Type Description _feeValue uint256 Desired fee, in wei. Must be between minFeeValueWei and maxFeeValueWei . 0 means no fee. Returns Type Description [0] uint256 Reward epoch ID when the changes become effective. wNat # Defined in IIClaimSetupManager ( Docs , Source ). function wNat ( ) external view returns ( contract WNat ); Returns the WNat contract. withdraw # Defined in ClaimSetupManager ( Docs , Source ). function withdraw ( uint256 _amount ) external ; Allows the caller to transfer WNat wrapped tokens from their PDA to the owner account. Parameters Type Description _amount uint256 Amount of tokens to transfer, in wei. Modifiers # nonReentrant # Defined in ReentrancyGuard ( Source ). modifier nonReentrant () Prevents a contract from calling itself, directly or indirectly. Calling a nonReentrant function from another nonReentrant function is not supported. It is possible to prevent this from happening by making the nonReentrant function external, and make it call a private function that does the actual work. onlyAddressUpdater # Defined in AddressUpdatable ( Docs , Source ). modifier onlyAddressUpdater () Only the AdressUpdater contract can call this method. Its address is set at construction time but it can also update itself. onlyGovernance # Defined in GovernedBase ( Docs , Source ). modifier onlyGovernance () onlyImmediateGovernance # Defined in GovernedBase ( Docs , Source ). modifier onlyImmediateGovernance () onlyOwnerOrExecutor # Defined in ClaimSetupManager ( Docs , Source ). modifier onlyOwnerOrExecutor ( address _executor , address [] _owners ) Structures # DelegationAccountData # Defined in ClaimSetupManager ( Docs , Source ). struct DelegationAccountData { contract IIDelegationAccount delegationAccount ; bool enabled ; } ExecutorFee # Defined in ClaimSetupManager ( Docs , Source ). struct ExecutorFee { uint256 value ; uint256 validFromEpoch ; } TimelockedCall # Defined in GovernedBase ( Docs , Source ). struct TimelockedCall { uint256 allowedAfterTimestamp ; bytes encodedCall ; } Variables # feeValueUpdateOffset # Defined in ClaimSetupManager ( Docs , Source ). uint256 feeValueUpdateOffset Number of reward epochs that must elapse before an executor's fee change takes effect. ftsoManager # Defined in ClaimSetupManager ( Docs , Source ). contract IFtsoManager ftsoManager The FtsoManager contract. governanceSettings # Defined in GovernedBase ( Docs , Source ). contract IGovernanceSettings governanceSettings Governance Settings. governanceVP # Defined in ClaimSetupManager ( Docs , Source ). contract IGovernanceVotePower governanceVP The GovernanceVotePower contract. libraryAddress # Defined in ClaimSetupManager ( Docs , Source ). address libraryAddress maxFeeValueWei # Defined in ClaimSetupManager ( Docs , Source ). uint256 maxFeeValueWei Maximum allowed value for an executor's fee. minFeeValueWei # Defined in ClaimSetupManager ( Docs , Source ). uint256 minFeeValueWei Minimum allowed value for an executor's fee. productionMode # Defined in GovernedBase ( Docs , Source ). bool productionMode When true, governance is enabled and cannot be disabled. See switchToProductionMode . registerExecutorFeeValueWei # Defined in ClaimSetupManager ( Docs , Source ). uint256 registerExecutorFeeValueWei Fee that must be paid to register an executor. timelockedCalls # Defined in GovernedBase ( Docs , Source ). mapping ( bytes4 => struct GovernedBase . TimelockedCall ) timelockedCalls List of pending timelocked governance calls. wNat # Defined in ClaimSetupManager ( Docs , Source ). contract WNat wNat The WNat contract.","title":"ClaimSetupManager"},{"location":"apis/smart-contracts/ClaimSetupManager/#ct_claimsetupmanager","text":"Source | Inherits from IIClaimSetupManager , Governed , AddressUpdatable , CloneFactory , ReentrancyGuard Manages automation of operations related to reward claiming. Rewards include FTSO rewards and airdrops . Managed operations include Automatic Claiming and Personal Delegation Accounts .","title":"ClaimSetupManager"},{"location":"apis/smart-contracts/ClaimSetupManager/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_accounttodelegationaccount_69ea2387","text":"Defined in ClaimSetupManager ( Docs , Source ). function accountToDelegationAccount ( address _owner ) external view returns ( address ); Gets the PDA of an account. Parameters Type Description _owner address Account to query. Returns Type Description [0] address Address of its PDA or address(0) if it has not been created yet.","title":"accountToDelegationAccount"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_allowedclaimrecipients_dfd14c34","text":"Defined in ClaimSetupManager ( Docs , Source ). function allowedClaimRecipients ( address _owner ) external view returns ( address []); Gets the addresses of recipients allowed to receive rewards on behalf of an account. Beside these, the owner of the rewards is always authorized. See setAllowedClaimRecipients . Parameters Type Description _owner address Returns Type Description [0] address[] Addresses of all set authorized recipients.","title":"allowedClaimRecipients"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_batchdelegate_dc4fcda7","text":"Defined in ClaimSetupManager ( Docs , Source ). function batchDelegate ( address [] _delegatees , uint256 [] _bips ) external ; Undelegates all percentage delegations from the caller's PDA and then delegate to a list of accounts. See delegate . Parameters Type Description _delegatees address[] The addresses of the new recipients. _bips uint256[] The percentage of voting power to be delegated to each delegatee, expressed in basis points (1/100 of one percent). Total of all _bips values must be lower than 10000.","title":"batchDelegate"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_cancelgovernancecall_67fc4029","text":"Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector.","title":"cancelGovernanceCall"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_checkexecutorandallowedrecipient_ce2caa57","text":"Defined in ClaimSetupManager ( Docs , Source ). function checkExecutorAndAllowedRecipient ( address _executor , address _claimFor , address _recipient ) external view ; Checks if an executor can claim on behalf of a given account and send funds to a given recipient address. Reverts if claiming is not possible, does nothing otherwise. Parameters Type Description _executor address The executor to query. _claimFor address _recipient address The address where the reward would be sent.","title":"checkExecutorAndAllowedRecipient"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_claimexecutors_3f317fe1","text":"Defined in ClaimSetupManager ( Docs , Source ). function claimExecutors ( address _owner ) external view returns ( address []); Gets the addresses of executors authorized to claim for an account. See setClaimExecutors . Parameters Type Description _owner address The account to query. Returns Type Description [0] address[] Addresses of all set executors.","title":"claimExecutors"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_constructor_undefined","text":"Defined in ClaimSetupManager ( Docs , Source ). constructor ( address _governance , address _addressUpdater , uint256 _feeValueUpdateOffset , uint256 _minFeeValueWei , uint256 _maxFeeValueWei , uint256 _registerExecutorFeeValueWei ) public ;","title":"constructor"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_constructor_undefined","text":"Defined in Governed ( Docs , Source ). constructor ( address _governance ) public ; Parameters Type Description _governance address Governance contract. Must not be zero.","title":"constructor"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_delegate_026e402b","text":"Defined in ClaimSetupManager ( Docs , Source ). function delegate ( address _to , uint256 _bips ) external ; Delegates a percentage of the caller's PDA 's voting power to another address. Parameters Type Description _to address The address of the recipient. _bips uint256 The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: Every call resets the delegation value. A value of 0 revokes delegation.","title":"delegate"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_delegategovernance_7a68a508","text":"Defined in ClaimSetupManager ( Docs , Source ). function delegateGovernance ( address _to ) external ; Delegates all the governance vote power of the caller's PDA to another account. Parameters Type Description _to address Address of the recipient of the delegation.","title":"delegateGovernance"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_disabledelegationaccount_2394deb1","text":"Defined in ClaimSetupManager ( Docs , Source ). function disableDelegationAccount ( ) external ; Disables the Personal Delegation Account (PDA). When using automatic claiming, all airdrops and FTSO rewards will be sent to the owner's account. Rewards accrued by the PDA will no longer be automatically claimed. Reverts if there is no PDA.","title":"disableDelegationAccount"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_enabledelegationaccount_f0977215","text":"Defined in ClaimSetupManager ( Docs , Source ). function enableDelegationAccount ( ) external returns ( contract IDelegationAccount ); Enables (or creates) a Personal Delegation Account (PDA). When using automatic claiming, all airdrops and FTSO rewards will be sent to the PDA, and any rewards accrued by the PDA will be claimed too. Returns Type Description [0] contract IDelegationAccount Address of the delegation account contract.","title":"enableDelegationAccount"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_executegovernancecall_5ff27079","text":"Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored).","title":"executeGovernanceCall"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_getaddressupdater_5267a15d","text":"Defined in AddressUpdatable ( Docs , Source ). function getAddressUpdater ( ) public view returns ( address _addressUpdater ); Returns the configured address updater. Returns Type Description _addressUpdater address The AddresUpdater contract that can update our contract address list, as a response to a governance call.","title":"getAddressUpdater"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_getautoclaimaddressesandexecutorfee_e24883b2","text":"Defined in ClaimSetupManager ( Docs , Source ). function getAutoClaimAddressesAndExecutorFee ( address _executor , address [] _owners ) external view returns ( address [] _recipients , uint256 _executorFeeValue ); Gets the Personal Delegation Account (PDA) for a list of accounts for which an executor is claiming. Returns owner address instead if the PDA is not created yet or not enabled. Parameters Type Description _executor address Executor to query. _owners address[] Array of reward owners which must have set _executor as their executor. Returns Type Description _recipients address[] Addresses which will receive the claimed rewards. Can be the reward owners or their PDAs. _executorFeeValue uint256 Executor's fee value, in wei.","title":"getAutoClaimAddressesAndExecutorFee"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_getdelegationaccountdata_17a1e3fc","text":"Defined in ClaimSetupManager ( Docs , Source ). function getDelegationAccountData ( address _owner ) external view returns ( contract IDelegationAccount _delegationAccount , bool _enabled ); Gets PDA data for an account. Parameters Type Description _owner address Account to query. Returns Type Description _delegationAccount contract IDelegationAccount Account's PDA address or address(0) if it has not been created yet. _enabled bool Whether the PDA is enabled.","title":"getDelegationAccountData"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_getexecutorcurrentfeevalue_e25547f8","text":"Defined in ClaimSetupManager ( Docs , Source ). function getExecutorCurrentFeeValue ( address _executor ) public view returns ( uint256 ); Returns the current fee of a registered executor. Reverts if the executor is not registered. Parameters Type Description _executor address The executor to query. Returns Type Description [0] uint256 Fee in wei.","title":"getExecutorCurrentFeeValue"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_getexecutorfeevalue_3f8f784c","text":"Defined in ClaimSetupManager ( Docs , Source ). function getExecutorFeeValue ( address _executor , uint256 _rewardEpoch ) external view returns ( uint256 ); Returns the fee of an executor at a given reward epoch. Parameters Type Description _executor address The executor to query. _rewardEpoch uint256 Reward Epoch ID to query. Returns Type Description [0] uint256 Fee in wei at that reward epoch.","title":"getExecutorFeeValue"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_getexecutorinfo_8e28b923","text":"Defined in ClaimSetupManager ( Docs , Source ). function getExecutorInfo ( address _executor ) external view returns ( bool _registered , uint256 _currentFeeValue ); Returns information about an executor. Parameters Type Description _executor address The executor to query. Returns Type Description _registered bool Whether the executor is registered. _currentFeeValue uint256 Executor's current fee value, if registered.","title":"getExecutorInfo"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_getexecutorscheduledfeevaluechanges_950b028c","text":"Defined in ClaimSetupManager ( Docs , Source ). function getExecutorScheduledFeeValueChanges ( address _executor ) external view returns ( uint256 [] _feeValue , uint256 [] _validFromEpoch , bool [] _fixed ); Returns the currently scheduled fee changes of an executor. Parameters Type Description _executor address Executor to query. Returns Type Description _feeValue uint256[] Array of scheduled fees. _validFromEpoch uint256[] Array of reward epochs ID where the scheduled fees will become effective. _fixed bool[] Array of booleans indicating if an scheduled fee change is fixed or it might still be changed.","title":"getExecutorScheduledFeeValueChanges"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_getregisteredexecutors_6e927e61","text":"Defined in ClaimSetupManager ( Docs , Source ). function getRegisteredExecutors ( uint256 _start , uint256 _end ) external view returns ( address [] _registeredExecutors , uint256 _totalLength ); Returns the list of executors registered through registerExecutor . Supports paging. Parameters Type Description _start uint256 First executor to return. _end uint256 Last executor to return. Returns Type Description _registeredExecutors address[] Addresses of the registered executors. _totalLength uint256 Total amount of executors.","title":"getRegisteredExecutors"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_governance_5aa6e675","text":"Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address.","title":"governance"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_isclaimexecutor_87962abe","text":"Defined in ClaimSetupManager ( Docs , Source ). function isClaimExecutor ( address _owner , address _executor ) external view returns ( bool ); Returns whether an executor is authorized to claim on behalf of a reward owner. See setClaimExecutors . Parameters Type Description _owner address The reward owner to query. _executor address The executor to query.","title":"isClaimExecutor"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_registerexecutor_ccce7e86","text":"Defined in ClaimSetupManager ( Docs , Source ). function registerExecutor ( uint256 _feeValue ) external payable returns ( uint256 ); Registers the caller as an executor and sets its initial fee value. If the executor was already registered, this method only updates the fee, which will take effect after feeValueUpdateOffset reward epochs have elapsed. Executor must pay a fee in order to register. See registerExecutorFeeValueWei . Parameters Type Description _feeValue uint256 Desired fee, in wei. Must be between minFeeValueWei and maxFeeValueWei . 0 means no fee. Returns Type Description [0] uint256 Reward epoch ID when the changes become effective.","title":"registerExecutor"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_revokedelegationat_bbd6fbf8","text":"Defined in ClaimSetupManager ( Docs , Source ). function revokeDelegationAt ( address _who , uint256 _blockNumber ) external ; Revokes all delegation from the caller's PDA to a given account at a given block. Only affects the reads via votePowerOfAtCached() in the specified block. This method should be used only to prevent rogue delegate voting in the current voting block. To stop delegating use delegate with percentage of 0 or undelegateAll . Parameters Type Description _who address The account to revoke. _blockNumber uint256 Block number where the revoking will take place. Must be in the past.","title":"revokeDelegationAt"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_setallowedclaimrecipients_d2a4ac61","text":"Defined in ClaimSetupManager ( Docs , Source ). function setAllowedClaimRecipients ( address [] _recipients ) external ; Set the addresses of allowed recipients. The reward owner is always an allowed recipient. Parameters Type Description _recipients address[] The new allowed recipients. All old recipients will be deleted and replaced by these.","title":"setAllowedClaimRecipients"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_setautoclaiming_e72dcdbb","text":"Defined in ClaimSetupManager ( Docs , Source ). function setAutoClaiming ( address [] _executors , bool _enableDelegationAccount ) external payable ; Sets the addresses of executors and optionally enables (creates) a Personal Delegation Account (PDA). If any of the executors is a registered executor, some fee needs to be paid. Parameters Type Description _executors address[] The new executors. All old executors will be deleted and replaced by these. _enableDelegationAccount bool Whether the PDA should be enabled.","title":"setAutoClaiming"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_setclaimexecutors_9119c494","text":"Defined in ClaimSetupManager ( Docs , Source ). function setClaimExecutors ( address [] _executors ) external payable ; Sets the addresses of executors. If any of the executors is a registered executor, some fee needs to be paid. Parameters Type Description _executors address[] The new executors. All old executors will be deleted and replaced by these.","title":"setClaimExecutors"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_setlibraryaddress_4863ba17","text":"Defined in ClaimSetupManager ( Docs , Source ). function setLibraryAddress ( address _libraryAddress ) external ; Sets new library address. Only governance can call this.","title":"setLibraryAddress"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_setmaxfeevaluewei_2e9b6afa","text":"Defined in ClaimSetupManager ( Docs , Source ). function setMaxFeeValueWei ( uint256 _maxFeeValueWei ) external ; Sets maximum fee allowed for executors, in wei. Only governance can call this.","title":"setMaxFeeValueWei"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_setminfeevaluewei_d8343550","text":"Defined in ClaimSetupManager ( Docs , Source ). function setMinFeeValueWei ( uint256 _minFeeValueWei ) external ; Sets minimum fee allowed for executors, in wei. Only governance can call this.","title":"setMinFeeValueWei"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_setregisterexecutorfeevaluewei_869d90a5","text":"Defined in ClaimSetupManager ( Docs , Source ). function setRegisterExecutorFeeValueWei ( uint256 _registerExecutorFeeValueWei ) external ; Sets the fee required to register an executor, which must be higher than 0. Only governance can call this.","title":"setRegisterExecutorFeeValueWei"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_switchtoproductionmode_f5a98383","text":"Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered .","title":"switchToProductionMode"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_transferexternaltoken_489a8a47","text":"Defined in ClaimSetupManager ( Docs , Source ). function transferExternalToken ( contract IERC20 _token , uint256 _amount ) external ; Allows the caller to transfer ERC-20 tokens from their PDA to the owner account. The main use case is to move ERC-20 tokes received by mistake (by an airdrop, for example) out of the PDA and into the main account, where they can be more easily managed. Reverts if the target token is the WNat contract: use method withdraw for that. Parameters Type Description _token contract IERC20 Target token contract address. _amount uint256 Amount of tokens to transfer.","title":"transferExternalToken"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_undelegateall_b302f393","text":"Defined in ClaimSetupManager ( Docs , Source ). function undelegateAll ( ) external ; Removes all delegations from the caller's PDA .","title":"undelegateAll"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_undelegategovernance_87a2a0dc","text":"Defined in ClaimSetupManager ( Docs , Source ). function undelegateGovernance ( ) external ; Undelegates all governance vote power currently delegated by the caller's PDA .","title":"undelegateGovernance"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_unregisterexecutor_868a660f","text":"Defined in ClaimSetupManager ( Docs , Source ). function unregisterExecutor ( ) external returns ( uint256 _validFromEpoch ); Unregisters the caller as an executor. Returns Type Description _validFromEpoch uint256 Reward epoch ID when the change becomes effective.","title":"unregisterExecutor"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_updatecontractaddresses_b00c0b76","text":"Defined in AddressUpdatable ( Docs , Source ). function updateContractAddresses ( bytes32 [] _contractNameHashes , address [] _contractAddresses ) external ; External method called from AddressUpdater only.","title":"updateContractAddresses"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_updateexecutorfeevalue_831f16af","text":"Defined in ClaimSetupManager ( Docs , Source ). function updateExecutorFeeValue ( uint256 _feeValue ) external returns ( uint256 ); Sets the caller's executor fee. The caller must be an executor registered through registerExecutor . When called multiple times inside the same reward epoch, only the last value remains. Parameters Type Description _feeValue uint256 Desired fee, in wei. Must be between minFeeValueWei and maxFeeValueWei . 0 means no fee. Returns Type Description [0] uint256 Reward epoch ID when the changes become effective.","title":"updateExecutorFeeValue"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_wnat_9edbf007","text":"Defined in IIClaimSetupManager ( Docs , Source ). function wNat ( ) external view returns ( contract WNat ); Returns the WNat contract.","title":"wNat"},{"location":"apis/smart-contracts/ClaimSetupManager/#fn_withdraw_2e1a7d4d","text":"Defined in ClaimSetupManager ( Docs , Source ). function withdraw ( uint256 _amount ) external ; Allows the caller to transfer WNat wrapped tokens from their PDA to the owner account. Parameters Type Description _amount uint256 Amount of tokens to transfer, in wei.","title":"withdraw"},{"location":"apis/smart-contracts/ClaimSetupManager/#modifiers","text":"","title":"Modifiers"},{"location":"apis/smart-contracts/ClaimSetupManager/#md_nonreentrant","text":"Defined in ReentrancyGuard ( Source ). modifier nonReentrant () Prevents a contract from calling itself, directly or indirectly. Calling a nonReentrant function from another nonReentrant function is not supported. It is possible to prevent this from happening by making the nonReentrant function external, and make it call a private function that does the actual work.","title":"nonReentrant"},{"location":"apis/smart-contracts/ClaimSetupManager/#md_onlyaddressupdater","text":"Defined in AddressUpdatable ( Docs , Source ). modifier onlyAddressUpdater () Only the AdressUpdater contract can call this method. Its address is set at construction time but it can also update itself.","title":"onlyAddressUpdater"},{"location":"apis/smart-contracts/ClaimSetupManager/#md_onlygovernance","text":"Defined in GovernedBase ( Docs , Source ). modifier onlyGovernance ()","title":"onlyGovernance"},{"location":"apis/smart-contracts/ClaimSetupManager/#md_onlyimmediategovernance","text":"Defined in GovernedBase ( Docs , Source ). modifier onlyImmediateGovernance ()","title":"onlyImmediateGovernance"},{"location":"apis/smart-contracts/ClaimSetupManager/#md_onlyownerorexecutor","text":"Defined in ClaimSetupManager ( Docs , Source ). modifier onlyOwnerOrExecutor ( address _executor , address [] _owners )","title":"onlyOwnerOrExecutor"},{"location":"apis/smart-contracts/ClaimSetupManager/#structures","text":"","title":"Structures"},{"location":"apis/smart-contracts/ClaimSetupManager/#st_delegationaccountdata","text":"Defined in ClaimSetupManager ( Docs , Source ). struct DelegationAccountData { contract IIDelegationAccount delegationAccount ; bool enabled ; }","title":"DelegationAccountData"},{"location":"apis/smart-contracts/ClaimSetupManager/#st_executorfee","text":"Defined in ClaimSetupManager ( Docs , Source ). struct ExecutorFee { uint256 value ; uint256 validFromEpoch ; }","title":"ExecutorFee"},{"location":"apis/smart-contracts/ClaimSetupManager/#st_timelockedcall","text":"Defined in GovernedBase ( Docs , Source ). struct TimelockedCall { uint256 allowedAfterTimestamp ; bytes encodedCall ; }","title":"TimelockedCall"},{"location":"apis/smart-contracts/ClaimSetupManager/#variables","text":"","title":"Variables"},{"location":"apis/smart-contracts/ClaimSetupManager/#va_feevalueupdateoffset","text":"Defined in ClaimSetupManager ( Docs , Source ). uint256 feeValueUpdateOffset Number of reward epochs that must elapse before an executor's fee change takes effect.","title":"feeValueUpdateOffset"},{"location":"apis/smart-contracts/ClaimSetupManager/#va_ftsomanager","text":"Defined in ClaimSetupManager ( Docs , Source ). contract IFtsoManager ftsoManager The FtsoManager contract.","title":"ftsoManager"},{"location":"apis/smart-contracts/ClaimSetupManager/#va_governancesettings","text":"Defined in GovernedBase ( Docs , Source ). contract IGovernanceSettings governanceSettings Governance Settings.","title":"governanceSettings"},{"location":"apis/smart-contracts/ClaimSetupManager/#va_governancevp","text":"Defined in ClaimSetupManager ( Docs , Source ). contract IGovernanceVotePower governanceVP The GovernanceVotePower contract.","title":"governanceVP"},{"location":"apis/smart-contracts/ClaimSetupManager/#va_libraryaddress","text":"Defined in ClaimSetupManager ( Docs , Source ). address libraryAddress","title":"libraryAddress"},{"location":"apis/smart-contracts/ClaimSetupManager/#va_maxfeevaluewei","text":"Defined in ClaimSetupManager ( Docs , Source ). uint256 maxFeeValueWei Maximum allowed value for an executor's fee.","title":"maxFeeValueWei"},{"location":"apis/smart-contracts/ClaimSetupManager/#va_minfeevaluewei","text":"Defined in ClaimSetupManager ( Docs , Source ). uint256 minFeeValueWei Minimum allowed value for an executor's fee.","title":"minFeeValueWei"},{"location":"apis/smart-contracts/ClaimSetupManager/#va_productionmode","text":"Defined in GovernedBase ( Docs , Source ). bool productionMode When true, governance is enabled and cannot be disabled. See switchToProductionMode .","title":"productionMode"},{"location":"apis/smart-contracts/ClaimSetupManager/#va_registerexecutorfeevaluewei","text":"Defined in ClaimSetupManager ( Docs , Source ). uint256 registerExecutorFeeValueWei Fee that must be paid to register an executor.","title":"registerExecutorFeeValueWei"},{"location":"apis/smart-contracts/ClaimSetupManager/#va_timelockedcalls","text":"Defined in GovernedBase ( Docs , Source ). mapping ( bytes4 => struct GovernedBase . TimelockedCall ) timelockedCalls List of pending timelocked governance calls.","title":"timelockedCalls"},{"location":"apis/smart-contracts/ClaimSetupManager/#va_wnat","text":"Defined in ClaimSetupManager ( Docs , Source ). contract WNat wNat The WNat contract.","title":"wNat"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/","text":"CleanupBlockNumberManager # Source | Inherits from Governed , AddressUpdatable Token history cleanup manager. Maintains the list of cleanable tokens for which history cleanup can be collectively executed. Events # CleanupBlockNumberSet # Defined in CleanupBlockNumberManager ( Docs , Source ). event CleanupBlockNumberSet ( contract IICleanable theContract , uint256 blockNumber , bool success ) Emitted when an attempt has been made to set the cleanup block number. Parameters Type Description theContract contract IICleanable The token contract address. blockNumber uint256 The block number being set. success bool Whether it succeeded or not. GovernanceCallTimelocked # Defined in GovernedBase ( Docs , Source ). event GovernanceCallTimelocked ( bytes4 selector , uint256 allowedAfterTimestamp , bytes encodedCall ) Emitted when a new governance call has been recorded and is now waiting for the time lock to expire. GovernanceInitialised # Defined in GovernedBase ( Docs , Source ). event GovernanceInitialised ( address initialGovernance ) Emitted when the governance address is initialized. This address will be used until production mode is entered (see GovernedProductionModeEntered ). At that point the governance address is taken from GovernanceSettings . GovernedProductionModeEntered # Defined in GovernedBase ( Docs , Source ). event GovernedProductionModeEntered ( address governanceSettings ) Emitted when governance is enabled and the governance address cannot be changed anymore (only through a network fork). RegistrationUpdated # Defined in CleanupBlockNumberManager ( Docs , Source ). event RegistrationUpdated ( contract IICleanable theContract , bool add ) Emitted when a new token has been registered to have its history managed by us, or an old one unregistered. Parameters Type Description theContract contract IICleanable The token contract address. add bool true is the token has been registered, false if unregistered. TimelockedGovernanceCallCanceled # Defined in GovernedBase ( Docs , Source ). event TimelockedGovernanceCallCanceled ( bytes4 selector , uint256 timestamp ) Emitted when a timelocked governance call is canceled before execution. TimelockedGovernanceCallExecuted # Defined in GovernedBase ( Docs , Source ). event TimelockedGovernanceCallExecuted ( bytes4 selector , uint256 timestamp ) Emitted when a timelocked governance call is executed. Functions # cancelGovernanceCall # Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector. constructor # Defined in CleanupBlockNumberManager ( Docs , Source ). constructor ( address _governance , address _addressUpdater , string _triggerContractName ) public ; Build a new instance. Parameters Type Description _governance address Contract address that can make governance calls. See Governed . _addressUpdater address Contract address that can update redeployable addresses. See AdressUpdatable . _triggerContractName string Contract name that can trigger history cleanups. executeGovernanceCall # Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored). getAddressUpdater # Defined in AddressUpdatable ( Docs , Source ). function getAddressUpdater ( ) public view returns ( address _addressUpdater ); Returns the configured address updater. Returns Type Description _addressUpdater address The AddresUpdater contract that can update our contract address list, as a response to a governance call. governance # Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address. registerToken # Defined in CleanupBlockNumberManager ( Docs , Source ). function registerToken ( contract IICleanable _cleanableToken ) external ; Register a token contract whose history cleanup index is to be managed. The registered contracts must allow calling setCleanupBlockNumber . Parameters Type Description _cleanableToken contract IICleanable The address of the contract to be managed. setCleanUpBlockNumber # Defined in CleanupBlockNumberManager ( Docs , Source ). function setCleanUpBlockNumber ( uint256 _blockNumber ) external ; Sets clean up block number on managed cleanable tokens. Parameters Type Description _blockNumber uint256 cleanup block number switchToProductionMode # Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered . unregisterToken # Defined in CleanupBlockNumberManager ( Docs , Source ). function unregisterToken ( contract IICleanable _cleanableToken ) external ; Unregister a token contract from history cleanup index management. Parameters Type Description _cleanableToken contract IICleanable The address of the contract to unregister. updateContractAddresses # Defined in AddressUpdatable ( Docs , Source ). function updateContractAddresses ( bytes32 [] _contractNameHashes , address [] _contractAddresses ) external ; External method called from AddressUpdater only. Modifiers # onlyAddressUpdater # Defined in AddressUpdatable ( Docs , Source ). modifier onlyAddressUpdater () Only the AdressUpdater contract can call this method. Its address is set at construction time but it can also update itself. onlyGovernance # Defined in GovernedBase ( Docs , Source ). modifier onlyGovernance () onlyImmediateGovernance # Defined in GovernedBase ( Docs , Source ). modifier onlyImmediateGovernance () onlyTrigger # Defined in CleanupBlockNumberManager ( Docs , Source ). modifier onlyTrigger () Only the trigger contract can call this method. This contract is set at construction time and updated through AddressUpdatable . Variables # governanceSettings # Defined in GovernedBase ( Docs , Source ). contract IGovernanceSettings governanceSettings Governance Settings. productionMode # Defined in GovernedBase ( Docs , Source ). bool productionMode When true, governance is enabled and cannot be disabled. See switchToProductionMode . registeredTokens # Defined in CleanupBlockNumberManager ( Docs , Source ). contract IICleanable [] registeredTokens Current list of token contracts being managed. timelockedCalls # Defined in GovernedBase ( Docs , Source ). mapping ( bytes4 => struct GovernedBase . TimelockedCall ) timelockedCalls List of pending timelocked governance calls. triggerContract # Defined in CleanupBlockNumberManager ( Docs , Source ). address triggerContract Address of the contract that can trigger a cleanup. triggerContractName # Defined in CleanupBlockNumberManager ( Docs , Source ). string triggerContractName Name of the contract that can trigger a cleanup. Needed to update the trigger contract address through the AddressUpdater .","title":"CleanupBlockNumberManager"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#ct_cleanupblocknumbermanager","text":"Source | Inherits from Governed , AddressUpdatable Token history cleanup manager. Maintains the list of cleanable tokens for which history cleanup can be collectively executed.","title":"CleanupBlockNumberManager"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#events","text":"","title":"Events"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#ev_cleanupblocknumberset","text":"Defined in CleanupBlockNumberManager ( Docs , Source ). event CleanupBlockNumberSet ( contract IICleanable theContract , uint256 blockNumber , bool success ) Emitted when an attempt has been made to set the cleanup block number. Parameters Type Description theContract contract IICleanable The token contract address. blockNumber uint256 The block number being set. success bool Whether it succeeded or not.","title":"CleanupBlockNumberSet"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#ev_governancecalltimelocked","text":"Defined in GovernedBase ( Docs , Source ). event GovernanceCallTimelocked ( bytes4 selector , uint256 allowedAfterTimestamp , bytes encodedCall ) Emitted when a new governance call has been recorded and is now waiting for the time lock to expire.","title":"GovernanceCallTimelocked"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#ev_governanceinitialised","text":"Defined in GovernedBase ( Docs , Source ). event GovernanceInitialised ( address initialGovernance ) Emitted when the governance address is initialized. This address will be used until production mode is entered (see GovernedProductionModeEntered ). At that point the governance address is taken from GovernanceSettings .","title":"GovernanceInitialised"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#ev_governedproductionmodeentered","text":"Defined in GovernedBase ( Docs , Source ). event GovernedProductionModeEntered ( address governanceSettings ) Emitted when governance is enabled and the governance address cannot be changed anymore (only through a network fork).","title":"GovernedProductionModeEntered"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#ev_registrationupdated","text":"Defined in CleanupBlockNumberManager ( Docs , Source ). event RegistrationUpdated ( contract IICleanable theContract , bool add ) Emitted when a new token has been registered to have its history managed by us, or an old one unregistered. Parameters Type Description theContract contract IICleanable The token contract address. add bool true is the token has been registered, false if unregistered.","title":"RegistrationUpdated"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#ev_timelockedgovernancecallcanceled","text":"Defined in GovernedBase ( Docs , Source ). event TimelockedGovernanceCallCanceled ( bytes4 selector , uint256 timestamp ) Emitted when a timelocked governance call is canceled before execution.","title":"TimelockedGovernanceCallCanceled"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#ev_timelockedgovernancecallexecuted","text":"Defined in GovernedBase ( Docs , Source ). event TimelockedGovernanceCallExecuted ( bytes4 selector , uint256 timestamp ) Emitted when a timelocked governance call is executed.","title":"TimelockedGovernanceCallExecuted"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#fn_cancelgovernancecall_67fc4029","text":"Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector.","title":"cancelGovernanceCall"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#fn_constructor_undefined","text":"Defined in CleanupBlockNumberManager ( Docs , Source ). constructor ( address _governance , address _addressUpdater , string _triggerContractName ) public ; Build a new instance. Parameters Type Description _governance address Contract address that can make governance calls. See Governed . _addressUpdater address Contract address that can update redeployable addresses. See AdressUpdatable . _triggerContractName string Contract name that can trigger history cleanups.","title":"constructor"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#fn_executegovernancecall_5ff27079","text":"Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored).","title":"executeGovernanceCall"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#fn_getaddressupdater_5267a15d","text":"Defined in AddressUpdatable ( Docs , Source ). function getAddressUpdater ( ) public view returns ( address _addressUpdater ); Returns the configured address updater. Returns Type Description _addressUpdater address The AddresUpdater contract that can update our contract address list, as a response to a governance call.","title":"getAddressUpdater"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#fn_governance_5aa6e675","text":"Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address.","title":"governance"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#fn_registertoken_09824a80","text":"Defined in CleanupBlockNumberManager ( Docs , Source ). function registerToken ( contract IICleanable _cleanableToken ) external ; Register a token contract whose history cleanup index is to be managed. The registered contracts must allow calling setCleanupBlockNumber . Parameters Type Description _cleanableToken contract IICleanable The address of the contract to be managed.","title":"registerToken"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#fn_setcleanupblocknumber_cbc31cf7","text":"Defined in CleanupBlockNumberManager ( Docs , Source ). function setCleanUpBlockNumber ( uint256 _blockNumber ) external ; Sets clean up block number on managed cleanable tokens. Parameters Type Description _blockNumber uint256 cleanup block number","title":"setCleanUpBlockNumber"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#fn_switchtoproductionmode_f5a98383","text":"Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered .","title":"switchToProductionMode"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#fn_unregistertoken_77860cdd","text":"Defined in CleanupBlockNumberManager ( Docs , Source ). function unregisterToken ( contract IICleanable _cleanableToken ) external ; Unregister a token contract from history cleanup index management. Parameters Type Description _cleanableToken contract IICleanable The address of the contract to unregister.","title":"unregisterToken"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#fn_updatecontractaddresses_b00c0b76","text":"Defined in AddressUpdatable ( Docs , Source ). function updateContractAddresses ( bytes32 [] _contractNameHashes , address [] _contractAddresses ) external ; External method called from AddressUpdater only.","title":"updateContractAddresses"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#modifiers","text":"","title":"Modifiers"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#md_onlyaddressupdater","text":"Defined in AddressUpdatable ( Docs , Source ). modifier onlyAddressUpdater () Only the AdressUpdater contract can call this method. Its address is set at construction time but it can also update itself.","title":"onlyAddressUpdater"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#md_onlygovernance","text":"Defined in GovernedBase ( Docs , Source ). modifier onlyGovernance ()","title":"onlyGovernance"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#md_onlyimmediategovernance","text":"Defined in GovernedBase ( Docs , Source ). modifier onlyImmediateGovernance ()","title":"onlyImmediateGovernance"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#md_onlytrigger","text":"Defined in CleanupBlockNumberManager ( Docs , Source ). modifier onlyTrigger () Only the trigger contract can call this method. This contract is set at construction time and updated through AddressUpdatable .","title":"onlyTrigger"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#variables","text":"","title":"Variables"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#va_governancesettings","text":"Defined in GovernedBase ( Docs , Source ). contract IGovernanceSettings governanceSettings Governance Settings.","title":"governanceSettings"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#va_productionmode","text":"Defined in GovernedBase ( Docs , Source ). bool productionMode When true, governance is enabled and cannot be disabled. See switchToProductionMode .","title":"productionMode"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#va_registeredtokens","text":"Defined in CleanupBlockNumberManager ( Docs , Source ). contract IICleanable [] registeredTokens Current list of token contracts being managed.","title":"registeredTokens"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#va_timelockedcalls","text":"Defined in GovernedBase ( Docs , Source ). mapping ( bytes4 => struct GovernedBase . TimelockedCall ) timelockedCalls List of pending timelocked governance calls.","title":"timelockedCalls"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#va_triggercontract","text":"Defined in CleanupBlockNumberManager ( Docs , Source ). address triggerContract Address of the contract that can trigger a cleanup.","title":"triggerContract"},{"location":"apis/smart-contracts/CleanupBlockNumberManager/#va_triggercontractname","text":"Defined in CleanupBlockNumberManager ( Docs , Source ). string triggerContractName Name of the contract that can trigger a cleanup. Needed to update the trigger contract address through the AddressUpdater .","title":"triggerContractName"},{"location":"apis/smart-contracts/CloneFactory/","text":"CloneFactory # Source Simple clone contract factory. This code (intended to be called from an implementor factory contract) will allow you to install a master copy of a contract, then easily (cheaply) create clones with separate state. The deployed bytecode just delegates all calls to the master contract address. Source attribution . Functions #","title":"CloneFactory"},{"location":"apis/smart-contracts/CloneFactory/#ct_clonefactory","text":"Source Simple clone contract factory. This code (intended to be called from an implementor factory contract) will allow you to install a master copy of a contract, then easily (cheaply) create clones with separate state. The deployed bytecode just delegates all calls to the master contract address. Source attribution .","title":"CloneFactory"},{"location":"apis/smart-contracts/CloneFactory/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/Delegatable/","text":"Delegatable # Source | Inherits from IVPContractEvents Delegatable ERC20 behavior. Adds delegation capabilities to tokens. This contract orchestrates interaction between managing a delegation and the vote power allocations that result. Enums # DelegationMode # Defined in Delegatable ( Docs , Source ). enum DelegationMode { NOTSET , PERCENTAGE , AMOUNT } Delegation mode of an account. Once set, it cannot be changed. NOTSET : Delegation mode not set yet. PERCENTAGE : Delegation by percentage. AMOUNT : Delegation by amount (explicit). Events # CreatedVotePowerCache # Defined in Delegatable ( Docs , Source ). event CreatedVotePowerCache ( address _owner , uint256 _blockNumber ) Emitted when a vote power cache entry is created. Allows history cleaners to track vote power cache cleanup opportunities off-chain. Parameters Type Description _owner address The address whose vote power has just been cached. _blockNumber uint256 The block number at which the vote power has been cached. Delegate # Defined in IVPContractEvents ( Docs , Source ). event Delegate ( address from , address to , uint256 priorVotePower , uint256 newVotePower ) Emitted when the amount of vote power delegated from one account to another changes. Note : This event is always emitted from VPToken 's writeVotePowerContract . Parameters Type Description from address The account that has changed the amount of vote power it is delegating. to address The account whose received vote power has changed. priorVotePower uint256 The vote power originally delegated. newVotePower uint256 The new vote power that triggered this event. It can be 0 if the delegation is completely canceled. Revoke # Defined in IVPContractEvents ( Docs , Source ). event Revoke ( address delegator , address delegatee , uint256 votePower , uint256 blockNumber ) Emitted when an account revokes its vote power delegation to another account for a single current or past block (typically the current vote block). Note : This event is always emitted from VPToken 's writeVotePowerContract or readVotePowerContract . See revokeDelegationAt in IVPToken . Parameters Type Description delegator address The account that revoked the delegation. delegatee address The account that has been revoked. votePower uint256 The revoked vote power. blockNumber uint256 The block number at which the delegation has been revoked. Functions # explicitDelegationHistoryCleanup # Defined in Delegatable ( Docs , Source ). function explicitDelegationHistoryCleanup ( address _from , address _to , uint256 _count ) external returns ( uint256 ); Delete explicit delegation checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _from address Delegator address. _to address Delegatee address. _count uint256 Maximum number of checkpoints to delete. Returns Type Description [0] uint256 Number of checkpoints deleted. percentageDelegationHistoryCleanup # Defined in Delegatable ( Docs , Source ). function percentageDelegationHistoryCleanup ( address _owner , uint256 _count ) external returns ( uint256 ); Delete percentage delegation checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _owner address Balance owner account address. _count uint256 Maximum number of checkpoints to delete. Returns Type Description [0] uint256 Number of deleted checkpoints. revocationCleanup # Defined in Delegatable ( Docs , Source ). function revocationCleanup ( address _from , address _to , uint256 _blockNumber ) external returns ( uint256 ); Delete revocation entry that expired (i.e. is before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _from address Delegator address. _to address Delegatee address. _blockNumber uint256 Block number for which total supply value was cached. Returns Type Description [0] uint256 Number of revocation entries deleted (always 0 or 1). votePowerCacheCleanup # Defined in Delegatable ( Docs , Source ). function votePowerCacheCleanup ( address _owner , uint256 _blockNumber ) external returns ( uint256 ); Delete vote power cache entry that expired (i.e. is before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _owner address Vote power owner account address. _blockNumber uint256 Block number for which total supply value was cached. Returns Type Description [0] uint256 Number of deleted cache entries (always 0 or 1). votePowerHistoryCleanup # Defined in Delegatable ( Docs , Source ). function votePowerHistoryCleanup ( address _owner , uint256 _count ) external returns ( uint256 ); Delete vote power checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _owner address Vote power owner account address. _count uint256 Maximum number of checkpoints to delete. Returns Type Description [0] uint256 Number of deleted checkpoints. Modifiers # notBeforeCleanupBlock # Defined in Delegatable ( Docs , Source ). modifier notBeforeCleanupBlock ( uint256 _blockNumber ) Reading from history is not allowed before cleanupBlockNumber , since data before that might have been deleted and is thus unreliable. Parameters Type Description _blockNumber uint256 The block number being checked for validity. onlyCleaner # Defined in Delegatable ( Docs , Source ). modifier onlyCleaner () History cleaning methods can be called only from cleanerContract . Variables # cleanerContract # Defined in Delegatable ( Docs , Source ). address cleanerContract Address of the contract that is allowed to call methods for history cleaning.","title":"Delegatable"},{"location":"apis/smart-contracts/Delegatable/#ct_delegatable","text":"Source | Inherits from IVPContractEvents Delegatable ERC20 behavior. Adds delegation capabilities to tokens. This contract orchestrates interaction between managing a delegation and the vote power allocations that result.","title":"Delegatable"},{"location":"apis/smart-contracts/Delegatable/#enums","text":"","title":"Enums"},{"location":"apis/smart-contracts/Delegatable/#en_delegationmode","text":"Defined in Delegatable ( Docs , Source ). enum DelegationMode { NOTSET , PERCENTAGE , AMOUNT } Delegation mode of an account. Once set, it cannot be changed. NOTSET : Delegation mode not set yet. PERCENTAGE : Delegation by percentage. AMOUNT : Delegation by amount (explicit).","title":"DelegationMode"},{"location":"apis/smart-contracts/Delegatable/#events","text":"","title":"Events"},{"location":"apis/smart-contracts/Delegatable/#ev_createdvotepowercache","text":"Defined in Delegatable ( Docs , Source ). event CreatedVotePowerCache ( address _owner , uint256 _blockNumber ) Emitted when a vote power cache entry is created. Allows history cleaners to track vote power cache cleanup opportunities off-chain. Parameters Type Description _owner address The address whose vote power has just been cached. _blockNumber uint256 The block number at which the vote power has been cached.","title":"CreatedVotePowerCache"},{"location":"apis/smart-contracts/Delegatable/#ev_delegate","text":"Defined in IVPContractEvents ( Docs , Source ). event Delegate ( address from , address to , uint256 priorVotePower , uint256 newVotePower ) Emitted when the amount of vote power delegated from one account to another changes. Note : This event is always emitted from VPToken 's writeVotePowerContract . Parameters Type Description from address The account that has changed the amount of vote power it is delegating. to address The account whose received vote power has changed. priorVotePower uint256 The vote power originally delegated. newVotePower uint256 The new vote power that triggered this event. It can be 0 if the delegation is completely canceled.","title":"Delegate"},{"location":"apis/smart-contracts/Delegatable/#ev_revoke","text":"Defined in IVPContractEvents ( Docs , Source ). event Revoke ( address delegator , address delegatee , uint256 votePower , uint256 blockNumber ) Emitted when an account revokes its vote power delegation to another account for a single current or past block (typically the current vote block). Note : This event is always emitted from VPToken 's writeVotePowerContract or readVotePowerContract . See revokeDelegationAt in IVPToken . Parameters Type Description delegator address The account that revoked the delegation. delegatee address The account that has been revoked. votePower uint256 The revoked vote power. blockNumber uint256 The block number at which the delegation has been revoked.","title":"Revoke"},{"location":"apis/smart-contracts/Delegatable/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/Delegatable/#fn_explicitdelegationhistorycleanup_cabc4528","text":"Defined in Delegatable ( Docs , Source ). function explicitDelegationHistoryCleanup ( address _from , address _to , uint256 _count ) external returns ( uint256 ); Delete explicit delegation checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _from address Delegator address. _to address Delegatee address. _count uint256 Maximum number of checkpoints to delete. Returns Type Description [0] uint256 Number of checkpoints deleted.","title":"explicitDelegationHistoryCleanup"},{"location":"apis/smart-contracts/Delegatable/#fn_percentagedelegationhistorycleanup_7f57d58f","text":"Defined in Delegatable ( Docs , Source ). function percentageDelegationHistoryCleanup ( address _owner , uint256 _count ) external returns ( uint256 ); Delete percentage delegation checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _owner address Balance owner account address. _count uint256 Maximum number of checkpoints to delete. Returns Type Description [0] uint256 Number of deleted checkpoints.","title":"percentageDelegationHistoryCleanup"},{"location":"apis/smart-contracts/Delegatable/#fn_revocationcleanup_8c0b6b40","text":"Defined in Delegatable ( Docs , Source ). function revocationCleanup ( address _from , address _to , uint256 _blockNumber ) external returns ( uint256 ); Delete revocation entry that expired (i.e. is before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _from address Delegator address. _to address Delegatee address. _blockNumber uint256 Block number for which total supply value was cached. Returns Type Description [0] uint256 Number of revocation entries deleted (always 0 or 1).","title":"revocationCleanup"},{"location":"apis/smart-contracts/Delegatable/#fn_votepowercachecleanup_891339a8","text":"Defined in Delegatable ( Docs , Source ). function votePowerCacheCleanup ( address _owner , uint256 _blockNumber ) external returns ( uint256 ); Delete vote power cache entry that expired (i.e. is before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _owner address Vote power owner account address. _blockNumber uint256 Block number for which total supply value was cached. Returns Type Description [0] uint256 Number of deleted cache entries (always 0 or 1).","title":"votePowerCacheCleanup"},{"location":"apis/smart-contracts/Delegatable/#fn_votepowerhistorycleanup_1a05274c","text":"Defined in Delegatable ( Docs , Source ). function votePowerHistoryCleanup ( address _owner , uint256 _count ) external returns ( uint256 ); Delete vote power checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _owner address Vote power owner account address. _count uint256 Maximum number of checkpoints to delete. Returns Type Description [0] uint256 Number of deleted checkpoints.","title":"votePowerHistoryCleanup"},{"location":"apis/smart-contracts/Delegatable/#modifiers","text":"","title":"Modifiers"},{"location":"apis/smart-contracts/Delegatable/#md_notbeforecleanupblock","text":"Defined in Delegatable ( Docs , Source ). modifier notBeforeCleanupBlock ( uint256 _blockNumber ) Reading from history is not allowed before cleanupBlockNumber , since data before that might have been deleted and is thus unreliable. Parameters Type Description _blockNumber uint256 The block number being checked for validity.","title":"notBeforeCleanupBlock"},{"location":"apis/smart-contracts/Delegatable/#md_onlycleaner","text":"Defined in Delegatable ( Docs , Source ). modifier onlyCleaner () History cleaning methods can be called only from cleanerContract .","title":"onlyCleaner"},{"location":"apis/smart-contracts/Delegatable/#variables","text":"","title":"Variables"},{"location":"apis/smart-contracts/Delegatable/#va_cleanercontract","text":"Defined in Delegatable ( Docs , Source ). address cleanerContract Address of the contract that is allowed to call methods for history cleaning.","title":"cleanerContract"},{"location":"apis/smart-contracts/FlareContractRegistry/","text":"FlareContractRegistry # Source | Inherits from IFlareContractRegistry , AddressUpdatable The Flare contract registry. Entry point for all external dapps that need the latest contract addresses deployed by Flare. Functions # constructor # Defined in FlareContractRegistry ( Docs , Source ). constructor ( address _addressUpdater ) public ; getAddressUpdater # Defined in AddressUpdatable ( Docs , Source ). function getAddressUpdater ( ) public view returns ( address _addressUpdater ); Returns the configured address updater. Returns Type Description _addressUpdater address The AddresUpdater contract that can update our contract address list, as a response to a governance call. getAllContracts # Defined in FlareContractRegistry ( Docs , Source ). function getAllContracts ( ) external view returns ( string [] _names , address [] _addresses ); Returns all contract names and their corresponding addresses. Returns Type Description _names string[] Array of contract names. _addresses address[] Array of corresponding contract addresses. getContractAddressByHash # Defined in FlareContractRegistry ( Docs , Source ). function getContractAddressByHash ( bytes32 _nameHash ) external view returns ( address ); Returns the address of a given contract hash. Parameters Type Description _nameHash bytes32 Hash of the contract name as: keccak256(abi.encode(name)) . Returns Type Description [0] address Address of the contract, or address(0) if not found. getContractAddressByName # Defined in FlareContractRegistry ( Docs , Source ). function getContractAddressByName ( string _name ) external view returns ( address ); Returns the address of a given contract name. Parameters Type Description _name string Name of the contract. Returns Type Description [0] address Address of the contract, or address(0) if not found. getContractAddressesByHash # Defined in FlareContractRegistry ( Docs , Source ). function getContractAddressesByHash ( bytes32 [] _nameHashes ) external view returns ( address []); Returns the addresses of a list of contract hashes. Parameters Type Description _nameHashes bytes32[] Array of contract name hashes as: keccak256(abi.encode(name)) . Returns Type Description [0] address[] Array of addresses of the contracts. Any of them might be address(0) if not found. getContractAddressesByName # Defined in FlareContractRegistry ( Docs , Source ). function getContractAddressesByName ( string [] _names ) external view returns ( address []); Returns the addresses of a list of contract names. Parameters Type Description _names string[] Array of contract names. Returns Type Description [0] address[] Array of addresses of the contracts. Any of them might be address(0) if not found. updateContractAddresses # Defined in AddressUpdatable ( Docs , Source ). function updateContractAddresses ( bytes32 [] _contractNameHashes , address [] _contractAddresses ) external ; External method called from AddressUpdater only.","title":"FlareContractRegistry"},{"location":"apis/smart-contracts/FlareContractRegistry/#ct_flarecontractregistry","text":"Source | Inherits from IFlareContractRegistry , AddressUpdatable The Flare contract registry. Entry point for all external dapps that need the latest contract addresses deployed by Flare.","title":"FlareContractRegistry"},{"location":"apis/smart-contracts/FlareContractRegistry/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/FlareContractRegistry/#fn_constructor_undefined","text":"Defined in FlareContractRegistry ( Docs , Source ). constructor ( address _addressUpdater ) public ;","title":"constructor"},{"location":"apis/smart-contracts/FlareContractRegistry/#fn_getaddressupdater_5267a15d","text":"Defined in AddressUpdatable ( Docs , Source ). function getAddressUpdater ( ) public view returns ( address _addressUpdater ); Returns the configured address updater. Returns Type Description _addressUpdater address The AddresUpdater contract that can update our contract address list, as a response to a governance call.","title":"getAddressUpdater"},{"location":"apis/smart-contracts/FlareContractRegistry/#fn_getallcontracts_18d3ce96","text":"Defined in FlareContractRegistry ( Docs , Source ). function getAllContracts ( ) external view returns ( string [] _names , address [] _addresses ); Returns all contract names and their corresponding addresses. Returns Type Description _names string[] Array of contract names. _addresses address[] Array of corresponding contract addresses.","title":"getAllContracts"},{"location":"apis/smart-contracts/FlareContractRegistry/#fn_getcontractaddressbyhash_159354a2","text":"Defined in FlareContractRegistry ( Docs , Source ). function getContractAddressByHash ( bytes32 _nameHash ) external view returns ( address ); Returns the address of a given contract hash. Parameters Type Description _nameHash bytes32 Hash of the contract name as: keccak256(abi.encode(name)) . Returns Type Description [0] address Address of the contract, or address(0) if not found.","title":"getContractAddressByHash"},{"location":"apis/smart-contracts/FlareContractRegistry/#fn_getcontractaddressbyname_82760fca","text":"Defined in FlareContractRegistry ( Docs , Source ). function getContractAddressByName ( string _name ) external view returns ( address ); Returns the address of a given contract name. Parameters Type Description _name string Name of the contract. Returns Type Description [0] address Address of the contract, or address(0) if not found.","title":"getContractAddressByName"},{"location":"apis/smart-contracts/FlareContractRegistry/#fn_getcontractaddressesbyhash_5e11e2d1","text":"Defined in FlareContractRegistry ( Docs , Source ). function getContractAddressesByHash ( bytes32 [] _nameHashes ) external view returns ( address []); Returns the addresses of a list of contract hashes. Parameters Type Description _nameHashes bytes32[] Array of contract name hashes as: keccak256(abi.encode(name)) . Returns Type Description [0] address[] Array of addresses of the contracts. Any of them might be address(0) if not found.","title":"getContractAddressesByHash"},{"location":"apis/smart-contracts/FlareContractRegistry/#fn_getcontractaddressesbyname_76d2b1af","text":"Defined in FlareContractRegistry ( Docs , Source ). function getContractAddressesByName ( string [] _names ) external view returns ( address []); Returns the addresses of a list of contract names. Parameters Type Description _names string[] Array of contract names. Returns Type Description [0] address[] Array of addresses of the contracts. Any of them might be address(0) if not found.","title":"getContractAddressesByName"},{"location":"apis/smart-contracts/FlareContractRegistry/#fn_updatecontractaddresses_b00c0b76","text":"Defined in AddressUpdatable ( Docs , Source ). function updateContractAddresses ( bytes32 [] _contractNameHashes , address [] _contractAddresses ) external ; External method called from AddressUpdater only.","title":"updateContractAddresses"},{"location":"apis/smart-contracts/FlareDaemon/","text":"FlareDaemon # Source | Inherits from GovernedAtGenesis , AddressUpdatable Flare Daemon contract. This contract exists to coordinate regular daemon-like polling of contracts that are registered to receive said polling. The trigger method is called by the validator right at the end of block state transition. Events # ContractDaemonizeErrored # Defined in FlareDaemon ( Docs , Source ). event ContractDaemonizeErrored ( address theContract , uint256 atBlock , string theMessage , uint256 gasConsumed ) ContractDaemonized # Defined in FlareDaemon ( Docs , Source ). event ContractDaemonized ( address theContract , uint256 gasConsumed ) ContractHeldOff # Defined in FlareDaemon ( Docs , Source ). event ContractHeldOff ( address theContract , uint256 blockHoldoffsRemaining ) ContractsSkippedOutOfGas # Defined in FlareDaemon ( Docs , Source ). event ContractsSkippedOutOfGas ( uint256 numberOfSkippedConstracts ) GovernanceCallTimelocked # Defined in GovernedBase ( Docs , Source ). event GovernanceCallTimelocked ( bytes4 selector , uint256 allowedAfterTimestamp , bytes encodedCall ) Emitted when a new governance call has been recorded and is now waiting for the time lock to expire. GovernanceInitialised # Defined in GovernedBase ( Docs , Source ). event GovernanceInitialised ( address initialGovernance ) Emitted when the governance address is initialized. This address will be used until production mode is entered (see GovernedProductionModeEntered ). At that point the governance address is taken from GovernanceSettings . GovernedProductionModeEntered # Defined in GovernedBase ( Docs , Source ). event GovernedProductionModeEntered ( address governanceSettings ) Emitted when governance is enabled and the governance address cannot be changed anymore (only through a network fork). InflationSet # Defined in FlareDaemon ( Docs , Source ). event InflationSet ( contract IInflationGenesis theNewContract , contract IInflationGenesis theOldContract ) MintingReceived # Defined in FlareDaemon ( Docs , Source ). event MintingReceived ( uint256 amountWei ) MintingRequestReceived # Defined in FlareDaemon ( Docs , Source ). event MintingRequestReceived ( uint256 amountWei ) MintingRequestTriggered # Defined in FlareDaemon ( Docs , Source ). event MintingRequestTriggered ( uint256 amountWei ) MintingWithdrawn # Defined in FlareDaemon ( Docs , Source ). event MintingWithdrawn ( uint256 amountWei ) RegistrationUpdated # Defined in FlareDaemon ( Docs , Source ). event RegistrationUpdated ( contract IFlareDaemonize theContract , bool add ) SelfDestructReceived # Defined in FlareDaemon ( Docs , Source ). event SelfDestructReceived ( uint256 amountWei ) TimelockedGovernanceCallCanceled # Defined in GovernedBase ( Docs , Source ). event TimelockedGovernanceCallCanceled ( bytes4 selector , uint256 timestamp ) Emitted when a timelocked governance call is canceled before execution. TimelockedGovernanceCallExecuted # Defined in GovernedBase ( Docs , Source ). event TimelockedGovernanceCallExecuted ( bytes4 selector , uint256 timestamp ) Emitted when a timelocked governance call is executed. Functions # cancelGovernanceCall # Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector. constructor # Defined in FlareDaemon ( Docs , Source ). constructor ( ) public ; This constructor should contain no code as this contract is pre-loaded into the genesis block. The super constructor is called for testing convenience. executeGovernanceCall # Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored). getAddressUpdater # Defined in AddressUpdatable ( Docs , Source ). function getAddressUpdater ( ) public view returns ( address _addressUpdater ); Returns the configured address updater. Returns Type Description _addressUpdater address The AddresUpdater contract that can update our contract address list, as a response to a governance call. getDaemonizedContractsData # Defined in FlareDaemon ( Docs , Source ). function getDaemonizedContractsData ( ) external view returns ( contract IFlareDaemonize [] _daemonizeContracts , uint256 [] _gasLimits , uint256 [] _blockHoldoffsRemaining ); getNextMintRequestAllowedTs # Defined in FlareDaemon ( Docs , Source ). function getNextMintRequestAllowedTs ( ) external view returns ( uint256 ); governance # Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address. initialise # Defined in GovernedAtGenesis ( Docs , Source ). function initialise ( address _governance ) public pure ; Disallow initialise to be called. Parameters Type Description _governance address The governance address for initial claiming. initialiseFixedAddress # Defined in FlareDaemon ( Docs , Source ). function initialiseFixedAddress ( ) public returns ( address ); Set the governance address to a hard-coded known address. This should be done at contract deployment time. Returns Type Description [0] address The governance address. registerToDaemonize # Defined in FlareDaemon ( Docs , Source ). function registerToDaemonize ( struct FlareDaemon . Registration [] _registrations ) external ; Register contracts to be polled by the daemon process. A gas limit of zero will set no limit for the contract but the validator has an overall limit for the trigger method. If any registrations already exist, they will be unregistered. Contracts will be daemonized in the order in which presented via the _registrations array. Parameters Type Description _registrations struct FlareDaemon.Registration[] An array of Registration structures of IFlareDaemonize contracts to daemonize and gas limits for each contract. requestMinting # Defined in FlareDaemon ( Docs , Source ). function requestMinting ( uint256 _amountWei ) external ; Queue up a minting request to send to the validator at next trigger . Parameters Type Description _amountWei uint256 The amount to mint. setAddressUpdater # Defined in FlareDaemon ( Docs , Source ). function setAddressUpdater ( address _addressUpdater ) external ; Sets the address udpater contract. Parameters Type Description _addressUpdater address The address updater contract. setBlockHoldoff # Defined in FlareDaemon ( Docs , Source ). function setBlockHoldoff ( uint256 _blockHoldoff ) external ; Set number of blocks that must elapse before a daemonized contract exceeding gas limit can have its daemonize() method called again. Parameters Type Description _blockHoldoff uint256 The number of blocks to holdoff. setMaxMintingRequest # Defined in FlareDaemon ( Docs , Source ). function setMaxMintingRequest ( uint256 _maxMintingRequestWei ) external ; Set limit on how much can be minted per request. this number can't be udated too often Parameters Type Description _maxMintingRequestWei uint256 The request maximum in wei. showDaemonizedErrors # Defined in FlareDaemon ( Docs , Source ). function showDaemonizedErrors ( uint256 startIndex , uint256 numErrorTypesToShow ) public view returns ( uint256 [] _lastErrorBlock , uint256 [] _numErrors , string [] _errorString , address [] _erroringContract , uint256 _totalDaemonizedErrors ); showLastDaemonizedError # Defined in FlareDaemon ( Docs , Source ). function showLastDaemonizedError ( ) external view returns ( uint256 [] _lastErrorBlock , uint256 [] _numErrors , string [] _errorString , address [] _erroringContract , uint256 _totalDaemonizedErrors ); switchToProductionMode # Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered . updateContractAddresses # Defined in AddressUpdatable ( Docs , Source ). function updateContractAddresses ( bytes32 [] _contractNameHashes , address [] _contractAddresses ) external ; External method called from AddressUpdater only. Modifiers # inflationSet # Defined in FlareDaemon ( Docs , Source ). modifier inflationSet () As there is not a constructor , this modifier exists to make sure the inflation contract is set for methods that require it. onlyAddressUpdater # Defined in AddressUpdatable ( Docs , Source ). modifier onlyAddressUpdater () Only the AdressUpdater contract can call this method. Its address is set at construction time but it can also update itself. onlyGovernance # Defined in GovernedBase ( Docs , Source ). modifier onlyGovernance () onlyImmediateGovernance # Defined in GovernedBase ( Docs , Source ). modifier onlyImmediateGovernance () onlyInflation # Defined in FlareDaemon ( Docs , Source ). modifier onlyInflation ( address _inflation ) Access control to protect methods to allow only minters to call select methods (like transferring balance out). onlySystemTrigger # Defined in FlareDaemon ( Docs , Source ). modifier onlySystemTrigger () Access control to protect trigger method. Please note that the sender address is the same as deployed FlareDaemon address in this case. Structures # DaemonizedError # Defined in FlareDaemon ( Docs , Source ). struct DaemonizedError { uint192 lastErrorBlock ; uint64 numErrors ; address fromContract ; uint64 errorTypeIndex ; string errorMessage ; } LastErrorData # Defined in FlareDaemon ( Docs , Source ). struct LastErrorData { uint192 totalDaemonizedErrors ; uint64 lastErrorTypeIndex ; } Registration # Defined in FlareDaemon ( Docs , Source ). struct Registration { contract IFlareDaemonize daemonizedContract ; uint256 gasLimit ; } TimelockedCall # Defined in GovernedBase ( Docs , Source ). struct TimelockedCall { uint256 allowedAfterTimestamp ; bytes encodedCall ; } Variables # blockHoldoff # Defined in FlareDaemon ( Docs , Source ). uint256 blockHoldoff errorData # Defined in FlareDaemon ( Docs , Source ). struct FlareDaemon . LastErrorData errorData governanceSettings # Defined in GovernedBase ( Docs , Source ). contract IGovernanceSettings governanceSettings Governance Settings. inflation # Defined in FlareDaemon ( Docs , Source ). contract IInflationGenesis inflation lastMintRequestTs # Defined in FlareDaemon ( Docs , Source ). uint256 lastMintRequestTs lastUpdateMaxMintRequestTs # Defined in FlareDaemon ( Docs , Source ). uint256 lastUpdateMaxMintRequestTs maxMintingRequestWei # Defined in FlareDaemon ( Docs , Source ). uint256 maxMintingRequestWei productionMode # Defined in GovernedBase ( Docs , Source ). bool productionMode When true, governance is enabled and cannot be disabled. See switchToProductionMode . systemLastTriggeredAt # Defined in FlareDaemon ( Docs , Source ). uint256 systemLastTriggeredAt timelockedCalls # Defined in GovernedBase ( Docs , Source ). mapping ( bytes4 => struct GovernedBase . TimelockedCall ) timelockedCalls List of pending timelocked governance calls. totalMintingReceivedWei # Defined in FlareDaemon ( Docs , Source ). uint256 totalMintingReceivedWei totalMintingRequestedWei # Defined in FlareDaemon ( Docs , Source ). uint256 totalMintingRequestedWei totalMintingWithdrawnWei # Defined in FlareDaemon ( Docs , Source ). uint256 totalMintingWithdrawnWei totalSelfDestructReceivedWei # Defined in FlareDaemon ( Docs , Source ). uint256 totalSelfDestructReceivedWei","title":"FlareDaemon"},{"location":"apis/smart-contracts/FlareDaemon/#ct_flaredaemon","text":"Source | Inherits from GovernedAtGenesis , AddressUpdatable Flare Daemon contract. This contract exists to coordinate regular daemon-like polling of contracts that are registered to receive said polling. The trigger method is called by the validator right at the end of block state transition.","title":"FlareDaemon"},{"location":"apis/smart-contracts/FlareDaemon/#events","text":"","title":"Events"},{"location":"apis/smart-contracts/FlareDaemon/#ev_contractdaemonizeerrored","text":"Defined in FlareDaemon ( Docs , Source ). event ContractDaemonizeErrored ( address theContract , uint256 atBlock , string theMessage , uint256 gasConsumed )","title":"ContractDaemonizeErrored"},{"location":"apis/smart-contracts/FlareDaemon/#ev_contractdaemonized","text":"Defined in FlareDaemon ( Docs , Source ). event ContractDaemonized ( address theContract , uint256 gasConsumed )","title":"ContractDaemonized"},{"location":"apis/smart-contracts/FlareDaemon/#ev_contractheldoff","text":"Defined in FlareDaemon ( Docs , Source ). event ContractHeldOff ( address theContract , uint256 blockHoldoffsRemaining )","title":"ContractHeldOff"},{"location":"apis/smart-contracts/FlareDaemon/#ev_contractsskippedoutofgas","text":"Defined in FlareDaemon ( Docs , Source ). event ContractsSkippedOutOfGas ( uint256 numberOfSkippedConstracts )","title":"ContractsSkippedOutOfGas"},{"location":"apis/smart-contracts/FlareDaemon/#ev_governancecalltimelocked","text":"Defined in GovernedBase ( Docs , Source ). event GovernanceCallTimelocked ( bytes4 selector , uint256 allowedAfterTimestamp , bytes encodedCall ) Emitted when a new governance call has been recorded and is now waiting for the time lock to expire.","title":"GovernanceCallTimelocked"},{"location":"apis/smart-contracts/FlareDaemon/#ev_governanceinitialised","text":"Defined in GovernedBase ( Docs , Source ). event GovernanceInitialised ( address initialGovernance ) Emitted when the governance address is initialized. This address will be used until production mode is entered (see GovernedProductionModeEntered ). At that point the governance address is taken from GovernanceSettings .","title":"GovernanceInitialised"},{"location":"apis/smart-contracts/FlareDaemon/#ev_governedproductionmodeentered","text":"Defined in GovernedBase ( Docs , Source ). event GovernedProductionModeEntered ( address governanceSettings ) Emitted when governance is enabled and the governance address cannot be changed anymore (only through a network fork).","title":"GovernedProductionModeEntered"},{"location":"apis/smart-contracts/FlareDaemon/#ev_inflationset","text":"Defined in FlareDaemon ( Docs , Source ). event InflationSet ( contract IInflationGenesis theNewContract , contract IInflationGenesis theOldContract )","title":"InflationSet"},{"location":"apis/smart-contracts/FlareDaemon/#ev_mintingreceived","text":"Defined in FlareDaemon ( Docs , Source ). event MintingReceived ( uint256 amountWei )","title":"MintingReceived"},{"location":"apis/smart-contracts/FlareDaemon/#ev_mintingrequestreceived","text":"Defined in FlareDaemon ( Docs , Source ). event MintingRequestReceived ( uint256 amountWei )","title":"MintingRequestReceived"},{"location":"apis/smart-contracts/FlareDaemon/#ev_mintingrequesttriggered","text":"Defined in FlareDaemon ( Docs , Source ). event MintingRequestTriggered ( uint256 amountWei )","title":"MintingRequestTriggered"},{"location":"apis/smart-contracts/FlareDaemon/#ev_mintingwithdrawn","text":"Defined in FlareDaemon ( Docs , Source ). event MintingWithdrawn ( uint256 amountWei )","title":"MintingWithdrawn"},{"location":"apis/smart-contracts/FlareDaemon/#ev_registrationupdated","text":"Defined in FlareDaemon ( Docs , Source ). event RegistrationUpdated ( contract IFlareDaemonize theContract , bool add )","title":"RegistrationUpdated"},{"location":"apis/smart-contracts/FlareDaemon/#ev_selfdestructreceived","text":"Defined in FlareDaemon ( Docs , Source ). event SelfDestructReceived ( uint256 amountWei )","title":"SelfDestructReceived"},{"location":"apis/smart-contracts/FlareDaemon/#ev_timelockedgovernancecallcanceled","text":"Defined in GovernedBase ( Docs , Source ). event TimelockedGovernanceCallCanceled ( bytes4 selector , uint256 timestamp ) Emitted when a timelocked governance call is canceled before execution.","title":"TimelockedGovernanceCallCanceled"},{"location":"apis/smart-contracts/FlareDaemon/#ev_timelockedgovernancecallexecuted","text":"Defined in GovernedBase ( Docs , Source ). event TimelockedGovernanceCallExecuted ( bytes4 selector , uint256 timestamp ) Emitted when a timelocked governance call is executed.","title":"TimelockedGovernanceCallExecuted"},{"location":"apis/smart-contracts/FlareDaemon/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/FlareDaemon/#fn_cancelgovernancecall_67fc4029","text":"Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector.","title":"cancelGovernanceCall"},{"location":"apis/smart-contracts/FlareDaemon/#fn_constructor_undefined","text":"Defined in FlareDaemon ( Docs , Source ). constructor ( ) public ; This constructor should contain no code as this contract is pre-loaded into the genesis block. The super constructor is called for testing convenience.","title":"constructor"},{"location":"apis/smart-contracts/FlareDaemon/#fn_executegovernancecall_5ff27079","text":"Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored).","title":"executeGovernanceCall"},{"location":"apis/smart-contracts/FlareDaemon/#fn_getaddressupdater_5267a15d","text":"Defined in AddressUpdatable ( Docs , Source ). function getAddressUpdater ( ) public view returns ( address _addressUpdater ); Returns the configured address updater. Returns Type Description _addressUpdater address The AddresUpdater contract that can update our contract address list, as a response to a governance call.","title":"getAddressUpdater"},{"location":"apis/smart-contracts/FlareDaemon/#fn_getdaemonizedcontractsdata_ed21b6e4","text":"Defined in FlareDaemon ( Docs , Source ). function getDaemonizedContractsData ( ) external view returns ( contract IFlareDaemonize [] _daemonizeContracts , uint256 [] _gasLimits , uint256 [] _blockHoldoffsRemaining );","title":"getDaemonizedContractsData"},{"location":"apis/smart-contracts/FlareDaemon/#fn_getnextmintrequestallowedts_63903143","text":"Defined in FlareDaemon ( Docs , Source ). function getNextMintRequestAllowedTs ( ) external view returns ( uint256 );","title":"getNextMintRequestAllowedTs"},{"location":"apis/smart-contracts/FlareDaemon/#fn_governance_5aa6e675","text":"Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address.","title":"governance"},{"location":"apis/smart-contracts/FlareDaemon/#fn_initialise_9d6a890f","text":"Defined in GovernedAtGenesis ( Docs , Source ). function initialise ( address _governance ) public pure ; Disallow initialise to be called. Parameters Type Description _governance address The governance address for initial claiming.","title":"initialise"},{"location":"apis/smart-contracts/FlareDaemon/#fn_initialisefixedaddress_c9f960eb","text":"Defined in FlareDaemon ( Docs , Source ). function initialiseFixedAddress ( ) public returns ( address ); Set the governance address to a hard-coded known address. This should be done at contract deployment time. Returns Type Description [0] address The governance address.","title":"initialiseFixedAddress"},{"location":"apis/smart-contracts/FlareDaemon/#fn_registertodaemonize_689c4999","text":"Defined in FlareDaemon ( Docs , Source ). function registerToDaemonize ( struct FlareDaemon . Registration [] _registrations ) external ; Register contracts to be polled by the daemon process. A gas limit of zero will set no limit for the contract but the validator has an overall limit for the trigger method. If any registrations already exist, they will be unregistered. Contracts will be daemonized in the order in which presented via the _registrations array. Parameters Type Description _registrations struct FlareDaemon.Registration[] An array of Registration structures of IFlareDaemonize contracts to daemonize and gas limits for each contract.","title":"registerToDaemonize"},{"location":"apis/smart-contracts/FlareDaemon/#fn_requestminting_e9de7d60","text":"Defined in FlareDaemon ( Docs , Source ). function requestMinting ( uint256 _amountWei ) external ; Queue up a minting request to send to the validator at next trigger . Parameters Type Description _amountWei uint256 The amount to mint.","title":"requestMinting"},{"location":"apis/smart-contracts/FlareDaemon/#fn_setaddressupdater_aea36b53","text":"Defined in FlareDaemon ( Docs , Source ). function setAddressUpdater ( address _addressUpdater ) external ; Sets the address udpater contract. Parameters Type Description _addressUpdater address The address updater contract.","title":"setAddressUpdater"},{"location":"apis/smart-contracts/FlareDaemon/#fn_setblockholdoff_5042916c","text":"Defined in FlareDaemon ( Docs , Source ). function setBlockHoldoff ( uint256 _blockHoldoff ) external ; Set number of blocks that must elapse before a daemonized contract exceeding gas limit can have its daemonize() method called again. Parameters Type Description _blockHoldoff uint256 The number of blocks to holdoff.","title":"setBlockHoldoff"},{"location":"apis/smart-contracts/FlareDaemon/#fn_setmaxmintingrequest_870196b8","text":"Defined in FlareDaemon ( Docs , Source ). function setMaxMintingRequest ( uint256 _maxMintingRequestWei ) external ; Set limit on how much can be minted per request. this number can't be udated too often Parameters Type Description _maxMintingRequestWei uint256 The request maximum in wei.","title":"setMaxMintingRequest"},{"location":"apis/smart-contracts/FlareDaemon/#fn_showdaemonizederrors_ecdda0dd","text":"Defined in FlareDaemon ( Docs , Source ). function showDaemonizedErrors ( uint256 startIndex , uint256 numErrorTypesToShow ) public view returns ( uint256 [] _lastErrorBlock , uint256 [] _numErrors , string [] _errorString , address [] _erroringContract , uint256 _totalDaemonizedErrors );","title":"showDaemonizedErrors"},{"location":"apis/smart-contracts/FlareDaemon/#fn_showlastdaemonizederror_63d4a53a","text":"Defined in FlareDaemon ( Docs , Source ). function showLastDaemonizedError ( ) external view returns ( uint256 [] _lastErrorBlock , uint256 [] _numErrors , string [] _errorString , address [] _erroringContract , uint256 _totalDaemonizedErrors );","title":"showLastDaemonizedError"},{"location":"apis/smart-contracts/FlareDaemon/#fn_switchtoproductionmode_f5a98383","text":"Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered .","title":"switchToProductionMode"},{"location":"apis/smart-contracts/FlareDaemon/#fn_updatecontractaddresses_b00c0b76","text":"Defined in AddressUpdatable ( Docs , Source ). function updateContractAddresses ( bytes32 [] _contractNameHashes , address [] _contractAddresses ) external ; External method called from AddressUpdater only.","title":"updateContractAddresses"},{"location":"apis/smart-contracts/FlareDaemon/#modifiers","text":"","title":"Modifiers"},{"location":"apis/smart-contracts/FlareDaemon/#md_inflationset","text":"Defined in FlareDaemon ( Docs , Source ). modifier inflationSet () As there is not a constructor , this modifier exists to make sure the inflation contract is set for methods that require it.","title":"inflationSet"},{"location":"apis/smart-contracts/FlareDaemon/#md_onlyaddressupdater","text":"Defined in AddressUpdatable ( Docs , Source ). modifier onlyAddressUpdater () Only the AdressUpdater contract can call this method. Its address is set at construction time but it can also update itself.","title":"onlyAddressUpdater"},{"location":"apis/smart-contracts/FlareDaemon/#md_onlygovernance","text":"Defined in GovernedBase ( Docs , Source ). modifier onlyGovernance ()","title":"onlyGovernance"},{"location":"apis/smart-contracts/FlareDaemon/#md_onlyimmediategovernance","text":"Defined in GovernedBase ( Docs , Source ). modifier onlyImmediateGovernance ()","title":"onlyImmediateGovernance"},{"location":"apis/smart-contracts/FlareDaemon/#md_onlyinflation","text":"Defined in FlareDaemon ( Docs , Source ). modifier onlyInflation ( address _inflation ) Access control to protect methods to allow only minters to call select methods (like transferring balance out).","title":"onlyInflation"},{"location":"apis/smart-contracts/FlareDaemon/#md_onlysystemtrigger","text":"Defined in FlareDaemon ( Docs , Source ). modifier onlySystemTrigger () Access control to protect trigger method. Please note that the sender address is the same as deployed FlareDaemon address in this case.","title":"onlySystemTrigger"},{"location":"apis/smart-contracts/FlareDaemon/#structures","text":"","title":"Structures"},{"location":"apis/smart-contracts/FlareDaemon/#st_daemonizederror","text":"Defined in FlareDaemon ( Docs , Source ). struct DaemonizedError { uint192 lastErrorBlock ; uint64 numErrors ; address fromContract ; uint64 errorTypeIndex ; string errorMessage ; }","title":"DaemonizedError"},{"location":"apis/smart-contracts/FlareDaemon/#st_lasterrordata","text":"Defined in FlareDaemon ( Docs , Source ). struct LastErrorData { uint192 totalDaemonizedErrors ; uint64 lastErrorTypeIndex ; }","title":"LastErrorData"},{"location":"apis/smart-contracts/FlareDaemon/#st_registration","text":"Defined in FlareDaemon ( Docs , Source ). struct Registration { contract IFlareDaemonize daemonizedContract ; uint256 gasLimit ; }","title":"Registration"},{"location":"apis/smart-contracts/FlareDaemon/#st_timelockedcall","text":"Defined in GovernedBase ( Docs , Source ). struct TimelockedCall { uint256 allowedAfterTimestamp ; bytes encodedCall ; }","title":"TimelockedCall"},{"location":"apis/smart-contracts/FlareDaemon/#variables","text":"","title":"Variables"},{"location":"apis/smart-contracts/FlareDaemon/#va_blockholdoff","text":"Defined in FlareDaemon ( Docs , Source ). uint256 blockHoldoff","title":"blockHoldoff"},{"location":"apis/smart-contracts/FlareDaemon/#va_errordata","text":"Defined in FlareDaemon ( Docs , Source ). struct FlareDaemon . LastErrorData errorData","title":"errorData"},{"location":"apis/smart-contracts/FlareDaemon/#va_governancesettings","text":"Defined in GovernedBase ( Docs , Source ). contract IGovernanceSettings governanceSettings Governance Settings.","title":"governanceSettings"},{"location":"apis/smart-contracts/FlareDaemon/#va_inflation","text":"Defined in FlareDaemon ( Docs , Source ). contract IInflationGenesis inflation","title":"inflation"},{"location":"apis/smart-contracts/FlareDaemon/#va_lastmintrequestts","text":"Defined in FlareDaemon ( Docs , Source ). uint256 lastMintRequestTs","title":"lastMintRequestTs"},{"location":"apis/smart-contracts/FlareDaemon/#va_lastupdatemaxmintrequestts","text":"Defined in FlareDaemon ( Docs , Source ). uint256 lastUpdateMaxMintRequestTs","title":"lastUpdateMaxMintRequestTs"},{"location":"apis/smart-contracts/FlareDaemon/#va_maxmintingrequestwei","text":"Defined in FlareDaemon ( Docs , Source ). uint256 maxMintingRequestWei","title":"maxMintingRequestWei"},{"location":"apis/smart-contracts/FlareDaemon/#va_productionmode","text":"Defined in GovernedBase ( Docs , Source ). bool productionMode When true, governance is enabled and cannot be disabled. See switchToProductionMode .","title":"productionMode"},{"location":"apis/smart-contracts/FlareDaemon/#va_systemlasttriggeredat","text":"Defined in FlareDaemon ( Docs , Source ). uint256 systemLastTriggeredAt","title":"systemLastTriggeredAt"},{"location":"apis/smart-contracts/FlareDaemon/#va_timelockedcalls","text":"Defined in GovernedBase ( Docs , Source ). mapping ( bytes4 => struct GovernedBase . TimelockedCall ) timelockedCalls List of pending timelocked governance calls.","title":"timelockedCalls"},{"location":"apis/smart-contracts/FlareDaemon/#va_totalmintingreceivedwei","text":"Defined in FlareDaemon ( Docs , Source ). uint256 totalMintingReceivedWei","title":"totalMintingReceivedWei"},{"location":"apis/smart-contracts/FlareDaemon/#va_totalmintingrequestedwei","text":"Defined in FlareDaemon ( Docs , Source ). uint256 totalMintingRequestedWei","title":"totalMintingRequestedWei"},{"location":"apis/smart-contracts/FlareDaemon/#va_totalmintingwithdrawnwei","text":"Defined in FlareDaemon ( Docs , Source ). uint256 totalMintingWithdrawnWei","title":"totalMintingWithdrawnWei"},{"location":"apis/smart-contracts/FlareDaemon/#va_totalselfdestructreceivedwei","text":"Defined in FlareDaemon ( Docs , Source ). uint256 totalSelfDestructReceivedWei","title":"totalSelfDestructReceivedWei"},{"location":"apis/smart-contracts/Ftso/","text":"Ftso # Source | Inherits from IIFtso Flare Time Series Oracle contract. An instance of this contract is created for each tracked asset, and typically accessed through the FtsoRegistry . Data providers do not access the Ftso instances directly either, and use the PriceSubmitter contract instead. Functions # activateFtso # Defined in Ftso ( Docs , Source ). function activateFtso ( uint256 _firstEpochStartTs , uint256 _submitPeriodSeconds , uint256 _revealPeriodSeconds ) external ; Initializes FTSO immutable settings and activates the contract. Can only be called by the ftsoManager . Parameters Type Description _firstEpochStartTs uint256 Timestamp of the first epoch in seconds from UNIX epoch. _submitPeriodSeconds uint256 Duration of epoch submission window in seconds. _revealPeriodSeconds uint256 Duration of epoch reveal window in seconds. active # Defined in IFtso ( Docs , Source ). function active ( ) external view returns ( bool ); Returns whether FTSO is active or not. configureEpochs # Defined in Ftso ( Docs , Source ). function configureEpochs ( uint256 _maxVotePowerNatThresholdFraction , uint256 _maxVotePowerAssetThresholdFraction , uint256 _lowAssetUSDThreshold , uint256 _highAssetUSDThreshold , uint256 _highAssetTurnoutThresholdBIPS , uint256 _lowNatTurnoutThresholdBIPS , uint256 _elasticBandRewardBIPS , uint256 _elasticBandWidthPPM , address [] _trustedAddresses ) external ; Sets configurable settings related to epochs. Can only be called by the ftsoManager . Should never revert if called from ftsoManager . Parameters Type Description _maxVotePowerNatThresholdFraction uint256 High threshold for native token vote power per voter. _maxVotePowerAssetThresholdFraction uint256 High threshold for asset vote power per voter. _lowAssetUSDThreshold uint256 Threshold for low asset vote power (in scaled USD). _highAssetUSDThreshold uint256 Threshold for high asset vote power (in scaled USD). _highAssetTurnoutThresholdBIPS uint256 Threshold for high asset turnout (in BIPS). _lowNatTurnoutThresholdBIPS uint256 Threshold for low nat turnout (in BIPS). _elasticBandRewardBIPS uint256 Percentage of the rewards (in BIPS) that go to the secondary reward band . The rest go to the primary reward band. _elasticBandWidthPPM uint256 Width of the secondary reward band, in parts-per-milion of the median. _trustedAddresses address[] Trusted voters that will be used if low voter turnout is detected. constructor # Defined in Ftso ( Docs , Source ). constructor ( string _symbol , uint256 _decimals , contract IPriceSubmitter _priceSubmitter , contract IIVPToken _wNat , address _ftsoManager , uint256 _firstEpochStartTs , uint256 _submitPeriodSeconds , uint256 _revealPeriodSeconds , uint128 _initialPriceUSD , uint256 _priceDeviationThresholdBIPS , uint256 _cyclicBufferSize ) public ; deactivateFtso # Defined in Ftso ( Docs , Source ). function deactivateFtso ( ) external ; Deactivates the contract. Can only be called by the ftsoManager . epochsConfiguration # Defined in Ftso ( Docs , Source ). function epochsConfiguration ( ) external view returns ( uint256 _maxVotePowerNatThresholdFraction , uint256 _maxVotePowerAssetThresholdFraction , uint256 _lowAssetUSDThreshold , uint256 _highAssetUSDThreshold , uint256 _highAssetTurnoutThresholdBIPS , uint256 _lowNatTurnoutThresholdBIPS , uint256 _elasticBandRewardBIPS , uint256 _elasticBandWidthPPM , address [] _trustedAddresses ); Returns current configuration of epoch state. Returns Type Description _maxVotePowerNatThresholdFraction uint256 High threshold for native token vote power per voter. _maxVotePowerAssetThresholdFraction uint256 High threshold for asset vote power per voter. _lowAssetUSDThreshold uint256 Threshold for low asset vote power (in scaled USD). _highAssetUSDThreshold uint256 Threshold for high asset vote power (in scaled USD). _highAssetTurnoutThresholdBIPS uint256 Threshold for high asset turnout (in BIPS). _lowNatTurnoutThresholdBIPS uint256 Threshold for low nat turnout (in BIPS). _elasticBandRewardBIPS uint256 Percentage of the rewards (in BIPS) that go to the secondary reward band . The rest go to the primary reward band. _elasticBandWidthPPM uint256 Width of the secondary reward band, in parts-per-milion of the median. _trustedAddresses address[] Trusted voters that will be used if low voter turnout is detected. fallbackFinalizePriceEpoch # Defined in Ftso ( Docs , Source ). function fallbackFinalizePriceEpoch ( uint256 _epochId ) external ; Forces finalization of a price epoch, calculating the median price from trusted addresses only. Used as a fallback method, for example, due to an unexpected error during normal epoch finalization or because the ftsoManager enabled the fallback mode. Can only be called by the ftsoManager . Parameters Type Description _epochId uint256 ID of the epoch to finalize. finalizePriceEpoch # Defined in Ftso ( Docs , Source ). function finalizePriceEpoch ( uint256 _epochId , bool _returnRewardData ) external returns ( address [] _eligibleAddresses , uint256 [] _natWeights , uint256 _natWeightsSum ); Computes epoch price based on gathered votes. If the price reveal window for the epoch has ended, finalize the epoch. Iterate list of price submissions. Find weighted median. Find adjacent 50% of price submissions. Allocate rewards for price submissions. Can only be called by the ftsoManager , and only at the correct time. Parameters Type Description _epochId uint256 ID of the epoch to finalize. _returnRewardData bool Parameter that determines if the reward data is returned. Returns Type Description _eligibleAddresses address[] List of addresses eligible for reward. _natWeights uint256[] List of native token weights corresponding to the eligible addresses. _natWeightsSum uint256 forceFinalizePriceEpoch # Defined in Ftso ( Docs , Source ). function forceFinalizePriceEpoch ( uint256 _epochId ) external ; Forces finalization of a price epoch by copying the price from the previous epoch. Used as a fallback method if fallbackFinalizePriceEpoch fails due to an exception. Can only be called by the ftsoManager . Parameters Type Description _epochId uint256 ID of the epoch to finalize. ftsoManager # Defined in IIFtso ( Docs , Source ). function ftsoManager ( ) external view returns ( address ); Returns the FTSO manager's address. Returns Type Description [0] address Address of the FTSO manager contract. getAsset # Defined in Ftso ( Docs , Source ). function getAsset ( ) external view returns ( contract IIVPToken ); Returns the FTSO asset. Returns Type Description [0] contract IIVPToken Address of the IIVPToken tracked by this FTSO. null in case of multi-asset FTSO. getAssetFtsos # Defined in Ftso ( Docs , Source ). function getAssetFtsos ( ) external view returns ( contract IIFtso []); Returns the asset FTSOs. Returns Type Description [0] contract IIFtso[] Array of IIFtso contract addresses. null in case of single-asset FTSO. getCurrentEpochId # Defined in Ftso ( Docs , Source ). function getCurrentEpochId ( ) public view returns ( uint256 ); Returns the current epoch ID. It never reverts. Returns Type Description [0] uint256 Currently running epoch ID. IDs are consecutive numbers starting from zero. getCurrentPrice # Defined in Ftso ( Docs , Source ). function getCurrentPrice ( ) external view returns ( uint256 _price , uint256 _timestamp ); Returns the current asset price. Returns Type Description _price uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Time when price was updated for the last time, in seconds from UNIX epoch. getCurrentPriceDetails # Defined in Ftso ( Docs , Source ). function getCurrentPriceDetails ( ) external view returns ( uint256 _price , uint256 _priceTimestamp , enum IFtso . PriceFinalizationType _priceFinalizationType , uint256 _lastPriceEpochFinalizationTimestamp , enum IFtso . PriceFinalizationType _lastPriceEpochFinalizationType ); Returns asset's current price details. All timestamps are in seconds from UNIX epoch. Returns Type Description _price uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _priceTimestamp uint256 Time when price was updated for the last time. _priceFinalizationType enum IFtso.PriceFinalizationType Finalization type when price was updated for the last time. _lastPriceEpochFinalizationTimestamp uint256 Time when last price epoch was finalized. _lastPriceEpochFinalizationType enum IFtso.PriceFinalizationType Finalization type of last finalized price epoch. getCurrentPriceFromTrustedProviders # Defined in Ftso ( Docs , Source ). function getCurrentPriceFromTrustedProviders ( ) external view returns ( uint256 _price , uint256 _timestamp ); Returns current asset price calculated only using input from trusted providers. Returns Type Description _price uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Time when price was updated for the last time, in seconds from UNIX epoch. getCurrentPriceWithDecimals # Defined in Ftso ( Docs , Source ). function getCurrentPriceWithDecimals ( ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Returns current asset price and number of decimals. Returns Type Description _price uint256 Price in USD multiplied by 10^ _assetPriceUsdDecimals . _timestamp uint256 Time when price was updated for the last time, in seconds from UNIX epoch. _assetPriceUsdDecimals uint256 Number of decimals used to return the USD price. getCurrentPriceWithDecimalsFromTrustedProviders # Defined in Ftso ( Docs , Source ). function getCurrentPriceWithDecimalsFromTrustedProviders ( ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Returns current asset price calculated only using input from trusted providers and number of decimals. Returns Type Description _price uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Time when price was updated for the last time, in seconds from UNIX epoch. _assetPriceUsdDecimals uint256 Number of decimals used to return the USD price. getCurrentRandom # Defined in Ftso ( Docs , Source ). function getCurrentRandom ( ) external view returns ( uint256 ); Returns the random number for the previous price epoch, obtained from the random numbers provided by all data providers along with their data submissions. It never reverts. getEpochId # Defined in Ftso ( Docs , Source ). function getEpochId ( uint256 _timestamp ) external view returns ( uint256 ); Returns the ID of the epoch that was opened for price submission at the specified timestamp. It never reverts. Parameters Type Description _timestamp uint256 Queried timestamp in seconds from UNIX epoch. Returns Type Description [0] uint256 Epoch ID corresponding to that timestamp. IDs are consecutive numbers starting from zero. getEpochPrice # Defined in Ftso ( Docs , Source ). function getEpochPrice ( uint256 _epochId ) external view returns ( uint256 ); Returns agreed asset price in the specified epoch. Parameters Type Description _epochId uint256 ID of the epoch. Only the last 200 epochs can be queried. Out-of-bounds queries revert. Returns Type Description [0] uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . getEpochPriceForVoter # Defined in Ftso ( Docs , Source ). function getEpochPriceForVoter ( uint256 _epochId , address _voter ) external view returns ( uint256 ); Returns asset price submitted by a voter in the specified epoch. Parameters Type Description _epochId uint256 ID of the epoch being queried. Only the last 200 epochs can be queried. Out-of-bounds queries revert. _voter address Address of the voter being queried. Returns Type Description [0] uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . getPriceEpochConfiguration # Defined in Ftso ( Docs , Source ). function getPriceEpochConfiguration ( ) external view returns ( uint256 _firstEpochStartTs , uint256 _submitPeriodSeconds , uint256 _revealPeriodSeconds ); Returns current epoch's configuration. Returns Type Description _firstEpochStartTs uint256 First epoch start timestamp in seconds from UNIX epoch. _submitPeriodSeconds uint256 Submit period in seconds. _revealPeriodSeconds uint256 Reveal period in seconds. getPriceEpochData # Defined in Ftso ( Docs , Source ). function getPriceEpochData ( ) external view returns ( uint256 _epochId , uint256 _epochSubmitEndTime , uint256 _epochRevealEndTime , uint256 _votePowerBlock , bool _fallbackMode ); Returns current epoch data. Intervals are open on the right: End times are not included. Returns Type Description _epochId uint256 Current epoch ID. _epochSubmitEndTime uint256 End time of the price submission window in seconds from UNIX epoch. _epochRevealEndTime uint256 End time of the price reveal window in seconds from UNIX epoch. _votePowerBlock uint256 Vote power block for the current epoch. _fallbackMode bool Whether the current epoch is in fallback mode. Only votes from trusted addresses are used in this mode. getRandom # Defined in Ftso ( Docs , Source ). function getRandom ( uint256 _epochId ) external view returns ( uint256 ); Returns the random number used in a specific past epoch, obtained from the random numbers provided by all data providers along with their data submissions. Parameters Type Description _epochId uint256 ID of the queried epoch. Current epoch cannot be queried, and the previous epoch is constantly updated as data providers reveal their prices and random numbers. Only the last 50 epochs can be queried and there is no bounds checking for this parameter. Out-of-bounds queries return undefined values. Returns Type Description [0] uint256 The random number used in that epoch. getVoteWeightingParameters # Defined in IIFtso ( Docs , Source ). function getVoteWeightingParameters ( ) external view returns ( contract IIVPToken [] _assets , uint256 [] _assetMultipliers , uint256 _totalVotePowerNat , uint256 _totalVotePowerAsset , uint256 _assetWeightRatio , uint256 _votePowerBlock ); Returns parameters necessary for replicating vote weighting (used in VoterWhitelister ). Returns Type Description _assets contract IIVPToken[] The list of assets that are accounted in vote. _assetMultipliers uint256[] Weight multiplier of each asset in (multiasset) FTSO. _totalVotePowerNat uint256 Total native token vote power at block. _totalVotePowerAsset uint256 Total combined asset vote power at block. _assetWeightRatio uint256 Ratio of combined asset vote power vs. native token vp (in BIPS). _votePowerBlock uint256 Vote power block for the epoch. initializeCurrentEpochStateForReveal # Defined in Ftso ( Docs , Source ). function initializeCurrentEpochStateForReveal ( uint256 _circulatingSupplyNat , bool _fallbackMode ) external ; Initializes current epoch instance for reveal. Can only be called by the ftsoManager . Parameters Type Description _circulatingSupplyNat uint256 Epoch native token circulating supply. _fallbackMode bool Whether the current epoch is in fallback mode. revealPriceSubmitter # Defined in Ftso ( Docs , Source ). function revealPriceSubmitter ( address _voter , uint256 _epochId , uint256 _price , uint256 _voterWNatVP ) external ; Reveals the price submitted by a voter on a specific epoch. The hash of _price and _random must be equal to the submitted hash Emits a PriceRevealed event. Can only be called by the priceSubmitter . Parameters Type Description _voter address Voter address. _epochId uint256 ID of the epoch in which the price hash was submitted. _price uint256 Submitted price. _voterWNatVP uint256 Voter's vote power in WNat units. setAsset # Defined in Ftso ( Docs , Source ). function setAsset ( contract IIVPToken _asset ) external ; Sets asset for FTSO to operate as single-asset oracle. Can only be called by the ftsoManager . Parameters Type Description _asset contract IIVPToken Address of the IIVPToken contract that will be the asset tracked by this FTSO. setAssetFtsos # Defined in Ftso ( Docs , Source ). function setAssetFtsos ( contract IIFtso [] _assetFtsos ) external ; Sets an array of FTSOs for FTSO to operate as multi-asset oracle. FTSOs implicitly determine the FTSO assets . Can only be called by the ftsoManager . Parameters Type Description _assetFtsos contract IIFtso[] Array of FTSOs. setVotePowerBlock # Defined in Ftso ( Docs , Source ). function setVotePowerBlock ( uint256 _votePowerBlock ) external ; Sets the current vote power block. Current vote power block will update per reward epoch. The FTSO doesn't have notion of reward epochs. Can only be called by the ftsoManager . Parameters Type Description _votePowerBlock uint256 symbol # Defined in IFtso ( Docs , Source ). function symbol ( ) external view returns ( string ); Returns the FTSO symbol . updateInitialPrice # Defined in Ftso ( Docs , Source ). function updateInitialPrice ( uint256 _initialPriceUSD , uint256 _initialPriceTimestamp ) external ; Updates initial asset price when the contract is not active yet. Can only be called by the ftsoManager . wNat # Defined in IIFtso ( Docs , Source ). function wNat ( ) external view returns ( contract IIVPToken ); Address of the WNat contract. Returns Type Description [0] contract IIVPToken Address of the WNat contract. wNatVotePowerCached # Defined in Ftso ( Docs , Source ). function wNatVotePowerCached ( address _owner , uint256 _epochId ) public returns ( uint256 ); Get and cache the vote power of a voter on a specific epoch, in WNat units. Parameters Type Description _owner address _epochId uint256 ID of the epoch in which the price hash was submitted. Returns Type Description [0] uint256 Voter's vote power in WNat units. Modifiers # onlyFtsoManager # Defined in Ftso ( Docs , Source ). modifier onlyFtsoManager () Only the ftsoManager can call this method. onlyPriceSubmitter # Defined in Ftso ( Docs , Source ). modifier onlyPriceSubmitter () Only the priceSubmitter can call this method. whenActive # Defined in Ftso ( Docs , Source ). modifier whenActive () This method can only be called when the FTSO is active . Structures # RewardData # Defined in Ftso ( Docs , Source ). struct RewardData { uint256 [] weightIQR ; uint256 [] weightElasticBand ; uint256 weightsIQRSum ; uint256 weightsElasticBandSum ; uint256 numberOfVotes ; uint256 elasticBandRewardBIPS ; } Variables # ASSET_PRICE_USD_DECIMALS # Defined in Ftso ( Docs , Source ). uint256 ASSET_PRICE_USD_DECIMALS Number of decimal places in an asset's USD price. Actual USD price is the integer value divided by 10^ ASSET_PRICE_USD_DECIMALS active # Defined in Ftso ( Docs , Source ). bool active Activation status of this FTSO. assetFtsos # Defined in Ftso ( Docs , Source ). contract IIFtso [] assetFtsos Array of addresses of other Ftso contracts tracked by this multi-asset FTSO. assets # Defined in Ftso ( Docs , Source ). contract IIVPToken [] assets Array of addresses of the tracked assets . ftsoManager # Defined in Ftso ( Docs , Source ). address ftsoManager Address of the FtsoManager contract. priceDeviationThresholdBIPS # Defined in Ftso ( Docs , Source ). uint256 priceDeviationThresholdBIPS Threshold for price deviation between consecutive epochs. priceEpochCyclicBufferSize # Defined in Ftso ( Docs , Source ). uint256 priceEpochCyclicBufferSize Amount of stored prices for past epochs, set at construction time. priceSubmitter # Defined in Ftso ( Docs , Source ). contract IPriceSubmitter priceSubmitter Address of the PriceSubmitter contract. symbol # Defined in Ftso ( Docs , Source ). string symbol Asset symbol that identifies this FTSO. wNat # Defined in Ftso ( Docs , Source ). contract IIVPToken wNat Address of the wrapped native token ( WNat ) contract.","title":"Ftso"},{"location":"apis/smart-contracts/Ftso/#ct_ftso","text":"Source | Inherits from IIFtso Flare Time Series Oracle contract. An instance of this contract is created for each tracked asset, and typically accessed through the FtsoRegistry . Data providers do not access the Ftso instances directly either, and use the PriceSubmitter contract instead.","title":"Ftso"},{"location":"apis/smart-contracts/Ftso/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/Ftso/#fn_activateftso_2f0a6f3c","text":"Defined in Ftso ( Docs , Source ). function activateFtso ( uint256 _firstEpochStartTs , uint256 _submitPeriodSeconds , uint256 _revealPeriodSeconds ) external ; Initializes FTSO immutable settings and activates the contract. Can only be called by the ftsoManager . Parameters Type Description _firstEpochStartTs uint256 Timestamp of the first epoch in seconds from UNIX epoch. _submitPeriodSeconds uint256 Duration of epoch submission window in seconds. _revealPeriodSeconds uint256 Duration of epoch reveal window in seconds.","title":"activateFtso"},{"location":"apis/smart-contracts/Ftso/#fn_active_02fb0c5e","text":"Defined in IFtso ( Docs , Source ). function active ( ) external view returns ( bool ); Returns whether FTSO is active or not.","title":"active"},{"location":"apis/smart-contracts/Ftso/#fn_configureepochs_5a3c9d8e","text":"Defined in Ftso ( Docs , Source ). function configureEpochs ( uint256 _maxVotePowerNatThresholdFraction , uint256 _maxVotePowerAssetThresholdFraction , uint256 _lowAssetUSDThreshold , uint256 _highAssetUSDThreshold , uint256 _highAssetTurnoutThresholdBIPS , uint256 _lowNatTurnoutThresholdBIPS , uint256 _elasticBandRewardBIPS , uint256 _elasticBandWidthPPM , address [] _trustedAddresses ) external ; Sets configurable settings related to epochs. Can only be called by the ftsoManager . Should never revert if called from ftsoManager . Parameters Type Description _maxVotePowerNatThresholdFraction uint256 High threshold for native token vote power per voter. _maxVotePowerAssetThresholdFraction uint256 High threshold for asset vote power per voter. _lowAssetUSDThreshold uint256 Threshold for low asset vote power (in scaled USD). _highAssetUSDThreshold uint256 Threshold for high asset vote power (in scaled USD). _highAssetTurnoutThresholdBIPS uint256 Threshold for high asset turnout (in BIPS). _lowNatTurnoutThresholdBIPS uint256 Threshold for low nat turnout (in BIPS). _elasticBandRewardBIPS uint256 Percentage of the rewards (in BIPS) that go to the secondary reward band . The rest go to the primary reward band. _elasticBandWidthPPM uint256 Width of the secondary reward band, in parts-per-milion of the median. _trustedAddresses address[] Trusted voters that will be used if low voter turnout is detected.","title":"configureEpochs"},{"location":"apis/smart-contracts/Ftso/#fn_constructor_undefined","text":"Defined in Ftso ( Docs , Source ). constructor ( string _symbol , uint256 _decimals , contract IPriceSubmitter _priceSubmitter , contract IIVPToken _wNat , address _ftsoManager , uint256 _firstEpochStartTs , uint256 _submitPeriodSeconds , uint256 _revealPeriodSeconds , uint128 _initialPriceUSD , uint256 _priceDeviationThresholdBIPS , uint256 _cyclicBufferSize ) public ;","title":"constructor"},{"location":"apis/smart-contracts/Ftso/#fn_deactivateftso_555989da","text":"Defined in Ftso ( Docs , Source ). function deactivateFtso ( ) external ; Deactivates the contract. Can only be called by the ftsoManager .","title":"deactivateFtso"},{"location":"apis/smart-contracts/Ftso/#fn_epochsconfiguration_e3749e0c","text":"Defined in Ftso ( Docs , Source ). function epochsConfiguration ( ) external view returns ( uint256 _maxVotePowerNatThresholdFraction , uint256 _maxVotePowerAssetThresholdFraction , uint256 _lowAssetUSDThreshold , uint256 _highAssetUSDThreshold , uint256 _highAssetTurnoutThresholdBIPS , uint256 _lowNatTurnoutThresholdBIPS , uint256 _elasticBandRewardBIPS , uint256 _elasticBandWidthPPM , address [] _trustedAddresses ); Returns current configuration of epoch state. Returns Type Description _maxVotePowerNatThresholdFraction uint256 High threshold for native token vote power per voter. _maxVotePowerAssetThresholdFraction uint256 High threshold for asset vote power per voter. _lowAssetUSDThreshold uint256 Threshold for low asset vote power (in scaled USD). _highAssetUSDThreshold uint256 Threshold for high asset vote power (in scaled USD). _highAssetTurnoutThresholdBIPS uint256 Threshold for high asset turnout (in BIPS). _lowNatTurnoutThresholdBIPS uint256 Threshold for low nat turnout (in BIPS). _elasticBandRewardBIPS uint256 Percentage of the rewards (in BIPS) that go to the secondary reward band . The rest go to the primary reward band. _elasticBandWidthPPM uint256 Width of the secondary reward band, in parts-per-milion of the median. _trustedAddresses address[] Trusted voters that will be used if low voter turnout is detected.","title":"epochsConfiguration"},{"location":"apis/smart-contracts/Ftso/#fn_fallbackfinalizepriceepoch_4afd5102","text":"Defined in Ftso ( Docs , Source ). function fallbackFinalizePriceEpoch ( uint256 _epochId ) external ; Forces finalization of a price epoch, calculating the median price from trusted addresses only. Used as a fallback method, for example, due to an unexpected error during normal epoch finalization or because the ftsoManager enabled the fallback mode. Can only be called by the ftsoManager . Parameters Type Description _epochId uint256 ID of the epoch to finalize.","title":"fallbackFinalizePriceEpoch"},{"location":"apis/smart-contracts/Ftso/#fn_finalizepriceepoch_40462a2d","text":"Defined in Ftso ( Docs , Source ). function finalizePriceEpoch ( uint256 _epochId , bool _returnRewardData ) external returns ( address [] _eligibleAddresses , uint256 [] _natWeights , uint256 _natWeightsSum ); Computes epoch price based on gathered votes. If the price reveal window for the epoch has ended, finalize the epoch. Iterate list of price submissions. Find weighted median. Find adjacent 50% of price submissions. Allocate rewards for price submissions. Can only be called by the ftsoManager , and only at the correct time. Parameters Type Description _epochId uint256 ID of the epoch to finalize. _returnRewardData bool Parameter that determines if the reward data is returned. Returns Type Description _eligibleAddresses address[] List of addresses eligible for reward. _natWeights uint256[] List of native token weights corresponding to the eligible addresses. _natWeightsSum uint256","title":"finalizePriceEpoch"},{"location":"apis/smart-contracts/Ftso/#fn_forcefinalizepriceepoch_974d7a6b","text":"Defined in Ftso ( Docs , Source ). function forceFinalizePriceEpoch ( uint256 _epochId ) external ; Forces finalization of a price epoch by copying the price from the previous epoch. Used as a fallback method if fallbackFinalizePriceEpoch fails due to an exception. Can only be called by the ftsoManager . Parameters Type Description _epochId uint256 ID of the epoch to finalize.","title":"forceFinalizePriceEpoch"},{"location":"apis/smart-contracts/Ftso/#fn_ftsomanager_11a7aaaa","text":"Defined in IIFtso ( Docs , Source ). function ftsoManager ( ) external view returns ( address ); Returns the FTSO manager's address. Returns Type Description [0] address Address of the FTSO manager contract.","title":"ftsoManager"},{"location":"apis/smart-contracts/Ftso/#fn_getasset_5c222bad","text":"Defined in Ftso ( Docs , Source ). function getAsset ( ) external view returns ( contract IIVPToken ); Returns the FTSO asset. Returns Type Description [0] contract IIVPToken Address of the IIVPToken tracked by this FTSO. null in case of multi-asset FTSO.","title":"getAsset"},{"location":"apis/smart-contracts/Ftso/#fn_getassetftsos_18931c35","text":"Defined in Ftso ( Docs , Source ). function getAssetFtsos ( ) external view returns ( contract IIFtso []); Returns the asset FTSOs. Returns Type Description [0] contract IIFtso[] Array of IIFtso contract addresses. null in case of single-asset FTSO.","title":"getAssetFtsos"},{"location":"apis/smart-contracts/Ftso/#fn_getcurrentepochid_a29a839f","text":"Defined in Ftso ( Docs , Source ). function getCurrentEpochId ( ) public view returns ( uint256 ); Returns the current epoch ID. It never reverts. Returns Type Description [0] uint256 Currently running epoch ID. IDs are consecutive numbers starting from zero.","title":"getCurrentEpochId"},{"location":"apis/smart-contracts/Ftso/#fn_getcurrentprice_eb91d37e","text":"Defined in Ftso ( Docs , Source ). function getCurrentPrice ( ) external view returns ( uint256 _price , uint256 _timestamp ); Returns the current asset price. Returns Type Description _price uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Time when price was updated for the last time, in seconds from UNIX epoch.","title":"getCurrentPrice"},{"location":"apis/smart-contracts/Ftso/#fn_getcurrentpricedetails_040d73b8","text":"Defined in Ftso ( Docs , Source ). function getCurrentPriceDetails ( ) external view returns ( uint256 _price , uint256 _priceTimestamp , enum IFtso . PriceFinalizationType _priceFinalizationType , uint256 _lastPriceEpochFinalizationTimestamp , enum IFtso . PriceFinalizationType _lastPriceEpochFinalizationType ); Returns asset's current price details. All timestamps are in seconds from UNIX epoch. Returns Type Description _price uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _priceTimestamp uint256 Time when price was updated for the last time. _priceFinalizationType enum IFtso.PriceFinalizationType Finalization type when price was updated for the last time. _lastPriceEpochFinalizationTimestamp uint256 Time when last price epoch was finalized. _lastPriceEpochFinalizationType enum IFtso.PriceFinalizationType Finalization type of last finalized price epoch.","title":"getCurrentPriceDetails"},{"location":"apis/smart-contracts/Ftso/#fn_getcurrentpricefromtrustedproviders_af52df08","text":"Defined in Ftso ( Docs , Source ). function getCurrentPriceFromTrustedProviders ( ) external view returns ( uint256 _price , uint256 _timestamp ); Returns current asset price calculated only using input from trusted providers. Returns Type Description _price uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Time when price was updated for the last time, in seconds from UNIX epoch.","title":"getCurrentPriceFromTrustedProviders"},{"location":"apis/smart-contracts/Ftso/#fn_getcurrentpricewithdecimals_65f5cd86","text":"Defined in Ftso ( Docs , Source ). function getCurrentPriceWithDecimals ( ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Returns current asset price and number of decimals. Returns Type Description _price uint256 Price in USD multiplied by 10^ _assetPriceUsdDecimals . _timestamp uint256 Time when price was updated for the last time, in seconds from UNIX epoch. _assetPriceUsdDecimals uint256 Number of decimals used to return the USD price.","title":"getCurrentPriceWithDecimals"},{"location":"apis/smart-contracts/Ftso/#fn_getcurrentpricewithdecimalsfromtrustedproviders_3cacb3ae","text":"Defined in Ftso ( Docs , Source ). function getCurrentPriceWithDecimalsFromTrustedProviders ( ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Returns current asset price calculated only using input from trusted providers and number of decimals. Returns Type Description _price uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Time when price was updated for the last time, in seconds from UNIX epoch. _assetPriceUsdDecimals uint256 Number of decimals used to return the USD price.","title":"getCurrentPriceWithDecimalsFromTrustedProviders"},{"location":"apis/smart-contracts/Ftso/#fn_getcurrentrandom_d89601fd","text":"Defined in Ftso ( Docs , Source ). function getCurrentRandom ( ) external view returns ( uint256 ); Returns the random number for the previous price epoch, obtained from the random numbers provided by all data providers along with their data submissions. It never reverts.","title":"getCurrentRandom"},{"location":"apis/smart-contracts/Ftso/#fn_getepochid_5303548b","text":"Defined in Ftso ( Docs , Source ). function getEpochId ( uint256 _timestamp ) external view returns ( uint256 ); Returns the ID of the epoch that was opened for price submission at the specified timestamp. It never reverts. Parameters Type Description _timestamp uint256 Queried timestamp in seconds from UNIX epoch. Returns Type Description [0] uint256 Epoch ID corresponding to that timestamp. IDs are consecutive numbers starting from zero.","title":"getEpochId"},{"location":"apis/smart-contracts/Ftso/#fn_getepochprice_7d1d6f12","text":"Defined in Ftso ( Docs , Source ). function getEpochPrice ( uint256 _epochId ) external view returns ( uint256 ); Returns agreed asset price in the specified epoch. Parameters Type Description _epochId uint256 ID of the epoch. Only the last 200 epochs can be queried. Out-of-bounds queries revert. Returns Type Description [0] uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS .","title":"getEpochPrice"},{"location":"apis/smart-contracts/Ftso/#fn_getepochpriceforvoter_c5d8b9e7","text":"Defined in Ftso ( Docs , Source ). function getEpochPriceForVoter ( uint256 _epochId , address _voter ) external view returns ( uint256 ); Returns asset price submitted by a voter in the specified epoch. Parameters Type Description _epochId uint256 ID of the epoch being queried. Only the last 200 epochs can be queried. Out-of-bounds queries revert. _voter address Address of the voter being queried. Returns Type Description [0] uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS .","title":"getEpochPriceForVoter"},{"location":"apis/smart-contracts/Ftso/#fn_getpriceepochconfiguration_144e1591","text":"Defined in Ftso ( Docs , Source ). function getPriceEpochConfiguration ( ) external view returns ( uint256 _firstEpochStartTs , uint256 _submitPeriodSeconds , uint256 _revealPeriodSeconds ); Returns current epoch's configuration. Returns Type Description _firstEpochStartTs uint256 First epoch start timestamp in seconds from UNIX epoch. _submitPeriodSeconds uint256 Submit period in seconds. _revealPeriodSeconds uint256 Reveal period in seconds.","title":"getPriceEpochConfiguration"},{"location":"apis/smart-contracts/Ftso/#fn_getpriceepochdata_e3b3a3b3","text":"Defined in Ftso ( Docs , Source ). function getPriceEpochData ( ) external view returns ( uint256 _epochId , uint256 _epochSubmitEndTime , uint256 _epochRevealEndTime , uint256 _votePowerBlock , bool _fallbackMode ); Returns current epoch data. Intervals are open on the right: End times are not included. Returns Type Description _epochId uint256 Current epoch ID. _epochSubmitEndTime uint256 End time of the price submission window in seconds from UNIX epoch. _epochRevealEndTime uint256 End time of the price reveal window in seconds from UNIX epoch. _votePowerBlock uint256 Vote power block for the current epoch. _fallbackMode bool Whether the current epoch is in fallback mode. Only votes from trusted addresses are used in this mode.","title":"getPriceEpochData"},{"location":"apis/smart-contracts/Ftso/#fn_getrandom_cd4b6914","text":"Defined in Ftso ( Docs , Source ). function getRandom ( uint256 _epochId ) external view returns ( uint256 ); Returns the random number used in a specific past epoch, obtained from the random numbers provided by all data providers along with their data submissions. Parameters Type Description _epochId uint256 ID of the queried epoch. Current epoch cannot be queried, and the previous epoch is constantly updated as data providers reveal their prices and random numbers. Only the last 50 epochs can be queried and there is no bounds checking for this parameter. Out-of-bounds queries return undefined values. Returns Type Description [0] uint256 The random number used in that epoch.","title":"getRandom"},{"location":"apis/smart-contracts/Ftso/#fn_getvoteweightingparameters_8357d08c","text":"Defined in IIFtso ( Docs , Source ). function getVoteWeightingParameters ( ) external view returns ( contract IIVPToken [] _assets , uint256 [] _assetMultipliers , uint256 _totalVotePowerNat , uint256 _totalVotePowerAsset , uint256 _assetWeightRatio , uint256 _votePowerBlock ); Returns parameters necessary for replicating vote weighting (used in VoterWhitelister ). Returns Type Description _assets contract IIVPToken[] The list of assets that are accounted in vote. _assetMultipliers uint256[] Weight multiplier of each asset in (multiasset) FTSO. _totalVotePowerNat uint256 Total native token vote power at block. _totalVotePowerAsset uint256 Total combined asset vote power at block. _assetWeightRatio uint256 Ratio of combined asset vote power vs. native token vp (in BIPS). _votePowerBlock uint256 Vote power block for the epoch.","title":"getVoteWeightingParameters"},{"location":"apis/smart-contracts/Ftso/#fn_initializecurrentepochstateforreveal_f670ebe3","text":"Defined in Ftso ( Docs , Source ). function initializeCurrentEpochStateForReveal ( uint256 _circulatingSupplyNat , bool _fallbackMode ) external ; Initializes current epoch instance for reveal. Can only be called by the ftsoManager . Parameters Type Description _circulatingSupplyNat uint256 Epoch native token circulating supply. _fallbackMode bool Whether the current epoch is in fallback mode.","title":"initializeCurrentEpochStateForReveal"},{"location":"apis/smart-contracts/Ftso/#fn_revealpricesubmitter_c1f6c36e","text":"Defined in Ftso ( Docs , Source ). function revealPriceSubmitter ( address _voter , uint256 _epochId , uint256 _price , uint256 _voterWNatVP ) external ; Reveals the price submitted by a voter on a specific epoch. The hash of _price and _random must be equal to the submitted hash Emits a PriceRevealed event. Can only be called by the priceSubmitter . Parameters Type Description _voter address Voter address. _epochId uint256 ID of the epoch in which the price hash was submitted. _price uint256 Submitted price. _voterWNatVP uint256 Voter's vote power in WNat units.","title":"revealPriceSubmitter"},{"location":"apis/smart-contracts/Ftso/#fn_setasset_d0d552dd","text":"Defined in Ftso ( Docs , Source ). function setAsset ( contract IIVPToken _asset ) external ; Sets asset for FTSO to operate as single-asset oracle. Can only be called by the ftsoManager . Parameters Type Description _asset contract IIVPToken Address of the IIVPToken contract that will be the asset tracked by this FTSO.","title":"setAsset"},{"location":"apis/smart-contracts/Ftso/#fn_setassetftsos_131fdee2","text":"Defined in Ftso ( Docs , Source ). function setAssetFtsos ( contract IIFtso [] _assetFtsos ) external ; Sets an array of FTSOs for FTSO to operate as multi-asset oracle. FTSOs implicitly determine the FTSO assets . Can only be called by the ftsoManager . Parameters Type Description _assetFtsos contract IIFtso[] Array of FTSOs.","title":"setAssetFtsos"},{"location":"apis/smart-contracts/Ftso/#fn_setvotepowerblock_e536f396","text":"Defined in Ftso ( Docs , Source ). function setVotePowerBlock ( uint256 _votePowerBlock ) external ; Sets the current vote power block. Current vote power block will update per reward epoch. The FTSO doesn't have notion of reward epochs. Can only be called by the ftsoManager . Parameters Type Description _votePowerBlock uint256","title":"setVotePowerBlock"},{"location":"apis/smart-contracts/Ftso/#fn_symbol_95d89b41","text":"Defined in IFtso ( Docs , Source ). function symbol ( ) external view returns ( string ); Returns the FTSO symbol .","title":"symbol"},{"location":"apis/smart-contracts/Ftso/#fn_updateinitialprice_306ba253","text":"Defined in Ftso ( Docs , Source ). function updateInitialPrice ( uint256 _initialPriceUSD , uint256 _initialPriceTimestamp ) external ; Updates initial asset price when the contract is not active yet. Can only be called by the ftsoManager .","title":"updateInitialPrice"},{"location":"apis/smart-contracts/Ftso/#fn_wnat_9edbf007","text":"Defined in IIFtso ( Docs , Source ). function wNat ( ) external view returns ( contract IIVPToken ); Address of the WNat contract. Returns Type Description [0] contract IIVPToken Address of the WNat contract.","title":"wNat"},{"location":"apis/smart-contracts/Ftso/#fn_wnatvotepowercached_f72cab28","text":"Defined in Ftso ( Docs , Source ). function wNatVotePowerCached ( address _owner , uint256 _epochId ) public returns ( uint256 ); Get and cache the vote power of a voter on a specific epoch, in WNat units. Parameters Type Description _owner address _epochId uint256 ID of the epoch in which the price hash was submitted. Returns Type Description [0] uint256 Voter's vote power in WNat units.","title":"wNatVotePowerCached"},{"location":"apis/smart-contracts/Ftso/#modifiers","text":"","title":"Modifiers"},{"location":"apis/smart-contracts/Ftso/#md_onlyftsomanager","text":"Defined in Ftso ( Docs , Source ). modifier onlyFtsoManager () Only the ftsoManager can call this method.","title":"onlyFtsoManager"},{"location":"apis/smart-contracts/Ftso/#md_onlypricesubmitter","text":"Defined in Ftso ( Docs , Source ). modifier onlyPriceSubmitter () Only the priceSubmitter can call this method.","title":"onlyPriceSubmitter"},{"location":"apis/smart-contracts/Ftso/#md_whenactive","text":"Defined in Ftso ( Docs , Source ). modifier whenActive () This method can only be called when the FTSO is active .","title":"whenActive"},{"location":"apis/smart-contracts/Ftso/#structures","text":"","title":"Structures"},{"location":"apis/smart-contracts/Ftso/#st_rewarddata","text":"Defined in Ftso ( Docs , Source ). struct RewardData { uint256 [] weightIQR ; uint256 [] weightElasticBand ; uint256 weightsIQRSum ; uint256 weightsElasticBandSum ; uint256 numberOfVotes ; uint256 elasticBandRewardBIPS ; }","title":"RewardData"},{"location":"apis/smart-contracts/Ftso/#variables","text":"","title":"Variables"},{"location":"apis/smart-contracts/Ftso/#va_asset_price_usd_decimals","text":"Defined in Ftso ( Docs , Source ). uint256 ASSET_PRICE_USD_DECIMALS Number of decimal places in an asset's USD price. Actual USD price is the integer value divided by 10^ ASSET_PRICE_USD_DECIMALS","title":"ASSET_PRICE_USD_DECIMALS"},{"location":"apis/smart-contracts/Ftso/#va_active","text":"Defined in Ftso ( Docs , Source ). bool active Activation status of this FTSO.","title":"active"},{"location":"apis/smart-contracts/Ftso/#va_assetftsos","text":"Defined in Ftso ( Docs , Source ). contract IIFtso [] assetFtsos Array of addresses of other Ftso contracts tracked by this multi-asset FTSO.","title":"assetFtsos"},{"location":"apis/smart-contracts/Ftso/#va_assets","text":"Defined in Ftso ( Docs , Source ). contract IIVPToken [] assets Array of addresses of the tracked assets .","title":"assets"},{"location":"apis/smart-contracts/Ftso/#va_ftsomanager","text":"Defined in Ftso ( Docs , Source ). address ftsoManager Address of the FtsoManager contract.","title":"ftsoManager"},{"location":"apis/smart-contracts/Ftso/#va_pricedeviationthresholdbips","text":"Defined in Ftso ( Docs , Source ). uint256 priceDeviationThresholdBIPS Threshold for price deviation between consecutive epochs.","title":"priceDeviationThresholdBIPS"},{"location":"apis/smart-contracts/Ftso/#va_priceepochcyclicbuffersize","text":"Defined in Ftso ( Docs , Source ). uint256 priceEpochCyclicBufferSize Amount of stored prices for past epochs, set at construction time.","title":"priceEpochCyclicBufferSize"},{"location":"apis/smart-contracts/Ftso/#va_pricesubmitter","text":"Defined in Ftso ( Docs , Source ). contract IPriceSubmitter priceSubmitter Address of the PriceSubmitter contract.","title":"priceSubmitter"},{"location":"apis/smart-contracts/Ftso/#va_symbol","text":"Defined in Ftso ( Docs , Source ). string symbol Asset symbol that identifies this FTSO.","title":"symbol"},{"location":"apis/smart-contracts/Ftso/#va_wnat","text":"Defined in Ftso ( Docs , Source ). contract IIVPToken wNat Address of the wrapped native token ( WNat ) contract.","title":"wNat"},{"location":"apis/smart-contracts/FtsoManager/","text":"FtsoManager # Source | Inherits from IIFtsoManager , GovernedAndFlareDaemonized , AddressUpdatable , RevertErrorTracking FTSO Manager contract. It is in charge of: Defining reward epochs (few days). Choosing a single block each reward epoch that represents vote power of this epoch. Keeping track of all FTSO contracts. Every price epoch (few minutes): Randomly choose one FTSO for rewarding calculations. Trigger finalize price reveal epoch. Determine addresses and reward weights and triggers reward distribution. Functions # activate # Defined in FtsoManager ( Docs , Source ). function activate ( ) external ; Activates FTSO manager ( daemonize will run jobs). Only governance can call this method. active # Defined in IFtsoManager ( Docs , Source ). function active ( ) external view returns ( bool ); Returns whether the FTSO Manager is active or not. Returns Type Description [0] bool bool Active status. addFtso # Defined in FtsoManager ( Docs , Source ). function addFtso ( contract IIFtso _ftso ) external ; Adds FTSO to the list of managed FTSOs, to support a new price pair. All FTSOs in a multi-asset FTSO must be managed by the same FTSO manager. Only governance can call this method. Parameters Type Description _ftso contract IIFtso FTSO contract address to add. addFtsosBulk # Defined in FtsoManager ( Docs , Source ). function addFtsosBulk ( contract IIFtso [] _ftsos ) external ; Adds a list of FTSOs to the list of managed FTSOs, to support new price pairs. All FTSOs in a multi-asset FTSO must be managed by the same FTSO manager. Only governance can call this method. Parameters Type Description _ftsos contract IIFtso[] Array of FTSO contract addresses to add. cancelGovernanceCall # Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector. constructor # Defined in FtsoManager ( Docs , Source ). constructor ( address _governance , contract FlareDaemon _flareDaemon , address _addressUpdater , contract IIFtsoManagerV1 _oldFtsoManager , uint256 _firstPriceEpochStartTs , uint256 _priceEpochDurationSeconds , uint256 _revealEpochDurationSeconds , uint256 _firstRewardEpochStartTs , uint256 _rewardEpochDurationSeconds , uint256 _votePowerIntervalFraction ) public ; constructor # Defined in GovernedAndFlareDaemonized ( Docs , Source ). constructor ( address _governance , contract FlareDaemon _flareDaemon ) public ; constructor # Defined in Governed ( Docs , Source ). constructor ( address _governance ) public ; Parameters Type Description _governance address Governance contract. Must not be zero. currentRewardEpochEnds # Defined in IIFtsoManager ( Docs , Source ). function currentRewardEpochEnds ( ) external view returns ( uint256 ); Returns when the current reward epoch finishes. Returns Type Description [0] uint256 uint256 Time in seconds since the UNIX epoch when the current reward epoch will finish. daemonize # Defined in FtsoManager ( Docs , Source ). function daemonize ( ) external returns ( bool ); Implement this function to receive a trigger from the FlareDaemon . The trigger method is called by the validator right at the end of block state transition. Only flareDaemon can call this method. Returns Type Description [0] bool bool Whether the contract is still active after the call. Currently unused. deactivateFtsos # Defined in FtsoManager ( Docs , Source ). function deactivateFtsos ( contract IIFtso [] _ftsos ) external ; Deactivates FTSOs that are no longer used on FTSO registry. Only governance can call this method. Parameters Type Description _ftsos contract IIFtso[] Array of FTSO contract addresses to deactivate. executeGovernanceCall # Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored). ftsoRegistry # Defined in FtsoManager ( Docs , Source ). function ftsoRegistry ( ) external view returns ( contract IIFtsoRegistry ); Returns the FtsoRegistry contract address. getAddressUpdater # Defined in AddressUpdatable ( Docs , Source ). function getAddressUpdater ( ) public view returns ( address _addressUpdater ); Returns the configured address updater. Returns Type Description _addressUpdater address The AddresUpdater contract that can update our contract address list, as a response to a governance call. getContractName # Defined in FtsoManager ( Docs , Source ). function getContractName ( ) external pure returns ( string ); Implement this function to allow updating daemonized contracts through the AddressUpdater . Returns Type Description [0] string string Contract name. getCurrentPriceEpochData # Defined in FtsoManager ( Docs , Source ). function getCurrentPriceEpochData ( ) external view returns ( uint256 _priceEpochId , uint256 _priceEpochStartTimestamp , uint256 _priceEpochEndTimestamp , uint256 _priceEpochRevealEndTimestamp , uint256 _currentTimestamp ); Returns timing information for the current price epoch. All intervals are half-closed: end time is not included. All timestamps are in seconds since UNIX epoch. See the FTSO page for information about the different submission phases. Returns Type Description _priceEpochId uint256 Price epoch ID. _priceEpochStartTimestamp uint256 Beginning of the commit phase. _priceEpochEndTimestamp uint256 End of the commit phase. _priceEpochRevealEndTimestamp uint256 End of the reveal phase. _currentTimestamp uint256 Current time. getCurrentPriceEpochId # Defined in FtsoManager ( Docs , Source ). function getCurrentPriceEpochId ( ) external view returns ( uint256 _priceEpochId ); Returns current price epoch ID. Returns Type Description _priceEpochId uint256 Currently running epoch ID. IDs are consecutive numbers starting from zero. getCurrentRewardEpoch # Defined in FtsoManager ( Docs , Source ). function getCurrentRewardEpoch ( ) external view returns ( uint256 ); Returns current reward epoch ID (the one currently running). Returns Type Description [0] uint256 Reward epoch ID. A monotonically increasing integer. getElasticBandWidthPPMFtso # Defined in FtsoManager ( Docs , Source ). function getElasticBandWidthPPMFtso ( contract IIFtso _ftso ) external view returns ( uint256 ); Returns the secondary band's width in PPM (parts-per-million) of the median value, for a given FTSO. Parameters Type Description _ftso contract IIFtso The queried FTSO contract address. Returns Type Description [0] uint256 uint256 Secondary band width in PPM. To obtain the actual band width, divide this number by 10^6 and multiply by the price median value. getFallbackMode # Defined in FtsoManager ( Docs , Source ). function getFallbackMode ( ) external view returns ( bool _fallbackMode , contract IIFtso [] _ftsos , bool [] _ftsoInFallbackMode ); Returns whether the FTSO Manager is currently in fallback mode. In this mode only submissions from trusted providers are used. Returns Type Description _fallbackMode bool True if fallback mode is enabled for the manager. _ftsos contract IIFtso[] Array of all currently active FTSO assets. _ftsoInFallbackMode bool[] Boolean array indicating which FTSO assets are in fallback mode. If the FTSO Manager is in fallback mode then ALL FTSOs are in fallback mode. getFtsos # Defined in FtsoManager ( Docs , Source ). function getFtsos ( ) external view returns ( contract IIFtso [] _ftsos ); Returns the list of currently active FTSOs. Returns Type Description _ftsos contract IIFtso[] Array of contract addresses for the FTSOs. getGovernanceParameters # Defined in FtsoManager ( Docs , Source ). function getGovernanceParameters ( ) external view returns ( uint256 _maxVotePowerNatThresholdFraction , uint256 _maxVotePowerAssetThresholdFraction , uint256 _lowAssetUSDThreshold , uint256 _highAssetUSDThreshold , uint256 _highAssetTurnoutThresholdBIPS , uint256 _lowNatTurnoutThresholdBIPS , uint256 _elasticBandRewardBIPS , uint256 _rewardExpiryOffsetSeconds , address [] _trustedAddresses , bool _initialized , bool _changed ); Returns governance parameters for FTSOs. Returns Type Description _maxVotePowerNatThresholdFraction uint256 High threshold for native token vote power per voter. _maxVotePowerAssetThresholdFraction uint256 High threshold for asset vote power per voter _lowAssetUSDThreshold uint256 Threshold for low asset vote power (in scaled USD). _highAssetUSDThreshold uint256 Threshold for high asset vote power (in scaled USD). _highAssetTurnoutThresholdBIPS uint256 Threshold for high asset turnout (in BIPS). _lowNatTurnoutThresholdBIPS uint256 Threshold for low nat turnout (in BIPS). _elasticBandRewardBIPS uint256 Secondary reward band, where _elasticBandRewardBIPS goes to the secondary band and 10000 - _elasticBandRewardBIPS to the primary (IQR) band. _rewardExpiryOffsetSeconds uint256 Reward epochs closed earlier than block.timestamp - _rewardExpiryOffsetSeconds expire. _trustedAddresses address[] Trusted addresses will be used as a fallback mechanism for setting the price. _initialized bool _changed bool getLastUnprocessedPriceEpochData # Defined in FtsoManager ( Docs , Source ). function getLastUnprocessedPriceEpochData ( ) external view returns ( uint256 _lastUnprocessedPriceEpoch , uint256 _lastUnprocessedPriceEpochRevealEnds , bool _lastUnprocessedPriceEpochInitialized ); Returns information regarding the currently unprocessed price epoch. This epoch is not necessarily the last one, in case the network halts for some time due to validator node problems, for example. Returns Type Description _lastUnprocessedPriceEpoch uint256 ID of the price epoch that is currently waiting finalization. _lastUnprocessedPriceEpochRevealEnds uint256 When that price epoch can be finalized, in seconds since UNIX epoch. _lastUnprocessedPriceEpochInitialized bool Whether this price epoch has been already initialized and therefore it must be finalized before the corresponding reward epoch can be finalized. getPriceEpochConfiguration # Defined in FtsoManager ( Docs , Source ). function getPriceEpochConfiguration ( ) external view returns ( uint256 _firstPriceEpochStartTs , uint256 _priceEpochDurationSeconds , uint256 _revealEpochDurationSeconds ); Returns the current values for price epoch timing configuration. See the FTSO page for information about the different submission phases. Returns Type Description _firstPriceEpochStartTs uint256 Timestamp, in seconds since UNIX epoch, of the first price epoch. _priceEpochDurationSeconds uint256 Duration in seconds of the commit phase. _revealEpochDurationSeconds uint256 Duration in seconds of the reveal phase. getPriceSubmitter # Defined in FtsoManager ( Docs , Source ). function getPriceSubmitter ( ) external view returns ( contract IIPriceSubmitter ); Returns the PriceSubmitter contract. getRewardEpochConfiguration # Defined in FtsoManager ( Docs , Source ). function getRewardEpochConfiguration ( ) external view returns ( uint256 _firstRewardEpochStartTs , uint256 _rewardEpochDurationSeconds ); Returns the current values for reward epoch timing configuration. See the Reward epochs box. Returns Type Description _firstRewardEpochStartTs uint256 Timestamp, in seconds since UNIX epoch, of the first reward epoch. _rewardEpochDurationSeconds uint256 Duration in seconds of the reward epochs. getRewardEpochData # Defined in FtsoManager ( Docs , Source ). function getRewardEpochData ( uint256 _rewardEpochId ) public view returns ( struct IIFtsoManager . RewardEpochData ); Returns data regarding a specific reward epoch ID. Parameters Type Description _rewardEpochId uint256 Epoch ID. Returns Type Description [0] struct IIFtsoManager.RewardEpochData RewardEpochData Its associated data. getRewardEpochToExpireNext # Defined in FtsoManager ( Docs , Source ). function getRewardEpochToExpireNext ( ) external view returns ( uint256 ); Return reward epoch that will expire next, when a new reward epoch is initialized. Reward epochs older than 90 days expire, and any unclaimed rewards in them become inaccessible. Returns Type Description [0] uint256 uint256 Reward epoch ID. getRewardEpochVotePowerBlock # Defined in FtsoManager ( Docs , Source ). function getRewardEpochVotePowerBlock ( uint256 _rewardEpoch ) external view returns ( uint256 _votepowerBlock ); Returns the vote power block that was used for a past reward epoch. Parameters Type Description _rewardEpoch uint256 The queried reward epoch ID. Returns Type Description _votepowerBlock uint256 uint256 The block number of that reward epoch's vote power block. getRewardExpiryOffsetSeconds # Defined in FtsoManager ( Docs , Source ). function getRewardExpiryOffsetSeconds ( ) external view returns ( uint256 ); Returns the currently configured reward expiration time. Returns Type Description [0] uint256 uint256 Unclaimed rewards accrued in reward epochs more than this amount of seconds in the past expire and become inaccessible. getUpdateGovernanceParametersTs # Defined in FtsoManager ( Docs , Source ). function getUpdateGovernanceParametersTs ( ) external view returns ( uint256 ); Returns the timestamp, in seconds since UNIX epoch, when the scheduled new settings will take effect. getVotePowerIntervalFraction # Defined in FtsoManager ( Docs , Source ). function getVotePowerIntervalFraction ( ) external view returns ( uint256 ); governance # Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address. notInitializedFtsos # Defined in FtsoManager ( Docs , Source ). function notInitializedFtsos ( contract IIFtso _ftso ) external view returns ( bool ); Returns whether an FTSO has been initialized. Returns Type Description [0] bool bool Initialization state. removeFtso # Defined in FtsoManager ( Docs , Source ). function removeFtso ( contract IIFtso _ftso ) external ; Removes an FTSO from the list of managed FTSOs. Reverts if FTSO is used in a multi-asset FTSO. Deactivates the _ftso . Only governance can call this method. Parameters Type Description _ftso contract IIFtso FTSO contract address to remove. replaceFtso # Defined in FtsoManager ( Docs , Source ). function replaceFtso ( contract IIFtso _ftsoToAdd , bool _copyCurrentPrice , bool _copyAssetOrAssetFtsos ) external ; Replaces one FTSO with another with the same symbol. All FTSOs in a multi-asset FTSO must be managed by the same FTSO manager. Deactivates the old FTSO. Only governance can call this method. Parameters Type Description _ftsoToAdd contract IIFtso FTSO contract address to add. An existing FTSO with the same symbol will be removed. _copyCurrentPrice bool _copyAssetOrAssetFtsos bool replaceFtsosBulk # Defined in FtsoManager ( Docs , Source ). function replaceFtsosBulk ( contract IIFtso [] _ftsosToAdd , bool _copyCurrentPrice , bool _copyAssetOrAssetFtsos ) external ; Replaces a list of FTSOs with other FTSOs with the same symbol. All FTSOs in a multi-asset FTSO must be managed by the same FTSO manager. Deactivates the old FTSOs. Only governance can call this method. Parameters Type Description _ftsosToAdd contract IIFtso[] Array of FTSO contract addresses to add. Every existing FTSO with the same symbols will be removed. _copyCurrentPrice bool _copyAssetOrAssetFtsos bool rewardEpochDurationSeconds # Defined in IIFtsoManager ( Docs , Source ). function rewardEpochDurationSeconds ( ) external view returns ( uint256 ); Currently configured reward epoch duration. Returns Type Description [0] uint256 uint256 Reward epoch duration, in seconds. rewardEpochs # Defined in FtsoManager ( Docs , Source ). function rewardEpochs ( uint256 _rewardEpochId ) external view returns ( uint256 _votepowerBlock , uint256 _startBlock , uint256 _startTimestamp ); Returns information about a reward epoch. Parameters Type Description _rewardEpochId uint256 The epoch ID to query. Returns Type Description _votepowerBlock uint256 The vote power block of the epoch. _startBlock uint256 The first block of the epoch. _startTimestamp uint256 Timestamp of the epoch start, in seconds since UNIX epoch. rewardEpochsStartTs # Defined in IIFtsoManager ( Docs , Source ). function rewardEpochsStartTs ( ) external view returns ( uint256 ); Time when the current reward epoch started. Returns Type Description [0] uint256 uint256 Timestamp, in seconds since UNIX epoch. setElasticBandWidthPPMFtsos # Defined in FtsoManager ( Docs , Source ). function setElasticBandWidthPPMFtsos ( uint256 _updateTs , contract IIFtso [] _ftsos , uint256 [] _widths ) external ; Sets elastic band widths in PPM (parts-per-million) for given FTSOs. Only governance can call this method. Parameters Type Description _updateTs uint256 Timestamp when the changes will take effect, in seconds from UNIX epoch. _ftsos contract IIFtso[] Array of FTSO contract addresses to update. _widths uint256[] Array of secondary band widths in PPM. To obtain the actual band width, this number is divided by 10^6 and multiplied by the price median value. setFallbackMode # Defined in FtsoManager ( Docs , Source ). function setFallbackMode ( bool _fallbackMode ) external ; Sets whether the FTSO Manager is currently in fallback mode. In this mode only submissions from trusted providers are used. Only governance can call this method. Parameters Type Description _fallbackMode bool True if fallback mode is enabled. setFtsoAsset # Defined in FtsoManager ( Docs , Source ). function setFtsoAsset ( contract IIFtso _ftso , contract IIVPToken _asset ) external ; Sets the asset tracked by an FTSO. Only governance can call this method. Parameters Type Description _ftso contract IIFtso The FTSO contract address. _asset contract IIVPToken The VPToken contract address of the asset to track. setFtsoAssetFtsos # Defined in FtsoManager ( Docs , Source ). function setFtsoAssetFtsos ( contract IIFtso _ftso , contract IIFtso [] _assetFtsos ) external ; Sets an array of FTSOs to be tracked by a multi-asset FTSO. FTSOs implicitly determine the FTSO assets. Only governance can call this method. Parameters Type Description _ftso contract IIFtso The multi-asset FTSO contract address. _assetFtsos contract IIFtso[] Array of FTSOs to be tracked. setFtsoFallbackMode # Defined in FtsoManager ( Docs , Source ). function setFtsoFallbackMode ( contract IIFtso _ftso , bool _fallbackMode ) external ; Sets whether an FTSO is currently in fallback mode. In this mode only submissions from trusted providers are used. Only governance can call this method. Parameters Type Description _ftso contract IIFtso The FTSO contract address. _fallbackMode bool Fallback mode. setGovernanceParameters # Defined in FtsoManager ( Docs , Source ). function setGovernanceParameters ( uint256 _updateTs , uint256 _maxVotePowerNatThresholdFraction , uint256 _maxVotePowerAssetThresholdFraction , uint256 _lowAssetUSDThreshold , uint256 _highAssetUSDThreshold , uint256 _highAssetTurnoutThresholdBIPS , uint256 _lowNatTurnoutThresholdBIPS , uint256 _elasticBandRewardBIPS , uint256 _rewardExpiryOffsetSeconds , address [] _trustedAddresses ) external ; Sets governance parameters for FTSOs Only governance can call this method. Parameters Type Description _updateTs uint256 Time, in seconds since UNIX epoch, when updated settings should be pushed to FTSOs. _maxVotePowerNatThresholdFraction uint256 High threshold for native token vote power per voter. _maxVotePowerAssetThresholdFraction uint256 High threshold for asset vote power per voter _lowAssetUSDThreshold uint256 Threshold for low asset vote power (in scaled USD). _highAssetUSDThreshold uint256 Threshold for high asset vote power (in scaled USD). _highAssetTurnoutThresholdBIPS uint256 Threshold for high asset turnout (in BIPS). _lowNatTurnoutThresholdBIPS uint256 Threshold for low nat turnout (in BIPS). _elasticBandRewardBIPS uint256 Secondary reward band, where _elasticBandRewardBIPS goes to the secondary band and 10000 - _elasticBandRewardBIPS to the primary (IQR) band. _rewardExpiryOffsetSeconds uint256 Reward epochs closed earlier than block.timestamp - _rewardExpiryOffsetSeconds expire. _trustedAddresses address[] Trusted addresses will be used as a fallback mechanism for setting the price. setInitialRewardData # Defined in FtsoManager ( Docs , Source ). function setInitialRewardData ( uint256 _nextRewardEpochToExpire , uint256 _rewardEpochsLength , uint256 _currentRewardEpochEnds ) external ; Set reward data to values from old ftso manager. Can only be called before activation. Only governance can call this method. Parameters Type Description _nextRewardEpochToExpire uint256 See getRewardEpochToExpireNext . _rewardEpochsLength uint256 See getRewardEpochConfiguration . _currentRewardEpochEnds uint256 See getCurrentRewardEpoch . setRewardEpochDurationSeconds # Defined in FtsoManager ( Docs , Source ). function setRewardEpochDurationSeconds ( uint256 _rewardEpochDurationSeconds ) external ; Sets the reward epoch duration. Only governance can call this method. If the reward epoch is very short and the expiry offset is very long, the list of reward epochs to be checked becomes very long. Therefore reward epoch time has to be capped to expiry offset. setUpdateOnRewardEpochSwitchover # Defined in FtsoManager ( Docs , Source ). function setUpdateOnRewardEpochSwitchover ( contract IUpdateValidators _updateValidators ) external ; Unused. setUseGoodRandom # Defined in FtsoManager ( Docs , Source ). function setUseGoodRandom ( bool _useGoodRandom , uint256 _maxWaitForGoodRandomSeconds ) external ; Allow governance to switch to good random numbers only. Only governance can call this method. See IFtsoManager . UseGoodRandomSet . Parameters Type Description _useGoodRandom bool Whether good random numbers should be used or not. _maxWaitForGoodRandomSeconds uint256 Max time in seconds to wait for the good random. If there is none after given time, reward epoch finalization should proceed anyway. setVotePowerIntervalFraction # Defined in FtsoManager ( Docs , Source ). function setVotePowerIntervalFraction ( uint256 _votePowerIntervalFraction ) external ; showLastRevertedError # Defined in RevertErrorTracking ( Docs , Source ). function showLastRevertedError ( ) external view returns ( uint256 [] _lastErrorBlock , uint256 [] _numErrors , string [] _errorString , address [] _erroringContract , uint256 _totalRevertedErrors ); Returns latest error information. All arrays will contain only one entry. Returns Type Description _lastErrorBlock uint256[] Array of block numbers where the errors occurred. _numErrors uint256[] Array of number of times same error with same contract address has been reverted. _errorString string[] Array of revert error messages. _erroringContract address[] Array of addresses of the reverting contracts. _totalRevertedErrors uint256 Total number of revert errors across all contracts. showRevertedErrors # Defined in RevertErrorTracking ( Docs , Source ). function showRevertedErrors ( uint256 startIndex , uint256 numErrorTypesToShow ) public view returns ( uint256 [] _lastErrorBlock , uint256 [] _numErrors , string [] _errorString , address [] _erroringContract , uint256 _totalRevertedErrors ); Returns latest errors. Parameters Type Description startIndex uint256 Starting index in the error list array. numErrorTypesToShow uint256 Number of errors to show. The total amount can be found in errorData . Returns Type Description _lastErrorBlock uint256[] Array of block numbers where the errors occurred. _numErrors uint256[] Array of number of times same error with same contract address has been reverted. _errorString string[] Array of revert error messages. _erroringContract address[] Array of addresses of the reverting contracts. _totalRevertedErrors uint256 Total number of revert errors across all contracts. switchToFallbackMode # Defined in FtsoManager ( Docs , Source ). function switchToFallbackMode ( ) external returns ( bool ); This function will be called after an error is caught in daemonize . It will switch the contract to a simpler fallback mode, which hopefully works when full mode doesn't. Not every contract needs to support fallback mode ( FtsoManager does), so this method may be empty. Switching back to normal mode is left to the contract (typically a governed method call). This function may be called due to low-gas error, so it shouldn't use more than ~30.000 gas. Only flareDaemon can call this method. Returns Type Description [0] bool True if switched to fallback mode, false if already in fallback mode or if fallback mode is not supported. switchToProductionMode # Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered . updateContractAddresses # Defined in AddressUpdatable ( Docs , Source ). function updateContractAddresses ( bytes32 [] _contractNameHashes , address [] _contractAddresses ) external ; External method called from AddressUpdater only. voterWhitelister # Defined in FtsoManager ( Docs , Source ). function voterWhitelister ( ) external view returns ( contract IIVoterWhitelister ); Returns the VoterWhitelister contract address. Variables # MAX_TRUSTED_ADDRESSES_LENGTH # Defined in FtsoManager ( Docs , Source ). uint256 MAX_TRUSTED_ADDRESSES_LENGTH Maximum number of trusted addresses allowed. active # Defined in FtsoManager ( Docs , Source ). bool active Whether the FTSO Manager is active or not. cleanupBlockNumberManager # Defined in FtsoManager ( Docs , Source ). contract CleanupBlockNumberManager cleanupBlockNumberManager Address of the CleanupBlockNumberManager contract. currentRewardEpochEnds # Defined in FtsoManager ( Docs , Source ). uint256 currentRewardEpochEnds Timestamp when the current reward epoch finishes, in seconds since UNIX epoch. errorData # Defined in RevertErrorTracking ( Docs , Source ). struct RevertErrorTracking . LastErrorData errorData Most recent error information. flareDaemon # Defined in GovernedAndFlareDaemonized ( Docs , Source ). contract FlareDaemon flareDaemon The FlareDaemon contract, set at construction time. governanceSettings # Defined in GovernedBase ( Docs , Source ). contract IGovernanceSettings governanceSettings Governance Settings. lastRewardedFtsoAddress # Defined in FtsoManager ( Docs , Source ). address lastRewardedFtsoAddress Address of the FTSO contract that was last chosen for reward calculations. maxWaitForGoodRandomSeconds # Defined in FtsoManager ( Docs , Source ). uint256 maxWaitForGoodRandomSeconds Used only when useGoodRandom flag is set. oldFtsoManager # Defined in FtsoManager ( Docs , Source ). contract IIFtsoManagerV1 oldFtsoManager Previous FTSO Manager, in case of a redeployment. priceSubmitter # Defined in FtsoManager ( Docs , Source ). contract IIPriceSubmitter priceSubmitter Address of the PriceSubmitter contract. productionMode # Defined in GovernedBase ( Docs , Source ). bool productionMode When true, governance is enabled and cannot be disabled. See switchToProductionMode . rewardEpochDurationSeconds # Defined in FtsoManager ( Docs , Source ). uint256 rewardEpochDurationSeconds Duration of reward epochs, in seconds. rewardEpochsStartTs # Defined in FtsoManager ( Docs , Source ). uint256 rewardEpochsStartTs Timestamp when the first reward epoch started, in seconds since UNIX epoch. rewardManager # Defined in FtsoManager ( Docs , Source ). contract IIFtsoRewardManager rewardManager Address of the RewardManager contract. supply # Defined in FtsoManager ( Docs , Source ). contract IISupply supply timelockedCalls # Defined in GovernedBase ( Docs , Source ). mapping ( bytes4 => struct GovernedBase . TimelockedCall ) timelockedCalls List of pending timelocked governance calls. updateOnRewardEpochSwitchover # Defined in FtsoManager ( Docs , Source ). contract IUpdateValidators updateOnRewardEpochSwitchover Unused. useGoodRandom # Defined in FtsoManager ( Docs , Source ). bool useGoodRandom Whether use of good random numbers is enforced. See IFtsoManager . UseGoodRandomSet . waitingForGoodRandomSinceTs # Defined in FtsoManager ( Docs , Source ). uint256 waitingForGoodRandomSinceTs Used only when useGoodRandom flag is set.","title":"FtsoManager"},{"location":"apis/smart-contracts/FtsoManager/#ct_ftsomanager","text":"Source | Inherits from IIFtsoManager , GovernedAndFlareDaemonized , AddressUpdatable , RevertErrorTracking FTSO Manager contract. It is in charge of: Defining reward epochs (few days). Choosing a single block each reward epoch that represents vote power of this epoch. Keeping track of all FTSO contracts. Every price epoch (few minutes): Randomly choose one FTSO for rewarding calculations. Trigger finalize price reveal epoch. Determine addresses and reward weights and triggers reward distribution.","title":"FtsoManager"},{"location":"apis/smart-contracts/FtsoManager/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/FtsoManager/#fn_activate_0f15f4c0","text":"Defined in FtsoManager ( Docs , Source ). function activate ( ) external ; Activates FTSO manager ( daemonize will run jobs). Only governance can call this method.","title":"activate"},{"location":"apis/smart-contracts/FtsoManager/#fn_active_02fb0c5e","text":"Defined in IFtsoManager ( Docs , Source ). function active ( ) external view returns ( bool ); Returns whether the FTSO Manager is active or not. Returns Type Description [0] bool bool Active status.","title":"active"},{"location":"apis/smart-contracts/FtsoManager/#fn_addftso_2663f1b4","text":"Defined in FtsoManager ( Docs , Source ). function addFtso ( contract IIFtso _ftso ) external ; Adds FTSO to the list of managed FTSOs, to support a new price pair. All FTSOs in a multi-asset FTSO must be managed by the same FTSO manager. Only governance can call this method. Parameters Type Description _ftso contract IIFtso FTSO contract address to add.","title":"addFtso"},{"location":"apis/smart-contracts/FtsoManager/#fn_addftsosbulk_d429cfe5","text":"Defined in FtsoManager ( Docs , Source ). function addFtsosBulk ( contract IIFtso [] _ftsos ) external ; Adds a list of FTSOs to the list of managed FTSOs, to support new price pairs. All FTSOs in a multi-asset FTSO must be managed by the same FTSO manager. Only governance can call this method. Parameters Type Description _ftsos contract IIFtso[] Array of FTSO contract addresses to add.","title":"addFtsosBulk"},{"location":"apis/smart-contracts/FtsoManager/#fn_cancelgovernancecall_67fc4029","text":"Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector.","title":"cancelGovernanceCall"},{"location":"apis/smart-contracts/FtsoManager/#fn_constructor_undefined","text":"Defined in FtsoManager ( Docs , Source ). constructor ( address _governance , contract FlareDaemon _flareDaemon , address _addressUpdater , contract IIFtsoManagerV1 _oldFtsoManager , uint256 _firstPriceEpochStartTs , uint256 _priceEpochDurationSeconds , uint256 _revealEpochDurationSeconds , uint256 _firstRewardEpochStartTs , uint256 _rewardEpochDurationSeconds , uint256 _votePowerIntervalFraction ) public ;","title":"constructor"},{"location":"apis/smart-contracts/FtsoManager/#fn_constructor_undefined","text":"Defined in GovernedAndFlareDaemonized ( Docs , Source ). constructor ( address _governance , contract FlareDaemon _flareDaemon ) public ;","title":"constructor"},{"location":"apis/smart-contracts/FtsoManager/#fn_constructor_undefined","text":"Defined in Governed ( Docs , Source ). constructor ( address _governance ) public ; Parameters Type Description _governance address Governance contract. Must not be zero.","title":"constructor"},{"location":"apis/smart-contracts/FtsoManager/#fn_currentrewardepochends_d89c39e6","text":"Defined in IIFtsoManager ( Docs , Source ). function currentRewardEpochEnds ( ) external view returns ( uint256 ); Returns when the current reward epoch finishes. Returns Type Description [0] uint256 uint256 Time in seconds since the UNIX epoch when the current reward epoch will finish.","title":"currentRewardEpochEnds"},{"location":"apis/smart-contracts/FtsoManager/#fn_daemonize_6d0e8c34","text":"Defined in FtsoManager ( Docs , Source ). function daemonize ( ) external returns ( bool ); Implement this function to receive a trigger from the FlareDaemon . The trigger method is called by the validator right at the end of block state transition. Only flareDaemon can call this method. Returns Type Description [0] bool bool Whether the contract is still active after the call. Currently unused.","title":"daemonize"},{"location":"apis/smart-contracts/FtsoManager/#fn_deactivateftsos_8de306b1","text":"Defined in FtsoManager ( Docs , Source ). function deactivateFtsos ( contract IIFtso [] _ftsos ) external ; Deactivates FTSOs that are no longer used on FTSO registry. Only governance can call this method. Parameters Type Description _ftsos contract IIFtso[] Array of FTSO contract addresses to deactivate.","title":"deactivateFtsos"},{"location":"apis/smart-contracts/FtsoManager/#fn_executegovernancecall_5ff27079","text":"Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored).","title":"executeGovernanceCall"},{"location":"apis/smart-contracts/FtsoManager/#fn_ftsoregistry_38b5f869","text":"Defined in FtsoManager ( Docs , Source ). function ftsoRegistry ( ) external view returns ( contract IIFtsoRegistry ); Returns the FtsoRegistry contract address.","title":"ftsoRegistry"},{"location":"apis/smart-contracts/FtsoManager/#fn_getaddressupdater_5267a15d","text":"Defined in AddressUpdatable ( Docs , Source ). function getAddressUpdater ( ) public view returns ( address _addressUpdater ); Returns the configured address updater. Returns Type Description _addressUpdater address The AddresUpdater contract that can update our contract address list, as a response to a governance call.","title":"getAddressUpdater"},{"location":"apis/smart-contracts/FtsoManager/#fn_getcontractname_f5f5ba72","text":"Defined in FtsoManager ( Docs , Source ). function getContractName ( ) external pure returns ( string ); Implement this function to allow updating daemonized contracts through the AddressUpdater . Returns Type Description [0] string string Contract name.","title":"getContractName"},{"location":"apis/smart-contracts/FtsoManager/#fn_getcurrentpriceepochdata_93a79025","text":"Defined in FtsoManager ( Docs , Source ). function getCurrentPriceEpochData ( ) external view returns ( uint256 _priceEpochId , uint256 _priceEpochStartTimestamp , uint256 _priceEpochEndTimestamp , uint256 _priceEpochRevealEndTimestamp , uint256 _currentTimestamp ); Returns timing information for the current price epoch. All intervals are half-closed: end time is not included. All timestamps are in seconds since UNIX epoch. See the FTSO page for information about the different submission phases. Returns Type Description _priceEpochId uint256 Price epoch ID. _priceEpochStartTimestamp uint256 Beginning of the commit phase. _priceEpochEndTimestamp uint256 End of the commit phase. _priceEpochRevealEndTimestamp uint256 End of the reveal phase. _currentTimestamp uint256 Current time.","title":"getCurrentPriceEpochData"},{"location":"apis/smart-contracts/FtsoManager/#fn_getcurrentpriceepochid_08a7f402","text":"Defined in FtsoManager ( Docs , Source ). function getCurrentPriceEpochId ( ) external view returns ( uint256 _priceEpochId ); Returns current price epoch ID. Returns Type Description _priceEpochId uint256 Currently running epoch ID. IDs are consecutive numbers starting from zero.","title":"getCurrentPriceEpochId"},{"location":"apis/smart-contracts/FtsoManager/#fn_getcurrentrewardepoch_e7c830d4","text":"Defined in FtsoManager ( Docs , Source ). function getCurrentRewardEpoch ( ) external view returns ( uint256 ); Returns current reward epoch ID (the one currently running). Returns Type Description [0] uint256 Reward epoch ID. A monotonically increasing integer.","title":"getCurrentRewardEpoch"},{"location":"apis/smart-contracts/FtsoManager/#fn_getelasticbandwidthppmftso_5bb44e9a","text":"Defined in FtsoManager ( Docs , Source ). function getElasticBandWidthPPMFtso ( contract IIFtso _ftso ) external view returns ( uint256 ); Returns the secondary band's width in PPM (parts-per-million) of the median value, for a given FTSO. Parameters Type Description _ftso contract IIFtso The queried FTSO contract address. Returns Type Description [0] uint256 uint256 Secondary band width in PPM. To obtain the actual band width, divide this number by 10^6 and multiply by the price median value.","title":"getElasticBandWidthPPMFtso"},{"location":"apis/smart-contracts/FtsoManager/#fn_getfallbackmode_4b48dd5e","text":"Defined in FtsoManager ( Docs , Source ). function getFallbackMode ( ) external view returns ( bool _fallbackMode , contract IIFtso [] _ftsos , bool [] _ftsoInFallbackMode ); Returns whether the FTSO Manager is currently in fallback mode. In this mode only submissions from trusted providers are used. Returns Type Description _fallbackMode bool True if fallback mode is enabled for the manager. _ftsos contract IIFtso[] Array of all currently active FTSO assets. _ftsoInFallbackMode bool[] Boolean array indicating which FTSO assets are in fallback mode. If the FTSO Manager is in fallback mode then ALL FTSOs are in fallback mode.","title":"getFallbackMode"},{"location":"apis/smart-contracts/FtsoManager/#fn_getftsos_ce69f833","text":"Defined in FtsoManager ( Docs , Source ). function getFtsos ( ) external view returns ( contract IIFtso [] _ftsos ); Returns the list of currently active FTSOs. Returns Type Description _ftsos contract IIFtso[] Array of contract addresses for the FTSOs.","title":"getFtsos"},{"location":"apis/smart-contracts/FtsoManager/#fn_getgovernanceparameters_5835cf30","text":"Defined in FtsoManager ( Docs , Source ). function getGovernanceParameters ( ) external view returns ( uint256 _maxVotePowerNatThresholdFraction , uint256 _maxVotePowerAssetThresholdFraction , uint256 _lowAssetUSDThreshold , uint256 _highAssetUSDThreshold , uint256 _highAssetTurnoutThresholdBIPS , uint256 _lowNatTurnoutThresholdBIPS , uint256 _elasticBandRewardBIPS , uint256 _rewardExpiryOffsetSeconds , address [] _trustedAddresses , bool _initialized , bool _changed ); Returns governance parameters for FTSOs. Returns Type Description _maxVotePowerNatThresholdFraction uint256 High threshold for native token vote power per voter. _maxVotePowerAssetThresholdFraction uint256 High threshold for asset vote power per voter _lowAssetUSDThreshold uint256 Threshold for low asset vote power (in scaled USD). _highAssetUSDThreshold uint256 Threshold for high asset vote power (in scaled USD). _highAssetTurnoutThresholdBIPS uint256 Threshold for high asset turnout (in BIPS). _lowNatTurnoutThresholdBIPS uint256 Threshold for low nat turnout (in BIPS). _elasticBandRewardBIPS uint256 Secondary reward band, where _elasticBandRewardBIPS goes to the secondary band and 10000 - _elasticBandRewardBIPS to the primary (IQR) band. _rewardExpiryOffsetSeconds uint256 Reward epochs closed earlier than block.timestamp - _rewardExpiryOffsetSeconds expire. _trustedAddresses address[] Trusted addresses will be used as a fallback mechanism for setting the price. _initialized bool _changed bool","title":"getGovernanceParameters"},{"location":"apis/smart-contracts/FtsoManager/#fn_getlastunprocessedpriceepochdata_6ca051e6","text":"Defined in FtsoManager ( Docs , Source ). function getLastUnprocessedPriceEpochData ( ) external view returns ( uint256 _lastUnprocessedPriceEpoch , uint256 _lastUnprocessedPriceEpochRevealEnds , bool _lastUnprocessedPriceEpochInitialized ); Returns information regarding the currently unprocessed price epoch. This epoch is not necessarily the last one, in case the network halts for some time due to validator node problems, for example. Returns Type Description _lastUnprocessedPriceEpoch uint256 ID of the price epoch that is currently waiting finalization. _lastUnprocessedPriceEpochRevealEnds uint256 When that price epoch can be finalized, in seconds since UNIX epoch. _lastUnprocessedPriceEpochInitialized bool Whether this price epoch has been already initialized and therefore it must be finalized before the corresponding reward epoch can be finalized.","title":"getLastUnprocessedPriceEpochData"},{"location":"apis/smart-contracts/FtsoManager/#fn_getpriceepochconfiguration_144e1591","text":"Defined in FtsoManager ( Docs , Source ). function getPriceEpochConfiguration ( ) external view returns ( uint256 _firstPriceEpochStartTs , uint256 _priceEpochDurationSeconds , uint256 _revealEpochDurationSeconds ); Returns the current values for price epoch timing configuration. See the FTSO page for information about the different submission phases. Returns Type Description _firstPriceEpochStartTs uint256 Timestamp, in seconds since UNIX epoch, of the first price epoch. _priceEpochDurationSeconds uint256 Duration in seconds of the commit phase. _revealEpochDurationSeconds uint256 Duration in seconds of the reveal phase.","title":"getPriceEpochConfiguration"},{"location":"apis/smart-contracts/FtsoManager/#fn_getpricesubmitter_0e063d7d","text":"Defined in FtsoManager ( Docs , Source ). function getPriceSubmitter ( ) external view returns ( contract IIPriceSubmitter ); Returns the PriceSubmitter contract.","title":"getPriceSubmitter"},{"location":"apis/smart-contracts/FtsoManager/#fn_getrewardepochconfiguration_1cb513f7","text":"Defined in FtsoManager ( Docs , Source ). function getRewardEpochConfiguration ( ) external view returns ( uint256 _firstRewardEpochStartTs , uint256 _rewardEpochDurationSeconds ); Returns the current values for reward epoch timing configuration. See the Reward epochs box. Returns Type Description _firstRewardEpochStartTs uint256 Timestamp, in seconds since UNIX epoch, of the first reward epoch. _rewardEpochDurationSeconds uint256 Duration in seconds of the reward epochs.","title":"getRewardEpochConfiguration"},{"location":"apis/smart-contracts/FtsoManager/#fn_getrewardepochdata_e5399da3","text":"Defined in FtsoManager ( Docs , Source ). function getRewardEpochData ( uint256 _rewardEpochId ) public view returns ( struct IIFtsoManager . RewardEpochData ); Returns data regarding a specific reward epoch ID. Parameters Type Description _rewardEpochId uint256 Epoch ID. Returns Type Description [0] struct IIFtsoManager.RewardEpochData RewardEpochData Its associated data.","title":"getRewardEpochData"},{"location":"apis/smart-contracts/FtsoManager/#fn_getrewardepochtoexpirenext_3e7ff857","text":"Defined in FtsoManager ( Docs , Source ). function getRewardEpochToExpireNext ( ) external view returns ( uint256 ); Return reward epoch that will expire next, when a new reward epoch is initialized. Reward epochs older than 90 days expire, and any unclaimed rewards in them become inaccessible. Returns Type Description [0] uint256 uint256 Reward epoch ID.","title":"getRewardEpochToExpireNext"},{"location":"apis/smart-contracts/FtsoManager/#fn_getrewardepochvotepowerblock_f2edab5a","text":"Defined in FtsoManager ( Docs , Source ). function getRewardEpochVotePowerBlock ( uint256 _rewardEpoch ) external view returns ( uint256 _votepowerBlock ); Returns the vote power block that was used for a past reward epoch. Parameters Type Description _rewardEpoch uint256 The queried reward epoch ID. Returns Type Description _votepowerBlock uint256 uint256 The block number of that reward epoch's vote power block.","title":"getRewardEpochVotePowerBlock"},{"location":"apis/smart-contracts/FtsoManager/#fn_getrewardexpiryoffsetseconds_ec31db0c","text":"Defined in FtsoManager ( Docs , Source ). function getRewardExpiryOffsetSeconds ( ) external view returns ( uint256 ); Returns the currently configured reward expiration time. Returns Type Description [0] uint256 uint256 Unclaimed rewards accrued in reward epochs more than this amount of seconds in the past expire and become inaccessible.","title":"getRewardExpiryOffsetSeconds"},{"location":"apis/smart-contracts/FtsoManager/#fn_getupdategovernanceparametersts_a157713b","text":"Defined in FtsoManager ( Docs , Source ). function getUpdateGovernanceParametersTs ( ) external view returns ( uint256 ); Returns the timestamp, in seconds since UNIX epoch, when the scheduled new settings will take effect.","title":"getUpdateGovernanceParametersTs"},{"location":"apis/smart-contracts/FtsoManager/#fn_getvotepowerintervalfraction_60f2c5b2","text":"Defined in FtsoManager ( Docs , Source ). function getVotePowerIntervalFraction ( ) external view returns ( uint256 );","title":"getVotePowerIntervalFraction"},{"location":"apis/smart-contracts/FtsoManager/#fn_governance_5aa6e675","text":"Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address.","title":"governance"},{"location":"apis/smart-contracts/FtsoManager/#fn_notinitializedftsos_823033a9","text":"Defined in FtsoManager ( Docs , Source ). function notInitializedFtsos ( contract IIFtso _ftso ) external view returns ( bool ); Returns whether an FTSO has been initialized. Returns Type Description [0] bool bool Initialization state.","title":"notInitializedFtsos"},{"location":"apis/smart-contracts/FtsoManager/#fn_removeftso_a670ff87","text":"Defined in FtsoManager ( Docs , Source ). function removeFtso ( contract IIFtso _ftso ) external ; Removes an FTSO from the list of managed FTSOs. Reverts if FTSO is used in a multi-asset FTSO. Deactivates the _ftso . Only governance can call this method. Parameters Type Description _ftso contract IIFtso FTSO contract address to remove.","title":"removeFtso"},{"location":"apis/smart-contracts/FtsoManager/#fn_replaceftso_3758e679","text":"Defined in FtsoManager ( Docs , Source ). function replaceFtso ( contract IIFtso _ftsoToAdd , bool _copyCurrentPrice , bool _copyAssetOrAssetFtsos ) external ; Replaces one FTSO with another with the same symbol. All FTSOs in a multi-asset FTSO must be managed by the same FTSO manager. Deactivates the old FTSO. Only governance can call this method. Parameters Type Description _ftsoToAdd contract IIFtso FTSO contract address to add. An existing FTSO with the same symbol will be removed. _copyCurrentPrice bool _copyAssetOrAssetFtsos bool","title":"replaceFtso"},{"location":"apis/smart-contracts/FtsoManager/#fn_replaceftsosbulk_758ff1da","text":"Defined in FtsoManager ( Docs , Source ). function replaceFtsosBulk ( contract IIFtso [] _ftsosToAdd , bool _copyCurrentPrice , bool _copyAssetOrAssetFtsos ) external ; Replaces a list of FTSOs with other FTSOs with the same symbol. All FTSOs in a multi-asset FTSO must be managed by the same FTSO manager. Deactivates the old FTSOs. Only governance can call this method. Parameters Type Description _ftsosToAdd contract IIFtso[] Array of FTSO contract addresses to add. Every existing FTSO with the same symbols will be removed. _copyCurrentPrice bool _copyAssetOrAssetFtsos bool","title":"replaceFtsosBulk"},{"location":"apis/smart-contracts/FtsoManager/#fn_rewardepochdurationseconds_85f3c9c9","text":"Defined in IIFtsoManager ( Docs , Source ). function rewardEpochDurationSeconds ( ) external view returns ( uint256 ); Currently configured reward epoch duration. Returns Type Description [0] uint256 uint256 Reward epoch duration, in seconds.","title":"rewardEpochDurationSeconds"},{"location":"apis/smart-contracts/FtsoManager/#fn_rewardepochs_a795f409","text":"Defined in FtsoManager ( Docs , Source ). function rewardEpochs ( uint256 _rewardEpochId ) external view returns ( uint256 _votepowerBlock , uint256 _startBlock , uint256 _startTimestamp ); Returns information about a reward epoch. Parameters Type Description _rewardEpochId uint256 The epoch ID to query. Returns Type Description _votepowerBlock uint256 The vote power block of the epoch. _startBlock uint256 The first block of the epoch. _startTimestamp uint256 Timestamp of the epoch start, in seconds since UNIX epoch.","title":"rewardEpochs"},{"location":"apis/smart-contracts/FtsoManager/#fn_rewardepochsstartts_a578f55b","text":"Defined in IIFtsoManager ( Docs , Source ). function rewardEpochsStartTs ( ) external view returns ( uint256 ); Time when the current reward epoch started. Returns Type Description [0] uint256 uint256 Timestamp, in seconds since UNIX epoch.","title":"rewardEpochsStartTs"},{"location":"apis/smart-contracts/FtsoManager/#fn_setelasticbandwidthppmftsos_882376c3","text":"Defined in FtsoManager ( Docs , Source ). function setElasticBandWidthPPMFtsos ( uint256 _updateTs , contract IIFtso [] _ftsos , uint256 [] _widths ) external ; Sets elastic band widths in PPM (parts-per-million) for given FTSOs. Only governance can call this method. Parameters Type Description _updateTs uint256 Timestamp when the changes will take effect, in seconds from UNIX epoch. _ftsos contract IIFtso[] Array of FTSO contract addresses to update. _widths uint256[] Array of secondary band widths in PPM. To obtain the actual band width, this number is divided by 10^6 and multiplied by the price median value.","title":"setElasticBandWidthPPMFtsos"},{"location":"apis/smart-contracts/FtsoManager/#fn_setfallbackmode_ff882fbb","text":"Defined in FtsoManager ( Docs , Source ). function setFallbackMode ( bool _fallbackMode ) external ; Sets whether the FTSO Manager is currently in fallback mode. In this mode only submissions from trusted providers are used. Only governance can call this method. Parameters Type Description _fallbackMode bool True if fallback mode is enabled.","title":"setFallbackMode"},{"location":"apis/smart-contracts/FtsoManager/#fn_setftsoasset_6b65cc34","text":"Defined in FtsoManager ( Docs , Source ). function setFtsoAsset ( contract IIFtso _ftso , contract IIVPToken _asset ) external ; Sets the asset tracked by an FTSO. Only governance can call this method. Parameters Type Description _ftso contract IIFtso The FTSO contract address. _asset contract IIVPToken The VPToken contract address of the asset to track.","title":"setFtsoAsset"},{"location":"apis/smart-contracts/FtsoManager/#fn_setftsoassetftsos_a93a6f42","text":"Defined in FtsoManager ( Docs , Source ). function setFtsoAssetFtsos ( contract IIFtso _ftso , contract IIFtso [] _assetFtsos ) external ; Sets an array of FTSOs to be tracked by a multi-asset FTSO. FTSOs implicitly determine the FTSO assets. Only governance can call this method. Parameters Type Description _ftso contract IIFtso The multi-asset FTSO contract address. _assetFtsos contract IIFtso[] Array of FTSOs to be tracked.","title":"setFtsoAssetFtsos"},{"location":"apis/smart-contracts/FtsoManager/#fn_setftsofallbackmode_af946af7","text":"Defined in FtsoManager ( Docs , Source ). function setFtsoFallbackMode ( contract IIFtso _ftso , bool _fallbackMode ) external ; Sets whether an FTSO is currently in fallback mode. In this mode only submissions from trusted providers are used. Only governance can call this method. Parameters Type Description _ftso contract IIFtso The FTSO contract address. _fallbackMode bool Fallback mode.","title":"setFtsoFallbackMode"},{"location":"apis/smart-contracts/FtsoManager/#fn_setgovernanceparameters_13226793","text":"Defined in FtsoManager ( Docs , Source ). function setGovernanceParameters ( uint256 _updateTs , uint256 _maxVotePowerNatThresholdFraction , uint256 _maxVotePowerAssetThresholdFraction , uint256 _lowAssetUSDThreshold , uint256 _highAssetUSDThreshold , uint256 _highAssetTurnoutThresholdBIPS , uint256 _lowNatTurnoutThresholdBIPS , uint256 _elasticBandRewardBIPS , uint256 _rewardExpiryOffsetSeconds , address [] _trustedAddresses ) external ; Sets governance parameters for FTSOs Only governance can call this method. Parameters Type Description _updateTs uint256 Time, in seconds since UNIX epoch, when updated settings should be pushed to FTSOs. _maxVotePowerNatThresholdFraction uint256 High threshold for native token vote power per voter. _maxVotePowerAssetThresholdFraction uint256 High threshold for asset vote power per voter _lowAssetUSDThreshold uint256 Threshold for low asset vote power (in scaled USD). _highAssetUSDThreshold uint256 Threshold for high asset vote power (in scaled USD). _highAssetTurnoutThresholdBIPS uint256 Threshold for high asset turnout (in BIPS). _lowNatTurnoutThresholdBIPS uint256 Threshold for low nat turnout (in BIPS). _elasticBandRewardBIPS uint256 Secondary reward band, where _elasticBandRewardBIPS goes to the secondary band and 10000 - _elasticBandRewardBIPS to the primary (IQR) band. _rewardExpiryOffsetSeconds uint256 Reward epochs closed earlier than block.timestamp - _rewardExpiryOffsetSeconds expire. _trustedAddresses address[] Trusted addresses will be used as a fallback mechanism for setting the price.","title":"setGovernanceParameters"},{"location":"apis/smart-contracts/FtsoManager/#fn_setinitialrewarddata_e080a970","text":"Defined in FtsoManager ( Docs , Source ). function setInitialRewardData ( uint256 _nextRewardEpochToExpire , uint256 _rewardEpochsLength , uint256 _currentRewardEpochEnds ) external ; Set reward data to values from old ftso manager. Can only be called before activation. Only governance can call this method. Parameters Type Description _nextRewardEpochToExpire uint256 See getRewardEpochToExpireNext . _rewardEpochsLength uint256 See getRewardEpochConfiguration . _currentRewardEpochEnds uint256 See getCurrentRewardEpoch .","title":"setInitialRewardData"},{"location":"apis/smart-contracts/FtsoManager/#fn_setrewardepochdurationseconds_132c7e1f","text":"Defined in FtsoManager ( Docs , Source ). function setRewardEpochDurationSeconds ( uint256 _rewardEpochDurationSeconds ) external ; Sets the reward epoch duration. Only governance can call this method. If the reward epoch is very short and the expiry offset is very long, the list of reward epochs to be checked becomes very long. Therefore reward epoch time has to be capped to expiry offset.","title":"setRewardEpochDurationSeconds"},{"location":"apis/smart-contracts/FtsoManager/#fn_setupdateonrewardepochswitchover_3fdeb7e1","text":"Defined in FtsoManager ( Docs , Source ). function setUpdateOnRewardEpochSwitchover ( contract IUpdateValidators _updateValidators ) external ; Unused.","title":"setUpdateOnRewardEpochSwitchover"},{"location":"apis/smart-contracts/FtsoManager/#fn_setusegoodrandom_a90a38e1","text":"Defined in FtsoManager ( Docs , Source ). function setUseGoodRandom ( bool _useGoodRandom , uint256 _maxWaitForGoodRandomSeconds ) external ; Allow governance to switch to good random numbers only. Only governance can call this method. See IFtsoManager . UseGoodRandomSet . Parameters Type Description _useGoodRandom bool Whether good random numbers should be used or not. _maxWaitForGoodRandomSeconds uint256 Max time in seconds to wait for the good random. If there is none after given time, reward epoch finalization should proceed anyway.","title":"setUseGoodRandom"},{"location":"apis/smart-contracts/FtsoManager/#fn_setvotepowerintervalfraction_361b5459","text":"Defined in FtsoManager ( Docs , Source ). function setVotePowerIntervalFraction ( uint256 _votePowerIntervalFraction ) external ;","title":"setVotePowerIntervalFraction"},{"location":"apis/smart-contracts/FtsoManager/#fn_showlastrevertederror_2b3c41a4","text":"Defined in RevertErrorTracking ( Docs , Source ). function showLastRevertedError ( ) external view returns ( uint256 [] _lastErrorBlock , uint256 [] _numErrors , string [] _errorString , address [] _erroringContract , uint256 _totalRevertedErrors ); Returns latest error information. All arrays will contain only one entry. Returns Type Description _lastErrorBlock uint256[] Array of block numbers where the errors occurred. _numErrors uint256[] Array of number of times same error with same contract address has been reverted. _errorString string[] Array of revert error messages. _erroringContract address[] Array of addresses of the reverting contracts. _totalRevertedErrors uint256 Total number of revert errors across all contracts.","title":"showLastRevertedError"},{"location":"apis/smart-contracts/FtsoManager/#fn_showrevertederrors_6ea0aa31","text":"Defined in RevertErrorTracking ( Docs , Source ). function showRevertedErrors ( uint256 startIndex , uint256 numErrorTypesToShow ) public view returns ( uint256 [] _lastErrorBlock , uint256 [] _numErrors , string [] _errorString , address [] _erroringContract , uint256 _totalRevertedErrors ); Returns latest errors. Parameters Type Description startIndex uint256 Starting index in the error list array. numErrorTypesToShow uint256 Number of errors to show. The total amount can be found in errorData . Returns Type Description _lastErrorBlock uint256[] Array of block numbers where the errors occurred. _numErrors uint256[] Array of number of times same error with same contract address has been reverted. _errorString string[] Array of revert error messages. _erroringContract address[] Array of addresses of the reverting contracts. _totalRevertedErrors uint256 Total number of revert errors across all contracts.","title":"showRevertedErrors"},{"location":"apis/smart-contracts/FtsoManager/#fn_switchtofallbackmode_e22fdece","text":"Defined in FtsoManager ( Docs , Source ). function switchToFallbackMode ( ) external returns ( bool ); This function will be called after an error is caught in daemonize . It will switch the contract to a simpler fallback mode, which hopefully works when full mode doesn't. Not every contract needs to support fallback mode ( FtsoManager does), so this method may be empty. Switching back to normal mode is left to the contract (typically a governed method call). This function may be called due to low-gas error, so it shouldn't use more than ~30.000 gas. Only flareDaemon can call this method. Returns Type Description [0] bool True if switched to fallback mode, false if already in fallback mode or if fallback mode is not supported.","title":"switchToFallbackMode"},{"location":"apis/smart-contracts/FtsoManager/#fn_switchtoproductionmode_f5a98383","text":"Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered .","title":"switchToProductionMode"},{"location":"apis/smart-contracts/FtsoManager/#fn_updatecontractaddresses_b00c0b76","text":"Defined in AddressUpdatable ( Docs , Source ). function updateContractAddresses ( bytes32 [] _contractNameHashes , address [] _contractAddresses ) external ; External method called from AddressUpdater only.","title":"updateContractAddresses"},{"location":"apis/smart-contracts/FtsoManager/#fn_voterwhitelister_c2b0d47b","text":"Defined in FtsoManager ( Docs , Source ). function voterWhitelister ( ) external view returns ( contract IIVoterWhitelister ); Returns the VoterWhitelister contract address.","title":"voterWhitelister"},{"location":"apis/smart-contracts/FtsoManager/#variables","text":"","title":"Variables"},{"location":"apis/smart-contracts/FtsoManager/#va_max_trusted_addresses_length","text":"Defined in FtsoManager ( Docs , Source ). uint256 MAX_TRUSTED_ADDRESSES_LENGTH Maximum number of trusted addresses allowed.","title":"MAX_TRUSTED_ADDRESSES_LENGTH"},{"location":"apis/smart-contracts/FtsoManager/#va_active","text":"Defined in FtsoManager ( Docs , Source ). bool active Whether the FTSO Manager is active or not.","title":"active"},{"location":"apis/smart-contracts/FtsoManager/#va_cleanupblocknumbermanager","text":"Defined in FtsoManager ( Docs , Source ). contract CleanupBlockNumberManager cleanupBlockNumberManager Address of the CleanupBlockNumberManager contract.","title":"cleanupBlockNumberManager"},{"location":"apis/smart-contracts/FtsoManager/#va_currentrewardepochends","text":"Defined in FtsoManager ( Docs , Source ). uint256 currentRewardEpochEnds Timestamp when the current reward epoch finishes, in seconds since UNIX epoch.","title":"currentRewardEpochEnds"},{"location":"apis/smart-contracts/FtsoManager/#va_errordata","text":"Defined in RevertErrorTracking ( Docs , Source ). struct RevertErrorTracking . LastErrorData errorData Most recent error information.","title":"errorData"},{"location":"apis/smart-contracts/FtsoManager/#va_flaredaemon","text":"Defined in GovernedAndFlareDaemonized ( Docs , Source ). contract FlareDaemon flareDaemon The FlareDaemon contract, set at construction time.","title":"flareDaemon"},{"location":"apis/smart-contracts/FtsoManager/#va_governancesettings","text":"Defined in GovernedBase ( Docs , Source ). contract IGovernanceSettings governanceSettings Governance Settings.","title":"governanceSettings"},{"location":"apis/smart-contracts/FtsoManager/#va_lastrewardedftsoaddress","text":"Defined in FtsoManager ( Docs , Source ). address lastRewardedFtsoAddress Address of the FTSO contract that was last chosen for reward calculations.","title":"lastRewardedFtsoAddress"},{"location":"apis/smart-contracts/FtsoManager/#va_maxwaitforgoodrandomseconds","text":"Defined in FtsoManager ( Docs , Source ). uint256 maxWaitForGoodRandomSeconds Used only when useGoodRandom flag is set.","title":"maxWaitForGoodRandomSeconds"},{"location":"apis/smart-contracts/FtsoManager/#va_oldftsomanager","text":"Defined in FtsoManager ( Docs , Source ). contract IIFtsoManagerV1 oldFtsoManager Previous FTSO Manager, in case of a redeployment.","title":"oldFtsoManager"},{"location":"apis/smart-contracts/FtsoManager/#va_pricesubmitter","text":"Defined in FtsoManager ( Docs , Source ). contract IIPriceSubmitter priceSubmitter Address of the PriceSubmitter contract.","title":"priceSubmitter"},{"location":"apis/smart-contracts/FtsoManager/#va_productionmode","text":"Defined in GovernedBase ( Docs , Source ). bool productionMode When true, governance is enabled and cannot be disabled. See switchToProductionMode .","title":"productionMode"},{"location":"apis/smart-contracts/FtsoManager/#va_rewardepochdurationseconds","text":"Defined in FtsoManager ( Docs , Source ). uint256 rewardEpochDurationSeconds Duration of reward epochs, in seconds.","title":"rewardEpochDurationSeconds"},{"location":"apis/smart-contracts/FtsoManager/#va_rewardepochsstartts","text":"Defined in FtsoManager ( Docs , Source ). uint256 rewardEpochsStartTs Timestamp when the first reward epoch started, in seconds since UNIX epoch.","title":"rewardEpochsStartTs"},{"location":"apis/smart-contracts/FtsoManager/#va_rewardmanager","text":"Defined in FtsoManager ( Docs , Source ). contract IIFtsoRewardManager rewardManager Address of the RewardManager contract.","title":"rewardManager"},{"location":"apis/smart-contracts/FtsoManager/#va_supply","text":"Defined in FtsoManager ( Docs , Source ). contract IISupply supply","title":"supply"},{"location":"apis/smart-contracts/FtsoManager/#va_timelockedcalls","text":"Defined in GovernedBase ( Docs , Source ). mapping ( bytes4 => struct GovernedBase . TimelockedCall ) timelockedCalls List of pending timelocked governance calls.","title":"timelockedCalls"},{"location":"apis/smart-contracts/FtsoManager/#va_updateonrewardepochswitchover","text":"Defined in FtsoManager ( Docs , Source ). contract IUpdateValidators updateOnRewardEpochSwitchover Unused.","title":"updateOnRewardEpochSwitchover"},{"location":"apis/smart-contracts/FtsoManager/#va_usegoodrandom","text":"Defined in FtsoManager ( Docs , Source ). bool useGoodRandom Whether use of good random numbers is enforced. See IFtsoManager . UseGoodRandomSet .","title":"useGoodRandom"},{"location":"apis/smart-contracts/FtsoManager/#va_waitingforgoodrandomsincets","text":"Defined in FtsoManager ( Docs , Source ). uint256 waitingForGoodRandomSinceTs Used only when useGoodRandom flag is set.","title":"waitingForGoodRandomSinceTs"},{"location":"apis/smart-contracts/FtsoRegistry/","text":"FtsoRegistry # Source | Inherits from IIFtsoRegistry , AddressUpdatable , GovernedBase Handles registration of assets to the FTSO system . Functions # addFtso # Defined in FtsoRegistry ( Docs , Source ). function addFtso ( contract IIFtso _ftsoContract ) external returns ( uint256 _assetIndex ); Add a new FTSO contract to the registry. Only the ftsoManager can call this method. Parameters Type Description _ftsoContract contract IIFtso New target FTSO contract. Returns Type Description _assetIndex uint256 The FTSO index assigned to the new asset. cancelGovernanceCall # Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector. constructor # Defined in FtsoRegistry ( Docs , Source ). constructor ( ) public ; executeGovernanceCall # Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored). getAddressUpdater # Defined in AddressUpdatable ( Docs , Source ). function getAddressUpdater ( ) public view returns ( address _addressUpdater ); Returns the configured address updater. Returns Type Description _addressUpdater address The AddresUpdater contract that can update our contract address list, as a response to a governance call. getAllCurrentPrices # Defined in FtsoRegistry ( Docs , Source ). function getAllCurrentPrices ( ) external view returns ( struct IFtsoRegistry . PriceInfo []); Returns the current price of all supported assets. Returns Type Description [0] struct IFtsoRegistry.PriceInfo[] Array of PriceInfo structures. getAllFtsos # Defined in FtsoRegistry ( Docs , Source ). function getAllFtsos ( ) external view returns ( contract IIFtso [] _ftsos ); Return all currently supported FTSO contracts. Returns Type Description _ftsos contract IIFtso[] Array of FTSO contract addresses. getCurrentPrice # Defined in FtsoRegistry ( Docs , Source ). function getCurrentPrice ( uint256 _assetIndex ) external view returns ( uint256 _price , uint256 _timestamp ); Public view function to get the current price of a given active FTSO index. Reverts if the index is not supported. Parameters Type Description _assetIndex uint256 Returns Type Description _price uint256 Current price of the asset in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Timestamp for when this price was updated, in seconds since UNIX epoch. getCurrentPrice # Defined in FtsoRegistry ( Docs , Source ). function getCurrentPrice ( string _symbol ) external view returns ( uint256 _price , uint256 _timestamp ); Public view function to get the current price of a given active asset symbol. Reverts if the symbol is not supported. Parameters Type Description _symbol string Symbol to query. Returns Type Description _price uint256 Current price of the asset in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Timestamp for when this price was updated, in seconds since UNIX epoch. getCurrentPriceWithDecimals # Defined in FtsoRegistry ( Docs , Source ). function getCurrentPriceWithDecimals ( uint256 _assetIndex ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Public view function to get the current price and decimals of a given active FTSO index. Reverts if the index is not supported. Parameters Type Description _assetIndex uint256 Index to query. Returns Type Description _price uint256 Current price of the asset in USD multiplied by 10^ _assetPriceUsdDecimals . _timestamp uint256 Timestamp for when this price was updated, in seconds since UNIX epoch. _assetPriceUsdDecimals uint256 Number of decimals used to return the _price . getCurrentPriceWithDecimals # Defined in FtsoRegistry ( Docs , Source ). function getCurrentPriceWithDecimals ( string _symbol ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Public view function to get the current price and decimals of a given active asset symbol. Reverts if the symbol is not supported. Parameters Type Description _symbol string Symbol to query. Returns Type Description _price uint256 Current price of the asset in USD multiplied by 10^ _assetPriceUsdDecimals . _timestamp uint256 Timestamp for when this price was updated, in seconds since UNIX epoch. _assetPriceUsdDecimals uint256 Number of decimals used to return the _price . getCurrentPricesByIndices # Defined in FtsoRegistry ( Docs , Source ). function getCurrentPricesByIndices ( uint256 [] _indices ) external view returns ( struct IFtsoRegistry . PriceInfo []); Returns the current price of a list of indices. Reverts if any of the indices is not supported. Parameters Type Description _indices uint256[] Array of indices to query. Returns Type Description [0] struct IFtsoRegistry.PriceInfo[] Array of PriceInfo structures. getCurrentPricesBySymbols # Defined in FtsoRegistry ( Docs , Source ). function getCurrentPricesBySymbols ( string [] _symbols ) external view returns ( struct IFtsoRegistry . PriceInfo []); Returns the current price of a list of asset symbols. Reverts if any of the symbols is not supported. Parameters Type Description _symbols string[] Array of symbols to query. Returns Type Description [0] struct IFtsoRegistry.PriceInfo[] Array of PriceInfo structures. getFtso # Defined in FtsoRegistry ( Docs , Source ). function getFtso ( uint256 _assetIndex ) external view returns ( contract IIFtso _activeFtso ); Returns the address of the FTSO contract for a given index. Reverts if unsupported index is passed. Parameters Type Description _assetIndex uint256 Returns Type Description _activeFtso contract IIFtso getFtsoBySymbol # Defined in FtsoRegistry ( Docs , Source ). function getFtsoBySymbol ( string _symbol ) external view returns ( contract IIFtso _activeFtso ); Returns the address of the FTSO contract for a given symbol. Reverts if unsupported symbol is passed. Parameters Type Description _symbol string The queried symbol. Returns Type Description _activeFtso contract IIFtso getFtsoHistory # Defined in FtsoRegistry ( Docs , Source ). function getFtsoHistory ( uint256 _assetIndex ) external view returns ( contract IIFtso [ 5 ] _ftsoAddressHistory ); Get the history of FTSOs for given index. If there are less then MAX_HISTORY_LENGTH the remaining addresses will be 0 addresses. Reverts if index is not supported. Parameters Type Description _assetIndex uint256 Asset index to query. Returns Type Description _ftsoAddressHistory contract IIFtso[5] History of FTSOs contract for provided index. getFtsoIndex # Defined in FtsoRegistry ( Docs , Source ). function getFtsoIndex ( string _symbol ) external view returns ( uint256 _assetIndex ); Returns the FTSO index corresponding to a given asset symbol. Reverts if the symbol is not supported. Parameters Type Description _symbol string Symbol to query. Returns Type Description _assetIndex uint256 The corresponding asset index. getFtsoSymbol # Defined in FtsoRegistry ( Docs , Source ). function getFtsoSymbol ( uint256 _assetIndex ) external view returns ( string _symbol ); Returns the asset symbol corresponding to a given FTSO index. Reverts if the index is not supported. Parameters Type Description _assetIndex uint256 Returns Type Description _symbol string The corresponding asset symbol. getFtsos # Defined in FtsoRegistry ( Docs , Source ). function getFtsos ( uint256 [] _assetIndices ) external view returns ( contract IFtsoGenesis [] _ftsos ); Get the addresses of the active FTSOs at the given indices. Reverts if any of the provided indices is non-existing or inactive. Parameters Type Description _assetIndices uint256[] Returns Type Description _ftsos contract IFtsoGenesis[] The array of FTSO addresses. getSupportedFtsos # Defined in FtsoRegistry ( Docs , Source ). function getSupportedFtsos ( ) external view returns ( contract IIFtso [] _ftsos ); Get array of all FTSO contracts for all supported asset indices. The index of FTSO in returned array does not necessarily correspond to the asset's index. Due to deletion, some indices might be unsupported. Use getSupportedIndicesAndFtsos to retrieve pairs of correct indices and FTSOs, where possible \"null\" holes are readily apparent. Returns Type Description _ftsos contract IIFtso[] Array of all supported FTSOs. getSupportedIndices # Defined in FtsoRegistry ( Docs , Source ). function getSupportedIndices ( ) external view returns ( uint256 [] _supportedIndices ); Returns the indices of the currently supported FTSOs. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedIndices uint256[] Array of all active FTSO indices in increasing order. getSupportedIndicesAndFtsos # Defined in FtsoRegistry ( Docs , Source ). function getSupportedIndicesAndFtsos ( ) external view returns ( uint256 [] _supportedIndices , contract IIFtso [] _ftsos ); Get all supported indices and corresponding FTSO addresses. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedIndices uint256[] Array of all supported indices. _ftsos contract IIFtso[] Array of all supported FTSO addresses. getSupportedIndicesAndSymbols # Defined in FtsoRegistry ( Docs , Source ). function getSupportedIndicesAndSymbols ( ) external view returns ( uint256 [] _supportedIndices , string [] _supportedSymbols ); Get all supported indices and corresponding symbols. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedIndices uint256[] Array of all supported indices. _supportedSymbols string[] Array of all supported symbols. getSupportedIndicesSymbolsAndFtsos # Defined in FtsoRegistry ( Docs , Source ). function getSupportedIndicesSymbolsAndFtsos ( ) external view returns ( uint256 [] _supportedIndices , string [] _supportedSymbols , contract IIFtso [] _ftsos ); Get all supported indices, symbols, and corresponding FTSO addresses. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedIndices uint256[] Array of all supported indices. _supportedSymbols string[] Array of all supported symbols. _ftsos contract IIFtso[] Array of all supported FTSO addresses. getSupportedSymbols # Defined in FtsoRegistry ( Docs , Source ). function getSupportedSymbols ( ) external view returns ( string [] _supportedSymbols ); Returns the symbols of the currently supported FTSOs. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedSymbols string[] Array of all active FTSO symbols in increasing order. getSupportedSymbolsAndFtsos # Defined in FtsoRegistry ( Docs , Source ). function getSupportedSymbolsAndFtsos ( ) external view returns ( string [] _supportedSymbols , contract IIFtso [] _ftsos ); Get all supported symbols and corresponding FTSO addresses. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedSymbols string[] Array of all supported symbols. _ftsos contract IIFtso[] Array of all supported FTSO addresses. governance # Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address. initialiseRegistry # Defined in FtsoRegistry ( Docs , Source ). function initialiseRegistry ( address _addressUpdater ) external ; removeFtso # Defined in FtsoRegistry ( Docs , Source ). function removeFtso ( contract IIFtso _ftso ) external ; Removes the FTSO and keeps part of the history. Reverts if the provided address is not supported. From now on, the index this asset was using is \"reserved\" and cannot be used again. It will not be returned in any list of currently supported assets. Only the ftsoManager can call this method. Parameters Type Description _ftso contract IIFtso Address of the FTSO contract to remove. switchToProductionMode # Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered . updateContractAddresses # Defined in AddressUpdatable ( Docs , Source ). function updateContractAddresses ( bytes32 [] _contractNameHashes , address [] _contractAddresses ) external ; External method called from AddressUpdater only. Modifiers # onlyAddressUpdater # Defined in AddressUpdatable ( Docs , Source ). modifier onlyAddressUpdater () Only the AdressUpdater contract can call this method. Its address is set at construction time but it can also update itself. onlyFtsoManager # Defined in FtsoRegistry ( Docs , Source ). modifier onlyFtsoManager () Only the ftsoManager can call this method. onlyGovernance # Defined in GovernedBase ( Docs , Source ). modifier onlyGovernance () onlyImmediateGovernance # Defined in GovernedBase ( Docs , Source ). modifier onlyImmediateGovernance () Variables # ftsoManager # Defined in FtsoRegistry ( Docs , Source ). contract IIFtsoManager ftsoManager FtsoManager contract that can add and remove assets to the registry. governanceSettings # Defined in GovernedBase ( Docs , Source ). contract IGovernanceSettings governanceSettings Governance Settings. productionMode # Defined in GovernedBase ( Docs , Source ). bool productionMode When true, governance is enabled and cannot be disabled. See switchToProductionMode . timelockedCalls # Defined in GovernedBase ( Docs , Source ). mapping ( bytes4 => struct GovernedBase . TimelockedCall ) timelockedCalls List of pending timelocked governance calls.","title":"FtsoRegistry"},{"location":"apis/smart-contracts/FtsoRegistry/#ct_ftsoregistry","text":"Source | Inherits from IIFtsoRegistry , AddressUpdatable , GovernedBase Handles registration of assets to the FTSO system .","title":"FtsoRegistry"},{"location":"apis/smart-contracts/FtsoRegistry/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_addftso_2663f1b4","text":"Defined in FtsoRegistry ( Docs , Source ). function addFtso ( contract IIFtso _ftsoContract ) external returns ( uint256 _assetIndex ); Add a new FTSO contract to the registry. Only the ftsoManager can call this method. Parameters Type Description _ftsoContract contract IIFtso New target FTSO contract. Returns Type Description _assetIndex uint256 The FTSO index assigned to the new asset.","title":"addFtso"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_cancelgovernancecall_67fc4029","text":"Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector.","title":"cancelGovernanceCall"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_constructor_undefined","text":"Defined in FtsoRegistry ( Docs , Source ). constructor ( ) public ;","title":"constructor"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_executegovernancecall_5ff27079","text":"Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored).","title":"executeGovernanceCall"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_getaddressupdater_5267a15d","text":"Defined in AddressUpdatable ( Docs , Source ). function getAddressUpdater ( ) public view returns ( address _addressUpdater ); Returns the configured address updater. Returns Type Description _addressUpdater address The AddresUpdater contract that can update our contract address list, as a response to a governance call.","title":"getAddressUpdater"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_getallcurrentprices_58f9296f","text":"Defined in FtsoRegistry ( Docs , Source ). function getAllCurrentPrices ( ) external view returns ( struct IFtsoRegistry . PriceInfo []); Returns the current price of all supported assets. Returns Type Description [0] struct IFtsoRegistry.PriceInfo[] Array of PriceInfo structures.","title":"getAllCurrentPrices"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_getallftsos_2bcdd6ab","text":"Defined in FtsoRegistry ( Docs , Source ). function getAllFtsos ( ) external view returns ( contract IIFtso [] _ftsos ); Return all currently supported FTSO contracts. Returns Type Description _ftsos contract IIFtso[] Array of FTSO contract addresses.","title":"getAllFtsos"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_getcurrentprice_c55d0f56","text":"Defined in FtsoRegistry ( Docs , Source ). function getCurrentPrice ( uint256 _assetIndex ) external view returns ( uint256 _price , uint256 _timestamp ); Public view function to get the current price of a given active FTSO index. Reverts if the index is not supported. Parameters Type Description _assetIndex uint256 Returns Type Description _price uint256 Current price of the asset in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Timestamp for when this price was updated, in seconds since UNIX epoch.","title":"getCurrentPrice"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_getcurrentprice_42a0f243","text":"Defined in FtsoRegistry ( Docs , Source ). function getCurrentPrice ( string _symbol ) external view returns ( uint256 _price , uint256 _timestamp ); Public view function to get the current price of a given active asset symbol. Reverts if the symbol is not supported. Parameters Type Description _symbol string Symbol to query. Returns Type Description _price uint256 Current price of the asset in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Timestamp for when this price was updated, in seconds since UNIX epoch.","title":"getCurrentPrice"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_getcurrentpricewithdecimals_257cbd3a","text":"Defined in FtsoRegistry ( Docs , Source ). function getCurrentPriceWithDecimals ( uint256 _assetIndex ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Public view function to get the current price and decimals of a given active FTSO index. Reverts if the index is not supported. Parameters Type Description _assetIndex uint256 Index to query. Returns Type Description _price uint256 Current price of the asset in USD multiplied by 10^ _assetPriceUsdDecimals . _timestamp uint256 Timestamp for when this price was updated, in seconds since UNIX epoch. _assetPriceUsdDecimals uint256 Number of decimals used to return the _price .","title":"getCurrentPriceWithDecimals"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_getcurrentpricewithdecimals_a69afdc6","text":"Defined in FtsoRegistry ( Docs , Source ). function getCurrentPriceWithDecimals ( string _symbol ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Public view function to get the current price and decimals of a given active asset symbol. Reverts if the symbol is not supported. Parameters Type Description _symbol string Symbol to query. Returns Type Description _price uint256 Current price of the asset in USD multiplied by 10^ _assetPriceUsdDecimals . _timestamp uint256 Timestamp for when this price was updated, in seconds since UNIX epoch. _assetPriceUsdDecimals uint256 Number of decimals used to return the _price .","title":"getCurrentPriceWithDecimals"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_getcurrentpricesbyindices_6ba31fa1","text":"Defined in FtsoRegistry ( Docs , Source ). function getCurrentPricesByIndices ( uint256 [] _indices ) external view returns ( struct IFtsoRegistry . PriceInfo []); Returns the current price of a list of indices. Reverts if any of the indices is not supported. Parameters Type Description _indices uint256[] Array of indices to query. Returns Type Description [0] struct IFtsoRegistry.PriceInfo[] Array of PriceInfo structures.","title":"getCurrentPricesByIndices"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_getcurrentpricesbysymbols_79d5ea4b","text":"Defined in FtsoRegistry ( Docs , Source ). function getCurrentPricesBySymbols ( string [] _symbols ) external view returns ( struct IFtsoRegistry . PriceInfo []); Returns the current price of a list of asset symbols. Reverts if any of the symbols is not supported. Parameters Type Description _symbols string[] Array of symbols to query. Returns Type Description [0] struct IFtsoRegistry.PriceInfo[] Array of PriceInfo structures.","title":"getCurrentPricesBySymbols"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_getftso_d75f6d81","text":"Defined in FtsoRegistry ( Docs , Source ). function getFtso ( uint256 _assetIndex ) external view returns ( contract IIFtso _activeFtso ); Returns the address of the FTSO contract for a given index. Reverts if unsupported index is passed. Parameters Type Description _assetIndex uint256 Returns Type Description _activeFtso contract IIFtso","title":"getFtso"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_getftsobysymbol_97da6af4","text":"Defined in FtsoRegistry ( Docs , Source ). function getFtsoBySymbol ( string _symbol ) external view returns ( contract IIFtso _activeFtso ); Returns the address of the FTSO contract for a given symbol. Reverts if unsupported symbol is passed. Parameters Type Description _symbol string The queried symbol. Returns Type Description _activeFtso contract IIFtso","title":"getFtsoBySymbol"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_getftsohistory_c71a1b20","text":"Defined in FtsoRegistry ( Docs , Source ). function getFtsoHistory ( uint256 _assetIndex ) external view returns ( contract IIFtso [ 5 ] _ftsoAddressHistory ); Get the history of FTSOs for given index. If there are less then MAX_HISTORY_LENGTH the remaining addresses will be 0 addresses. Reverts if index is not supported. Parameters Type Description _assetIndex uint256 Asset index to query. Returns Type Description _ftsoAddressHistory contract IIFtso[5] History of FTSOs contract for provided index.","title":"getFtsoHistory"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_getftsoindex_e848da30","text":"Defined in FtsoRegistry ( Docs , Source ). function getFtsoIndex ( string _symbol ) external view returns ( uint256 _assetIndex ); Returns the FTSO index corresponding to a given asset symbol. Reverts if the symbol is not supported. Parameters Type Description _symbol string Symbol to query. Returns Type Description _assetIndex uint256 The corresponding asset index.","title":"getFtsoIndex"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_getftsosymbol_136d3f64","text":"Defined in FtsoRegistry ( Docs , Source ). function getFtsoSymbol ( uint256 _assetIndex ) external view returns ( string _symbol ); Returns the asset symbol corresponding to a given FTSO index. Reverts if the index is not supported. Parameters Type Description _assetIndex uint256 Returns Type Description _symbol string The corresponding asset symbol.","title":"getFtsoSymbol"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_getftsos_9cb47538","text":"Defined in FtsoRegistry ( Docs , Source ). function getFtsos ( uint256 [] _assetIndices ) external view returns ( contract IFtsoGenesis [] _ftsos ); Get the addresses of the active FTSOs at the given indices. Reverts if any of the provided indices is non-existing or inactive. Parameters Type Description _assetIndices uint256[] Returns Type Description _ftsos contract IFtsoGenesis[] The array of FTSO addresses.","title":"getFtsos"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_getsupportedftsos_a40060ba","text":"Defined in FtsoRegistry ( Docs , Source ). function getSupportedFtsos ( ) external view returns ( contract IIFtso [] _ftsos ); Get array of all FTSO contracts for all supported asset indices. The index of FTSO in returned array does not necessarily correspond to the asset's index. Due to deletion, some indices might be unsupported. Use getSupportedIndicesAndFtsos to retrieve pairs of correct indices and FTSOs, where possible \"null\" holes are readily apparent. Returns Type Description _ftsos contract IIFtso[] Array of all supported FTSOs.","title":"getSupportedFtsos"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_getsupportedindices_798aac5b","text":"Defined in FtsoRegistry ( Docs , Source ). function getSupportedIndices ( ) external view returns ( uint256 [] _supportedIndices ); Returns the indices of the currently supported FTSOs. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedIndices uint256[] Array of all active FTSO indices in increasing order.","title":"getSupportedIndices"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_getsupportedindicesandftsos_06a2ba29","text":"Defined in FtsoRegistry ( Docs , Source ). function getSupportedIndicesAndFtsos ( ) external view returns ( uint256 [] _supportedIndices , contract IIFtso [] _ftsos ); Get all supported indices and corresponding FTSO addresses. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedIndices uint256[] Array of all supported indices. _ftsos contract IIFtso[] Array of all supported FTSO addresses.","title":"getSupportedIndicesAndFtsos"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_getsupportedindicesandsymbols_e68f283b","text":"Defined in FtsoRegistry ( Docs , Source ). function getSupportedIndicesAndSymbols ( ) external view returns ( uint256 [] _supportedIndices , string [] _supportedSymbols ); Get all supported indices and corresponding symbols. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedIndices uint256[] Array of all supported indices. _supportedSymbols string[] Array of all supported symbols.","title":"getSupportedIndicesAndSymbols"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_getsupportedindicessymbolsandftsos_7687542c","text":"Defined in FtsoRegistry ( Docs , Source ). function getSupportedIndicesSymbolsAndFtsos ( ) external view returns ( uint256 [] _supportedIndices , string [] _supportedSymbols , contract IIFtso [] _ftsos ); Get all supported indices, symbols, and corresponding FTSO addresses. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedIndices uint256[] Array of all supported indices. _supportedSymbols string[] Array of all supported symbols. _ftsos contract IIFtso[] Array of all supported FTSO addresses.","title":"getSupportedIndicesSymbolsAndFtsos"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_getsupportedsymbols_ce1c0e4d","text":"Defined in FtsoRegistry ( Docs , Source ). function getSupportedSymbols ( ) external view returns ( string [] _supportedSymbols ); Returns the symbols of the currently supported FTSOs. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedSymbols string[] Array of all active FTSO symbols in increasing order.","title":"getSupportedSymbols"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_getsupportedsymbolsandftsos_0cf48497","text":"Defined in FtsoRegistry ( Docs , Source ). function getSupportedSymbolsAndFtsos ( ) external view returns ( string [] _supportedSymbols , contract IIFtso [] _ftsos ); Get all supported symbols and corresponding FTSO addresses. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedSymbols string[] Array of all supported symbols. _ftsos contract IIFtso[] Array of all supported FTSO addresses.","title":"getSupportedSymbolsAndFtsos"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_governance_5aa6e675","text":"Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address.","title":"governance"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_initialiseregistry_ffc880fd","text":"Defined in FtsoRegistry ( Docs , Source ). function initialiseRegistry ( address _addressUpdater ) external ;","title":"initialiseRegistry"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_removeftso_a670ff87","text":"Defined in FtsoRegistry ( Docs , Source ). function removeFtso ( contract IIFtso _ftso ) external ; Removes the FTSO and keeps part of the history. Reverts if the provided address is not supported. From now on, the index this asset was using is \"reserved\" and cannot be used again. It will not be returned in any list of currently supported assets. Only the ftsoManager can call this method. Parameters Type Description _ftso contract IIFtso Address of the FTSO contract to remove.","title":"removeFtso"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_switchtoproductionmode_f5a98383","text":"Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered .","title":"switchToProductionMode"},{"location":"apis/smart-contracts/FtsoRegistry/#fn_updatecontractaddresses_b00c0b76","text":"Defined in AddressUpdatable ( Docs , Source ). function updateContractAddresses ( bytes32 [] _contractNameHashes , address [] _contractAddresses ) external ; External method called from AddressUpdater only.","title":"updateContractAddresses"},{"location":"apis/smart-contracts/FtsoRegistry/#modifiers","text":"","title":"Modifiers"},{"location":"apis/smart-contracts/FtsoRegistry/#md_onlyaddressupdater","text":"Defined in AddressUpdatable ( Docs , Source ). modifier onlyAddressUpdater () Only the AdressUpdater contract can call this method. Its address is set at construction time but it can also update itself.","title":"onlyAddressUpdater"},{"location":"apis/smart-contracts/FtsoRegistry/#md_onlyftsomanager","text":"Defined in FtsoRegistry ( Docs , Source ). modifier onlyFtsoManager () Only the ftsoManager can call this method.","title":"onlyFtsoManager"},{"location":"apis/smart-contracts/FtsoRegistry/#md_onlygovernance","text":"Defined in GovernedBase ( Docs , Source ). modifier onlyGovernance ()","title":"onlyGovernance"},{"location":"apis/smart-contracts/FtsoRegistry/#md_onlyimmediategovernance","text":"Defined in GovernedBase ( Docs , Source ). modifier onlyImmediateGovernance ()","title":"onlyImmediateGovernance"},{"location":"apis/smart-contracts/FtsoRegistry/#variables","text":"","title":"Variables"},{"location":"apis/smart-contracts/FtsoRegistry/#va_ftsomanager","text":"Defined in FtsoRegistry ( Docs , Source ). contract IIFtsoManager ftsoManager FtsoManager contract that can add and remove assets to the registry.","title":"ftsoManager"},{"location":"apis/smart-contracts/FtsoRegistry/#va_governancesettings","text":"Defined in GovernedBase ( Docs , Source ). contract IGovernanceSettings governanceSettings Governance Settings.","title":"governanceSettings"},{"location":"apis/smart-contracts/FtsoRegistry/#va_productionmode","text":"Defined in GovernedBase ( Docs , Source ). bool productionMode When true, governance is enabled and cannot be disabled. See switchToProductionMode .","title":"productionMode"},{"location":"apis/smart-contracts/FtsoRegistry/#va_timelockedcalls","text":"Defined in GovernedBase ( Docs , Source ). mapping ( bytes4 => struct GovernedBase . TimelockedCall ) timelockedCalls List of pending timelocked governance calls.","title":"timelockedCalls"},{"location":"apis/smart-contracts/FtsoRewardManager/","text":"FtsoRewardManager # Source | Inherits from IIFtsoRewardManager , Governed , ReentrancyGuard, AddressUpdatable Handles reward distribution and claiming related to the FTSO system. More specifically, this contract: Distributes rewards according to instructions from the FtsoManager . Allows data providers, delegators and executors to claim rewards. Functions # accrueUnearnedRewards # Defined in FtsoRewardManager ( Docs , Source ). function accrueUnearnedRewards ( uint256 _epochId , uint256 _priceEpochDurationSeconds , uint256 _priceEpochEndTime ) external ; Accrue unearned rewards for a given price epoch. Typically done when the FTSO is in fallback mode or because of insufficient vote power. Simply accrue them so they will not be distributed and will be burned later. The amount of rewards that will be burned is calculated in the same way as in distributeRewards . Only the FTSO Manager can call this method. Parameters Type Description _epochId uint256 _priceEpochDurationSeconds uint256 _priceEpochEndTime uint256 activate # Defined in FtsoRewardManager ( Docs , Source ). function activate ( ) external ; Activates reward manager (allows claiming rewards). Only governance can call this method. active # Defined in IFtsoRewardManager ( Docs , Source ). function active ( ) external view returns ( bool ); Whether rewards can be claimed from this reward manager. autoClaim # Defined in FtsoRewardManager ( Docs , Source ). function autoClaim ( address [] _rewardOwners , uint256 _rewardEpoch ) external ; Allows claiming rewards simultaneously for a list of reward owners and all unclaimed epochs before the specified one. This is meant as a convenience all-in-one reward claiming method to be used both by reward owners and registered executors . It performs a series of operations, besides claiming rewards: If a reward owner has enabled its Personal Delegation Account , rewards are also claimed for the PDA and the total claimed amount is sent to that PDA. Otherwise, the claimed amount is sent to the reward owner's account. Claimed amount is automatically wrapped through the WNat contract. If the caller is a registered executor with a non-zero fee, the fee is paid to the executor for each claimed address. Parameters Type Description _rewardOwners address[] List of reward owners to claim for. _rewardEpoch uint256 Last reward epoch ID to claim for. All previous epochs with pending rewards will be claimed too. cancelGovernanceCall # Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector. claim # Defined in FtsoRewardManager ( Docs , Source ). function claim ( address _rewardOwner , address payable _recipient , uint256 _rewardEpoch , bool _wrap ) external returns ( uint256 _rewardAmount ); Allows the caller to claim rewards for a reward owner. The caller does not have to be the owner of the rewards, but must be approved by the owner to claim on his behalf by using setClaimExecutors on the claimSetupManager . This function is intended to be used to claim rewards in case of delegation by percentage. Reverts if msg.sender is delegating by amount. Anybody can call this method, but rewards can only be sent to the reward owner, therefore no funds can be stolen. However, by limiting the authorized callers, the owner can control the timing of the calls. When the reward owner is the caller, rewards can be sent to any recipient set by setAllowedClaimRecipients on the claimSetupManager . The reward owner's Personal Delegation Account is always an authorized recipient. Parameters Type Description _rewardOwner address Address of the reward owner. _recipient address payable Address to transfer claimed rewards to. _rewardEpoch uint256 Last reward epoch to claim for. All previous epochs with pending rewards will be claimed too. _wrap bool Whether claimed rewards should be wrapped through the WNat contract before transferring them to the _recipient . This parameter is offered as a convenience. Returns Type Description _rewardAmount uint256 Total amount of claimed rewards (wei). claimFromDataProviders # Defined in FtsoRewardManager ( Docs , Source ). function claimFromDataProviders ( address _rewardOwner , address payable _recipient , uint256 [] _rewardEpochs , address [] _dataProviders , bool _wrap ) external returns ( uint256 _rewardAmount ); Allows the caller to claim rewards for a reward owner from specific data providers. The caller does not have to be the owner of the rewards, but must be approved by the owner to claim on his behalf by using setClaimExecutors on the claimSetupManager . This function is intended to be used to claim rewards in case of delegation by amount (explicit delegation). Reverts if msg.sender is delegating by percentage. Anybody can call this method, but rewards can only be sent to the reward owner, therefore no funds can be stolen. However, by limiting the authorized callers, the owner can control the timing of the calls. When the reward owner is the caller, rewards can be sent to any recipient set by setAllowedClaimRecipients on the claimSetupManager . The reward owner's Personal Delegation Account is always an authorized recipient. Parameters Type Description _rewardOwner address Address of the reward owner. _recipient address payable Address to transfer claimed rewards to. _rewardEpochs uint256[] Array of reward epoch IDs to claim for. _dataProviders address[] Array of addresses of the data providers to claim the reward from. _wrap bool Whether claimed rewards should be wrapped through the WNat contract before transferring them to the _recipient . This parameter is offered as a convenience. Returns Type Description _rewardAmount uint256 Total amount of claimed rewards (wei). claimReward # Defined in FtsoRewardManager ( Docs , Source ). function claimReward ( address payable _recipient , uint256 [] _rewardEpochs ) external returns ( uint256 _rewardAmount ); Allows a percentage delegator to claim rewards. This function is intended to be used to claim rewards in case of delegation by percentage. This function is deprecated : use claim instead. Reverts if msg.sender is delegating by amount. Claims for all unclaimed reward epochs to the 'max(_rewardEpochs)'. Retained for backward compatibility. Parameters Type Description _recipient address payable Address to transfer funds to. _rewardEpochs uint256[] Array of reward epoch numbers to claim for. Returns Type Description _rewardAmount uint256 Amount of total claimed rewards (wei). claimRewardFromDataProviders # Defined in FtsoRewardManager ( Docs , Source ). function claimRewardFromDataProviders ( address payable _recipient , uint256 [] _rewardEpochs , address [] _dataProviders ) external returns ( uint256 _rewardAmount ); Allows the caller to claim rewards from specific data providers. This function is intended to be used to claim rewards in case of delegation by amount. This function is deprecated : use claimFromDataProviders instead. Parameters Type Description _recipient address payable Address to transfer funds to. _rewardEpochs uint256[] Array of reward epoch numbers to claim for. _dataProviders address[] Array of addresses of the data providers to claim the reward from. Returns Type Description _rewardAmount uint256 Total amount of claimed rewards (wei). closeExpiredRewardEpoch # Defined in FtsoRewardManager ( Docs , Source ). function closeExpiredRewardEpoch ( uint256 _rewardEpoch ) external ; Collects funds from expired reward epoch and calculates totals. Triggered by ftsoManager on finalization of a reward epoch. Operation is irreversible: when some reward epoch is closed according to current settings, it cannot be reopened even if new parameters would allow it, because nextRewardEpochToExpire in ftsoManager never decreases. Parameters Type Description _rewardEpoch uint256 constructor # Defined in FtsoRewardManager ( Docs , Source ). constructor ( address _governance , address _addressUpdater , address _oldFtsoRewardManager , uint256 _feePercentageUpdateOffset , uint256 _defaultFeePercentage ) public ; constructor # Defined in Governed ( Docs , Source ). constructor ( address _governance ) public ; Parameters Type Description _governance address Governance contract. Must not be zero. deactivate # Defined in FtsoRewardManager ( Docs , Source ). function deactivate ( ) external ; Deactivates reward manager (prevents claiming rewards). Only governance can call this method. defaultFeePercentage # Defined in FtsoRewardManager ( Docs , Source ). function defaultFeePercentage ( ) external view returns ( uint256 ); Returns the configured default fee percentage. distributeRewards # Defined in FtsoRewardManager ( Docs , Source ). function distributeRewards ( address [] _addresses , uint256 [] _weights , uint256 _totalWeight , uint256 _epochId , address _ftso , uint256 _priceEpochDurationSeconds , uint256 _currentRewardEpoch , uint256 _priceEpochEndTime , uint256 _votePowerBlock ) external ; Distributes price epoch rewards to data provider accounts, according to input parameters. Must be called with totalWeight > 0 and addresses.length > 0. The amount of rewards for a given price epoch ID are calculated in FtsoRewardManager from priceEpochDurationSeconds , priceEpochEndTime and inflation authorization data (see _getTotalPriceEpochRewardWei in FtsoRewardManager . Then each data provider address is given a portion of this amount according to corresponding weight and total sum of weights. Parameters epochId and ftso are only needed so they can be passed onto the emitted event. Only the ftsoManager can call this method. Parameters Type Description _addresses address[] _weights uint256[] _totalWeight uint256 _epochId uint256 _ftso address _priceEpochDurationSeconds uint256 _currentRewardEpoch uint256 _priceEpochEndTime uint256 _votePowerBlock uint256 enableClaims # Defined in FtsoRewardManager ( Docs , Source ). function enableClaims ( ) external ; Enable claiming for current and all future reward epochs. Only governance can call this method. executeGovernanceCall # Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored). feePercentageUpdateOffset # Defined in FtsoRewardManager ( Docs , Source ). function feePercentageUpdateOffset ( ) external view returns ( uint256 ); Returns the amount of reward epoch that need to ellapse before a fee change takes effect. firstClaimableRewardEpoch # Defined in IIFtsoRewardManager ( Docs , Source ). function firstClaimableRewardEpoch ( ) external view returns ( uint256 ); Epochs before the token distribution event at Flare launch were not be claimable. Use this method to know the first reward epoch that was claimable. Returns Type Description [0] uint256 uint256 The first reward epoch that can be claimed. getAddressUpdater # Defined in AddressUpdatable ( Docs , Source ). function getAddressUpdater ( ) public view returns ( address _addressUpdater ); Returns the configured address updater. Returns Type Description _addressUpdater address The AddresUpdater contract that can update our contract address list, as a response to a governance call. getClaimedReward # Defined in FtsoRewardManager ( Docs , Source ). function getClaimedReward ( uint256 _rewardEpoch , address _dataProvider , address _claimer ) external view returns ( bool _claimed , uint256 _amount ); Returns information on the rewards accrued by a reward owner from a specific data provider at a specific reward epoch. Parameters Type Description _rewardEpoch uint256 Reward epoch ID to query. _dataProvider address Address of the data provider to query. _claimer address Address of the reward owner to query. Returns Type Description _claimed bool Whether the reward has been claimed or not. _amount uint256 Accrued amount in wei. getContractName # Defined in FtsoRewardManager ( Docs , Source ). function getContractName ( ) external pure returns ( string ); Implement this function to allow updating inflation receiver contracts through AddressUpdater . Returns Type Description [0] string Contract name. getCurrentRewardEpoch # Defined in FtsoRewardManager ( Docs , Source ). function getCurrentRewardEpoch ( ) external view returns ( uint256 ); Returns the current reward epoch ID. getDataProviderCurrentFeePercentage # Defined in FtsoRewardManager ( Docs , Source ). function getDataProviderCurrentFeePercentage ( address _dataProvider ) external view returns ( uint256 ); Returns the current fee percentage of a data provider. Parameters Type Description _dataProvider address Address of the queried data provider. Returns Type Description [0] uint256 getDataProviderFeePercentage # Defined in FtsoRewardManager ( Docs , Source ). function getDataProviderFeePercentage ( address _dataProvider , uint256 _rewardEpoch ) external view returns ( uint256 _feePercentageBIPS ); Returns the fee percentage of a data provider at a given reward epoch. Parameters Type Description _dataProvider address Address of the queried data provider. _rewardEpoch uint256 Reward epoch ID. Returns Type Description _feePercentageBIPS uint256 Fee percentage in BIPS. getDataProviderPerformanceInfo # Defined in FtsoRewardManager ( Docs , Source ). function getDataProviderPerformanceInfo ( uint256 _rewardEpoch , address _dataProvider ) external view returns ( uint256 _rewardAmount , uint256 _votePowerIgnoringRevocation ); Returns information on rewards and vote power of a data provider at a given reward epoch. Parameters Type Description _rewardEpoch uint256 Reward epoch ID. _dataProvider address Address of the data provider to query. Returns Type Description _rewardAmount uint256 Amount of rewards (wei). _votePowerIgnoringRevocation uint256 Vote power, not including revocations. getDataProviderScheduledFeePercentageChanges # Defined in FtsoRewardManager ( Docs , Source ). function getDataProviderScheduledFeePercentageChanges ( address _dataProvider ) external view returns ( uint256 [] _feePercentageBIPS , uint256 [] _validFromEpoch , bool [] _fixed ); Returns the scheduled fee percentage changes for a data provider. Parameters Type Description _dataProvider address Address of the queried data provider. Returns Type Description _feePercentageBIPS uint256[] Array of fee percentages in BIPS. _validFromEpoch uint256[] Array of block numbers from which the fee settings are effective. _fixed bool[] Array of boolean values indicating whether settings are subject to change or not. getEpochReward # Defined in FtsoRewardManager ( Docs , Source ). function getEpochReward ( uint256 _rewardEpoch ) external view returns ( uint256 _totalReward , uint256 _claimedReward ); Returns information on an epoch's rewards. Parameters Type Description _rewardEpoch uint256 Reward epoch ID. Returns Type Description _totalReward uint256 Total amount of rewards accrued on that epoch, in wei. _claimedReward uint256 Total amount of rewards that have already been claimed, in wei. getEpochsWithClaimableRewards # Defined in FtsoRewardManager ( Docs , Source ). function getEpochsWithClaimableRewards ( ) external view returns ( uint256 _startEpochId , uint256 _endEpochId ); Returns the reward epoch range for which rewards can be claimed. Rewards outside this range are unclaimable, either because they have expired or because the reward epoch is still ongoing. Returns Type Description _startEpochId uint256 The oldest epoch ID that allows reward claiming. _endEpochId uint256 The newest epoch ID that allows reward claiming. getEpochsWithUnclaimedRewards # Defined in FtsoRewardManager ( Docs , Source ). function getEpochsWithUnclaimedRewards ( address _beneficiary ) external view returns ( uint256 [] _epochIds ); Returns the array of claimable epoch IDs for which the rewards of a reward owner have not yet been claimed. Parameters Type Description _beneficiary address Address of the reward owner to query. Reverts if it uses delegation by amount. Returns Type Description _epochIds uint256[] Array of epoch IDs. getExpectedBalance # Defined in FtsoRewardManager ( Docs , Source ). function getExpectedBalance ( ) external view returns ( uint256 ); Returns the contract's expected balance (actual balance may be higher due to self-destruct funds). Returns Type Description [0] uint256 Expected native token balance. getInflationAddress # Defined in FtsoRewardManager ( Docs , Source ). function getInflationAddress ( ) external view returns ( address ); Returns the address of the Inflation contract. getInitialRewardEpoch # Defined in FtsoRewardManager ( Docs , Source ). function getInitialRewardEpoch ( ) external view returns ( uint256 _initialRewardEpoch ); Returns the initial reward epoch ID for this reward manager contract. This corresponds to the oldest reward epoch with claimable rewards in the previous reward manager when this one took over. Set by governance through setInitialRewardData . getRewardEpochToExpireNext # Defined in FtsoRewardManager ( Docs , Source ). function getRewardEpochToExpireNext ( ) external view returns ( uint256 ); Returns the reward epoch that will expire next once a new reward epoch starts. getRewardEpochVotePowerBlock # Defined in FtsoRewardManager ( Docs , Source ). function getRewardEpochVotePowerBlock ( uint256 _rewardEpoch ) external view returns ( uint256 ); Returns the vote power block of a given reward epoch. Parameters Type Description _rewardEpoch uint256 Reward epoch ID. getStateOfRewards # Defined in FtsoRewardManager ( Docs , Source ). function getStateOfRewards ( address _beneficiary , uint256 _rewardEpoch ) external view returns ( address [] _dataProviders , uint256 [] _rewardAmounts , bool [] _claimed , bool _claimable ); Returns the state of rewards for a given address at a specific reward epoch. Parameters Type Description _beneficiary address Address of the beneficiary to query. It can be a data provider or a delegator, for example. Reverts if the queried address is delegating by amount. _rewardEpoch uint256 Reward epoch ID to query. Returns Type Description _dataProviders address[] Array of addresses of data providers. _rewardAmounts uint256[] Array of reward amounts received from each provider, in wei. _claimed bool[] Array of boolean values indicating whether each reward has been claimed or not. _claimable bool Boolean value indicating whether rewards are claimable or not. getStateOfRewardsFromDataProviders # Defined in FtsoRewardManager ( Docs , Source ). function getStateOfRewardsFromDataProviders ( address _beneficiary , uint256 _rewardEpoch , address [] _dataProviders ) external view returns ( uint256 [] _rewardAmounts , bool [] _claimed , bool _claimable ); Returns the state of rewards for a given address coming from a specific set of data providers, at a specific reward epoch. Parameters Type Description _beneficiary address Address of beneficiary to query. _rewardEpoch uint256 Reward epoch ID to query. _dataProviders address[] Array of addresses of the data providers to query. Returns Type Description _rewardAmounts uint256[] Array of reward amounts received from each provider, in wei. _claimed bool[] Array of boolean values indicating whether each reward has been claimed or not. _claimable bool Boolean value indicating whether rewards are claimable or not. getTokenPoolSupplyData # Defined in FtsoRewardManager ( Docs , Source ). function getTokenPoolSupplyData ( ) external view returns ( uint256 _lockedFundsWei , uint256 _totalInflationAuthorizedWei , uint256 _totalClaimedWei ); Returns token pool supply data. Returns Type Description _lockedFundsWei uint256 Total amount of funds ever locked in the token pool (wei). _lockedFundsWei - _totalClaimedWei is the amount currently locked and outside the circulating supply. _totalInflationAuthorizedWei uint256 Total inflation authorized amount (wei). _totalClaimedWei uint256 Total claimed amount (wei). getTotals # Defined in FtsoRewardManager ( Docs , Source ). function getTotals ( ) external view returns ( uint256 _totalAwardedWei , uint256 _totalClaimedWei , uint256 _totalExpiredWei , uint256 _totalUnearnedWei , uint256 _totalBurnedWei , uint256 _totalInflationAuthorizedWei , uint256 _totalInflationReceivedWei , uint256 _lastInflationAuthorizationReceivedTs , uint256 _dailyAuthorizedInflation ); Returns statistics regarding rewards, accumulated over the whole lifespan of the reward manager contract. Returns Type Description _totalAwardedWei uint256 Rewards that were distributed (wei). _totalClaimedWei uint256 Distributed rewards that were claimed in time (wei). _totalExpiredWei uint256 Distributed rewards that were not claimed in time and expired (wei). _totalUnearnedWei uint256 Rewards that were unearned (due to FTSO being in fallback mode) and thus were not distributed (wei). _totalBurnedWei uint256 Rewards that were unearned or expired and thus burned (wei). _totalInflationAuthorizedWei uint256 Total inflation authorized amount (wei). _totalInflationReceivedWei uint256 Total inflation received amount (wei). _lastInflationAuthorizationReceivedTs uint256 UNIX timestamp of the last inflation authorization. _dailyAuthorizedInflation uint256 Inflation authorized amount (wei) at the time of last authorization. getUnclaimedReward # Defined in FtsoRewardManager ( Docs , Source ). function getUnclaimedReward ( uint256 _rewardEpoch , address _dataProvider ) external view returns ( uint256 _amount , uint256 _weight ); Returns information on unclaimed rewards for a given data provider and epoch. Parameters Type Description _rewardEpoch uint256 Queried reward epoch ID. _dataProvider address Address of the queried data provider. Returns Type Description _amount uint256 Amount available to be claimed, in wei. _weight uint256 Portion of total vote power used in this reward epoch that has not yet claimed its reward, in BIPS. It decreases to 0 when all data providers have claimed their rewards. governance # Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address. nextClaimableRewardEpoch # Defined in FtsoRewardManager ( Docs , Source ). function nextClaimableRewardEpoch ( address _rewardOwner ) external view returns ( uint256 ); Returns the next claimable reward epoch for a reward owner. Parameters Type Description _rewardOwner address Address of the reward owner to query. receiveInflation # Defined in FtsoRewardManager ( Docs , Source ). function receiveInflation ( ) external payable ; Receive native tokens from inflation. Only the inflation contract can call this method. setDailyAuthorizedInflation # Defined in FtsoRewardManager ( Docs , Source ). function setDailyAuthorizedInflation ( uint256 _toAuthorizeWei ) external ; Notify the receiver that it is entitled to receive a new inflation amount. Only the inflation contract can call this method. Parameters Type Description _toAuthorizeWei uint256 The amount of inflation that can be awarded in the coming day, in wei. setDataProviderFeePercentage # Defined in FtsoRewardManager ( Docs , Source ). function setDataProviderFeePercentage ( uint256 _feePercentageBIPS ) external returns ( uint256 ); Sets the fee a data provider keeps from all delegations. Takes effect after feeValueUpdateOffset reward epochs have elapsed. When called multiple times inside the same reward epoch, only the last value remains. Parameters Type Description _feePercentageBIPS uint256 Fee percentage in BIPS. Returns Type Description [0] uint256 setInitialRewardData # Defined in FtsoRewardManager ( Docs , Source ). function setInitialRewardData ( ) external ; Copy initial reward data from oldFtsoRewardManager before starting up this new reward manager. Should be called at the time of switching to the new reward manager, can be called only once, and only by governance . setNewFtsoRewardManager # Defined in FtsoRewardManager ( Docs , Source ). function setNewFtsoRewardManager ( address _newFtsoRewardManager ) external ; Sets new ftso reward manager which will take over closing expired reward epochs Should be called at the time of switching to the new reward manager, can be called only once, and only by governance . switchToProductionMode # Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered . updateContractAddresses # Defined in AddressUpdatable ( Docs , Source ). function updateContractAddresses ( bytes32 [] _contractNameHashes , address [] _contractAddresses ) external ; External method called from AddressUpdater only. Modifiers # mustBalance # Defined in FtsoRewardManager ( Docs , Source ). modifier mustBalance () nonReentrant # Defined in ReentrancyGuard ( Source ). modifier nonReentrant () Prevents a contract from calling itself, directly or indirectly. Calling a nonReentrant function from another nonReentrant function is not supported. It is possible to prevent this from happening by making the nonReentrant function external, and make it call a private function that does the actual work. onlyAddressUpdater # Defined in AddressUpdatable ( Docs , Source ). modifier onlyAddressUpdater () Only the AdressUpdater contract can call this method. Its address is set at construction time but it can also update itself. onlyExecutorAndAllowedRecipient # Defined in FtsoRewardManager ( Docs , Source ). modifier onlyExecutorAndAllowedRecipient ( address _rewardOwner , address _recipient ) Only the reward owner and its authorized executors can call this method. Executors can only send rewards to authorized recipients. See ClaimSetupManager . onlyFtsoManager # Defined in FtsoRewardManager ( Docs , Source ). modifier onlyFtsoManager () Only the ftsoManager contract can call this method. onlyGovernance # Defined in GovernedBase ( Docs , Source ). modifier onlyGovernance () onlyIfActive # Defined in FtsoRewardManager ( Docs , Source ). modifier onlyIfActive () This method can only be called if the contract is active . onlyImmediateGovernance # Defined in GovernedBase ( Docs , Source ). modifier onlyImmediateGovernance () onlyInflation # Defined in FtsoRewardManager ( Docs , Source ). modifier onlyInflation () Only the Inflation contract can call this method. Structures # RewardClaim # Defined in FtsoRewardManager ( Docs , Source ). struct RewardClaim { bool claimed ; uint128 amount ; } RewardState # Defined in FtsoRewardManager ( Docs , Source ). struct RewardState { address [] dataProviders ; uint256 [] weights ; uint256 [] amounts ; bool [] claimed ; } TimelockedCall # Defined in GovernedBase ( Docs , Source ). struct TimelockedCall { uint256 allowedAfterTimestamp ; bytes encodedCall ; } UnclaimedRewardState # Defined in FtsoRewardManager ( Docs , Source ). struct UnclaimedRewardState { uint128 amount ; uint128 weight ; } Variables # active # Defined in FtsoRewardManager ( Docs , Source ). bool active Whether rewards can be claimed from this reward manager. claimSetupManager # Defined in FtsoRewardManager ( Docs , Source ). contract IIClaimSetupManager claimSetupManager The ClaimSetupManager contract that helps automate reward claiming. firstClaimableRewardEpoch # Defined in FtsoRewardManager ( Docs , Source ). uint256 firstClaimableRewardEpoch Epochs before the token distribution event at Flare launch were not be claimable. This variable holds the first reward epoch that was claimable. ftsoManager # Defined in FtsoRewardManager ( Docs , Source ). contract IIFtsoManager ftsoManager The FtsoManager contract that controls reward distribution. governanceSettings # Defined in GovernedBase ( Docs , Source ). contract IGovernanceSettings governanceSettings Governance Settings. newFtsoRewardManager # Defined in FtsoRewardManager ( Docs , Source ). address newFtsoRewardManager Address of the new FtsoRewardManager that replaced this one. oldFtsoRewardManager # Defined in FtsoRewardManager ( Docs , Source ). address oldFtsoRewardManager Address of the old FtsoRewardManager , replaced by this one. productionMode # Defined in GovernedBase ( Docs , Source ). bool productionMode When true, governance is enabled and cannot be disabled. See switchToProductionMode . timelockedCalls # Defined in GovernedBase ( Docs , Source ). mapping ( bytes4 => struct GovernedBase . TimelockedCall ) timelockedCalls List of pending timelocked governance calls. wNat # Defined in FtsoRewardManager ( Docs , Source ). contract WNat wNat Address of the wrapped native token ( WNat ) contract.","title":"FtsoRewardManager"},{"location":"apis/smart-contracts/FtsoRewardManager/#ct_ftsorewardmanager","text":"Source | Inherits from IIFtsoRewardManager , Governed , ReentrancyGuard, AddressUpdatable Handles reward distribution and claiming related to the FTSO system. More specifically, this contract: Distributes rewards according to instructions from the FtsoManager . Allows data providers, delegators and executors to claim rewards.","title":"FtsoRewardManager"},{"location":"apis/smart-contracts/FtsoRewardManager/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_accrueunearnedrewards_67dcac53","text":"Defined in FtsoRewardManager ( Docs , Source ). function accrueUnearnedRewards ( uint256 _epochId , uint256 _priceEpochDurationSeconds , uint256 _priceEpochEndTime ) external ; Accrue unearned rewards for a given price epoch. Typically done when the FTSO is in fallback mode or because of insufficient vote power. Simply accrue them so they will not be distributed and will be burned later. The amount of rewards that will be burned is calculated in the same way as in distributeRewards . Only the FTSO Manager can call this method. Parameters Type Description _epochId uint256 _priceEpochDurationSeconds uint256 _priceEpochEndTime uint256","title":"accrueUnearnedRewards"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_activate_0f15f4c0","text":"Defined in FtsoRewardManager ( Docs , Source ). function activate ( ) external ; Activates reward manager (allows claiming rewards). Only governance can call this method.","title":"activate"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_active_02fb0c5e","text":"Defined in IFtsoRewardManager ( Docs , Source ). function active ( ) external view returns ( bool ); Whether rewards can be claimed from this reward manager.","title":"active"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_autoclaim_8dc305fa","text":"Defined in FtsoRewardManager ( Docs , Source ). function autoClaim ( address [] _rewardOwners , uint256 _rewardEpoch ) external ; Allows claiming rewards simultaneously for a list of reward owners and all unclaimed epochs before the specified one. This is meant as a convenience all-in-one reward claiming method to be used both by reward owners and registered executors . It performs a series of operations, besides claiming rewards: If a reward owner has enabled its Personal Delegation Account , rewards are also claimed for the PDA and the total claimed amount is sent to that PDA. Otherwise, the claimed amount is sent to the reward owner's account. Claimed amount is automatically wrapped through the WNat contract. If the caller is a registered executor with a non-zero fee, the fee is paid to the executor for each claimed address. Parameters Type Description _rewardOwners address[] List of reward owners to claim for. _rewardEpoch uint256 Last reward epoch ID to claim for. All previous epochs with pending rewards will be claimed too.","title":"autoClaim"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_cancelgovernancecall_67fc4029","text":"Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector.","title":"cancelGovernanceCall"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_claim_b2c12192","text":"Defined in FtsoRewardManager ( Docs , Source ). function claim ( address _rewardOwner , address payable _recipient , uint256 _rewardEpoch , bool _wrap ) external returns ( uint256 _rewardAmount ); Allows the caller to claim rewards for a reward owner. The caller does not have to be the owner of the rewards, but must be approved by the owner to claim on his behalf by using setClaimExecutors on the claimSetupManager . This function is intended to be used to claim rewards in case of delegation by percentage. Reverts if msg.sender is delegating by amount. Anybody can call this method, but rewards can only be sent to the reward owner, therefore no funds can be stolen. However, by limiting the authorized callers, the owner can control the timing of the calls. When the reward owner is the caller, rewards can be sent to any recipient set by setAllowedClaimRecipients on the claimSetupManager . The reward owner's Personal Delegation Account is always an authorized recipient. Parameters Type Description _rewardOwner address Address of the reward owner. _recipient address payable Address to transfer claimed rewards to. _rewardEpoch uint256 Last reward epoch to claim for. All previous epochs with pending rewards will be claimed too. _wrap bool Whether claimed rewards should be wrapped through the WNat contract before transferring them to the _recipient . This parameter is offered as a convenience. Returns Type Description _rewardAmount uint256 Total amount of claimed rewards (wei).","title":"claim"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_claimfromdataproviders_21bb25af","text":"Defined in FtsoRewardManager ( Docs , Source ). function claimFromDataProviders ( address _rewardOwner , address payable _recipient , uint256 [] _rewardEpochs , address [] _dataProviders , bool _wrap ) external returns ( uint256 _rewardAmount ); Allows the caller to claim rewards for a reward owner from specific data providers. The caller does not have to be the owner of the rewards, but must be approved by the owner to claim on his behalf by using setClaimExecutors on the claimSetupManager . This function is intended to be used to claim rewards in case of delegation by amount (explicit delegation). Reverts if msg.sender is delegating by percentage. Anybody can call this method, but rewards can only be sent to the reward owner, therefore no funds can be stolen. However, by limiting the authorized callers, the owner can control the timing of the calls. When the reward owner is the caller, rewards can be sent to any recipient set by setAllowedClaimRecipients on the claimSetupManager . The reward owner's Personal Delegation Account is always an authorized recipient. Parameters Type Description _rewardOwner address Address of the reward owner. _recipient address payable Address to transfer claimed rewards to. _rewardEpochs uint256[] Array of reward epoch IDs to claim for. _dataProviders address[] Array of addresses of the data providers to claim the reward from. _wrap bool Whether claimed rewards should be wrapped through the WNat contract before transferring them to the _recipient . This parameter is offered as a convenience. Returns Type Description _rewardAmount uint256 Total amount of claimed rewards (wei).","title":"claimFromDataProviders"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_claimreward_b2af870a","text":"Defined in FtsoRewardManager ( Docs , Source ). function claimReward ( address payable _recipient , uint256 [] _rewardEpochs ) external returns ( uint256 _rewardAmount ); Allows a percentage delegator to claim rewards. This function is intended to be used to claim rewards in case of delegation by percentage. This function is deprecated : use claim instead. Reverts if msg.sender is delegating by amount. Claims for all unclaimed reward epochs to the 'max(_rewardEpochs)'. Retained for backward compatibility. Parameters Type Description _recipient address payable Address to transfer funds to. _rewardEpochs uint256[] Array of reward epoch numbers to claim for. Returns Type Description _rewardAmount uint256 Amount of total claimed rewards (wei).","title":"claimReward"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_claimrewardfromdataproviders_d20bb542","text":"Defined in FtsoRewardManager ( Docs , Source ). function claimRewardFromDataProviders ( address payable _recipient , uint256 [] _rewardEpochs , address [] _dataProviders ) external returns ( uint256 _rewardAmount ); Allows the caller to claim rewards from specific data providers. This function is intended to be used to claim rewards in case of delegation by amount. This function is deprecated : use claimFromDataProviders instead. Parameters Type Description _recipient address payable Address to transfer funds to. _rewardEpochs uint256[] Array of reward epoch numbers to claim for. _dataProviders address[] Array of addresses of the data providers to claim the reward from. Returns Type Description _rewardAmount uint256 Total amount of claimed rewards (wei).","title":"claimRewardFromDataProviders"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_closeexpiredrewardepoch_d6c1dbee","text":"Defined in FtsoRewardManager ( Docs , Source ). function closeExpiredRewardEpoch ( uint256 _rewardEpoch ) external ; Collects funds from expired reward epoch and calculates totals. Triggered by ftsoManager on finalization of a reward epoch. Operation is irreversible: when some reward epoch is closed according to current settings, it cannot be reopened even if new parameters would allow it, because nextRewardEpochToExpire in ftsoManager never decreases. Parameters Type Description _rewardEpoch uint256","title":"closeExpiredRewardEpoch"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_constructor_undefined","text":"Defined in FtsoRewardManager ( Docs , Source ). constructor ( address _governance , address _addressUpdater , address _oldFtsoRewardManager , uint256 _feePercentageUpdateOffset , uint256 _defaultFeePercentage ) public ;","title":"constructor"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_constructor_undefined","text":"Defined in Governed ( Docs , Source ). constructor ( address _governance ) public ; Parameters Type Description _governance address Governance contract. Must not be zero.","title":"constructor"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_deactivate_51b42b00","text":"Defined in FtsoRewardManager ( Docs , Source ). function deactivate ( ) external ; Deactivates reward manager (prevents claiming rewards). Only governance can call this method.","title":"deactivate"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_defaultfeepercentage_b4824034","text":"Defined in FtsoRewardManager ( Docs , Source ). function defaultFeePercentage ( ) external view returns ( uint256 ); Returns the configured default fee percentage.","title":"defaultFeePercentage"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_distributerewards_a9b79e17","text":"Defined in FtsoRewardManager ( Docs , Source ). function distributeRewards ( address [] _addresses , uint256 [] _weights , uint256 _totalWeight , uint256 _epochId , address _ftso , uint256 _priceEpochDurationSeconds , uint256 _currentRewardEpoch , uint256 _priceEpochEndTime , uint256 _votePowerBlock ) external ; Distributes price epoch rewards to data provider accounts, according to input parameters. Must be called with totalWeight > 0 and addresses.length > 0. The amount of rewards for a given price epoch ID are calculated in FtsoRewardManager from priceEpochDurationSeconds , priceEpochEndTime and inflation authorization data (see _getTotalPriceEpochRewardWei in FtsoRewardManager . Then each data provider address is given a portion of this amount according to corresponding weight and total sum of weights. Parameters epochId and ftso are only needed so they can be passed onto the emitted event. Only the ftsoManager can call this method. Parameters Type Description _addresses address[] _weights uint256[] _totalWeight uint256 _epochId uint256 _ftso address _priceEpochDurationSeconds uint256 _currentRewardEpoch uint256 _priceEpochEndTime uint256 _votePowerBlock uint256","title":"distributeRewards"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_enableclaims_ea28edad","text":"Defined in FtsoRewardManager ( Docs , Source ). function enableClaims ( ) external ; Enable claiming for current and all future reward epochs. Only governance can call this method.","title":"enableClaims"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_executegovernancecall_5ff27079","text":"Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored).","title":"executeGovernanceCall"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_feepercentageupdateoffset_16fe49c7","text":"Defined in FtsoRewardManager ( Docs , Source ). function feePercentageUpdateOffset ( ) external view returns ( uint256 ); Returns the amount of reward epoch that need to ellapse before a fee change takes effect.","title":"feePercentageUpdateOffset"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_firstclaimablerewardepoch_7b6b2c0a","text":"Defined in IIFtsoRewardManager ( Docs , Source ). function firstClaimableRewardEpoch ( ) external view returns ( uint256 ); Epochs before the token distribution event at Flare launch were not be claimable. Use this method to know the first reward epoch that was claimable. Returns Type Description [0] uint256 uint256 The first reward epoch that can be claimed.","title":"firstClaimableRewardEpoch"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_getaddressupdater_5267a15d","text":"Defined in AddressUpdatable ( Docs , Source ). function getAddressUpdater ( ) public view returns ( address _addressUpdater ); Returns the configured address updater. Returns Type Description _addressUpdater address The AddresUpdater contract that can update our contract address list, as a response to a governance call.","title":"getAddressUpdater"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_getclaimedreward_85b4c538","text":"Defined in FtsoRewardManager ( Docs , Source ). function getClaimedReward ( uint256 _rewardEpoch , address _dataProvider , address _claimer ) external view returns ( bool _claimed , uint256 _amount ); Returns information on the rewards accrued by a reward owner from a specific data provider at a specific reward epoch. Parameters Type Description _rewardEpoch uint256 Reward epoch ID to query. _dataProvider address Address of the data provider to query. _claimer address Address of the reward owner to query. Returns Type Description _claimed bool Whether the reward has been claimed or not. _amount uint256 Accrued amount in wei.","title":"getClaimedReward"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_getcontractname_f5f5ba72","text":"Defined in FtsoRewardManager ( Docs , Source ). function getContractName ( ) external pure returns ( string ); Implement this function to allow updating inflation receiver contracts through AddressUpdater . Returns Type Description [0] string Contract name.","title":"getContractName"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_getcurrentrewardepoch_e7c830d4","text":"Defined in FtsoRewardManager ( Docs , Source ). function getCurrentRewardEpoch ( ) external view returns ( uint256 ); Returns the current reward epoch ID.","title":"getCurrentRewardEpoch"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_getdataprovidercurrentfeepercentage_cfbcd25f","text":"Defined in FtsoRewardManager ( Docs , Source ). function getDataProviderCurrentFeePercentage ( address _dataProvider ) external view returns ( uint256 ); Returns the current fee percentage of a data provider. Parameters Type Description _dataProvider address Address of the queried data provider. Returns Type Description [0] uint256","title":"getDataProviderCurrentFeePercentage"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_getdataproviderfeepercentage_961c00ed","text":"Defined in FtsoRewardManager ( Docs , Source ). function getDataProviderFeePercentage ( address _dataProvider , uint256 _rewardEpoch ) external view returns ( uint256 _feePercentageBIPS ); Returns the fee percentage of a data provider at a given reward epoch. Parameters Type Description _dataProvider address Address of the queried data provider. _rewardEpoch uint256 Reward epoch ID. Returns Type Description _feePercentageBIPS uint256 Fee percentage in BIPS.","title":"getDataProviderFeePercentage"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_getdataproviderperformanceinfo_eb82dd7f","text":"Defined in FtsoRewardManager ( Docs , Source ). function getDataProviderPerformanceInfo ( uint256 _rewardEpoch , address _dataProvider ) external view returns ( uint256 _rewardAmount , uint256 _votePowerIgnoringRevocation ); Returns information on rewards and vote power of a data provider at a given reward epoch. Parameters Type Description _rewardEpoch uint256 Reward epoch ID. _dataProvider address Address of the data provider to query. Returns Type Description _rewardAmount uint256 Amount of rewards (wei). _votePowerIgnoringRevocation uint256 Vote power, not including revocations.","title":"getDataProviderPerformanceInfo"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_getdataproviderscheduledfeepercentagechanges_33b7971e","text":"Defined in FtsoRewardManager ( Docs , Source ). function getDataProviderScheduledFeePercentageChanges ( address _dataProvider ) external view returns ( uint256 [] _feePercentageBIPS , uint256 [] _validFromEpoch , bool [] _fixed ); Returns the scheduled fee percentage changes for a data provider. Parameters Type Description _dataProvider address Address of the queried data provider. Returns Type Description _feePercentageBIPS uint256[] Array of fee percentages in BIPS. _validFromEpoch uint256[] Array of block numbers from which the fee settings are effective. _fixed bool[] Array of boolean values indicating whether settings are subject to change or not.","title":"getDataProviderScheduledFeePercentageChanges"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_getepochreward_d418634a","text":"Defined in FtsoRewardManager ( Docs , Source ). function getEpochReward ( uint256 _rewardEpoch ) external view returns ( uint256 _totalReward , uint256 _claimedReward ); Returns information on an epoch's rewards. Parameters Type Description _rewardEpoch uint256 Reward epoch ID. Returns Type Description _totalReward uint256 Total amount of rewards accrued on that epoch, in wei. _claimedReward uint256 Total amount of rewards that have already been claimed, in wei.","title":"getEpochReward"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_getepochswithclaimablerewards_0441218e","text":"Defined in FtsoRewardManager ( Docs , Source ). function getEpochsWithClaimableRewards ( ) external view returns ( uint256 _startEpochId , uint256 _endEpochId ); Returns the reward epoch range for which rewards can be claimed. Rewards outside this range are unclaimable, either because they have expired or because the reward epoch is still ongoing. Returns Type Description _startEpochId uint256 The oldest epoch ID that allows reward claiming. _endEpochId uint256 The newest epoch ID that allows reward claiming.","title":"getEpochsWithClaimableRewards"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_getepochswithunclaimedrewards_b4a2043d","text":"Defined in FtsoRewardManager ( Docs , Source ). function getEpochsWithUnclaimedRewards ( address _beneficiary ) external view returns ( uint256 [] _epochIds ); Returns the array of claimable epoch IDs for which the rewards of a reward owner have not yet been claimed. Parameters Type Description _beneficiary address Address of the reward owner to query. Reverts if it uses delegation by amount. Returns Type Description _epochIds uint256[] Array of epoch IDs.","title":"getEpochsWithUnclaimedRewards"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_getexpectedbalance_af04cd3b","text":"Defined in FtsoRewardManager ( Docs , Source ). function getExpectedBalance ( ) external view returns ( uint256 ); Returns the contract's expected balance (actual balance may be higher due to self-destruct funds). Returns Type Description [0] uint256 Expected native token balance.","title":"getExpectedBalance"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_getinflationaddress_ed39d3f8","text":"Defined in FtsoRewardManager ( Docs , Source ). function getInflationAddress ( ) external view returns ( address ); Returns the address of the Inflation contract.","title":"getInflationAddress"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_getinitialrewardepoch_3123b7d8","text":"Defined in FtsoRewardManager ( Docs , Source ). function getInitialRewardEpoch ( ) external view returns ( uint256 _initialRewardEpoch ); Returns the initial reward epoch ID for this reward manager contract. This corresponds to the oldest reward epoch with claimable rewards in the previous reward manager when this one took over. Set by governance through setInitialRewardData .","title":"getInitialRewardEpoch"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_getrewardepochtoexpirenext_3e7ff857","text":"Defined in FtsoRewardManager ( Docs , Source ). function getRewardEpochToExpireNext ( ) external view returns ( uint256 ); Returns the reward epoch that will expire next once a new reward epoch starts.","title":"getRewardEpochToExpireNext"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_getrewardepochvotepowerblock_f2edab5a","text":"Defined in FtsoRewardManager ( Docs , Source ). function getRewardEpochVotePowerBlock ( uint256 _rewardEpoch ) external view returns ( uint256 ); Returns the vote power block of a given reward epoch. Parameters Type Description _rewardEpoch uint256 Reward epoch ID.","title":"getRewardEpochVotePowerBlock"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_getstateofrewards_a4472c10","text":"Defined in FtsoRewardManager ( Docs , Source ). function getStateOfRewards ( address _beneficiary , uint256 _rewardEpoch ) external view returns ( address [] _dataProviders , uint256 [] _rewardAmounts , bool [] _claimed , bool _claimable ); Returns the state of rewards for a given address at a specific reward epoch. Parameters Type Description _beneficiary address Address of the beneficiary to query. It can be a data provider or a delegator, for example. Reverts if the queried address is delegating by amount. _rewardEpoch uint256 Reward epoch ID to query. Returns Type Description _dataProviders address[] Array of addresses of data providers. _rewardAmounts uint256[] Array of reward amounts received from each provider, in wei. _claimed bool[] Array of boolean values indicating whether each reward has been claimed or not. _claimable bool Boolean value indicating whether rewards are claimable or not.","title":"getStateOfRewards"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_getstateofrewardsfromdataproviders_e416b7e1","text":"Defined in FtsoRewardManager ( Docs , Source ). function getStateOfRewardsFromDataProviders ( address _beneficiary , uint256 _rewardEpoch , address [] _dataProviders ) external view returns ( uint256 [] _rewardAmounts , bool [] _claimed , bool _claimable ); Returns the state of rewards for a given address coming from a specific set of data providers, at a specific reward epoch. Parameters Type Description _beneficiary address Address of beneficiary to query. _rewardEpoch uint256 Reward epoch ID to query. _dataProviders address[] Array of addresses of the data providers to query. Returns Type Description _rewardAmounts uint256[] Array of reward amounts received from each provider, in wei. _claimed bool[] Array of boolean values indicating whether each reward has been claimed or not. _claimable bool Boolean value indicating whether rewards are claimable or not.","title":"getStateOfRewardsFromDataProviders"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_gettokenpoolsupplydata_2dafdbbf","text":"Defined in FtsoRewardManager ( Docs , Source ). function getTokenPoolSupplyData ( ) external view returns ( uint256 _lockedFundsWei , uint256 _totalInflationAuthorizedWei , uint256 _totalClaimedWei ); Returns token pool supply data. Returns Type Description _lockedFundsWei uint256 Total amount of funds ever locked in the token pool (wei). _lockedFundsWei - _totalClaimedWei is the amount currently locked and outside the circulating supply. _totalInflationAuthorizedWei uint256 Total inflation authorized amount (wei). _totalClaimedWei uint256 Total claimed amount (wei).","title":"getTokenPoolSupplyData"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_gettotals_84e10a90","text":"Defined in FtsoRewardManager ( Docs , Source ). function getTotals ( ) external view returns ( uint256 _totalAwardedWei , uint256 _totalClaimedWei , uint256 _totalExpiredWei , uint256 _totalUnearnedWei , uint256 _totalBurnedWei , uint256 _totalInflationAuthorizedWei , uint256 _totalInflationReceivedWei , uint256 _lastInflationAuthorizationReceivedTs , uint256 _dailyAuthorizedInflation ); Returns statistics regarding rewards, accumulated over the whole lifespan of the reward manager contract. Returns Type Description _totalAwardedWei uint256 Rewards that were distributed (wei). _totalClaimedWei uint256 Distributed rewards that were claimed in time (wei). _totalExpiredWei uint256 Distributed rewards that were not claimed in time and expired (wei). _totalUnearnedWei uint256 Rewards that were unearned (due to FTSO being in fallback mode) and thus were not distributed (wei). _totalBurnedWei uint256 Rewards that were unearned or expired and thus burned (wei). _totalInflationAuthorizedWei uint256 Total inflation authorized amount (wei). _totalInflationReceivedWei uint256 Total inflation received amount (wei). _lastInflationAuthorizationReceivedTs uint256 UNIX timestamp of the last inflation authorization. _dailyAuthorizedInflation uint256 Inflation authorized amount (wei) at the time of last authorization.","title":"getTotals"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_getunclaimedreward_657d9695","text":"Defined in FtsoRewardManager ( Docs , Source ). function getUnclaimedReward ( uint256 _rewardEpoch , address _dataProvider ) external view returns ( uint256 _amount , uint256 _weight ); Returns information on unclaimed rewards for a given data provider and epoch. Parameters Type Description _rewardEpoch uint256 Queried reward epoch ID. _dataProvider address Address of the queried data provider. Returns Type Description _amount uint256 Amount available to be claimed, in wei. _weight uint256 Portion of total vote power used in this reward epoch that has not yet claimed its reward, in BIPS. It decreases to 0 when all data providers have claimed their rewards.","title":"getUnclaimedReward"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_governance_5aa6e675","text":"Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address.","title":"governance"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_nextclaimablerewardepoch_69b91b59","text":"Defined in FtsoRewardManager ( Docs , Source ). function nextClaimableRewardEpoch ( address _rewardOwner ) external view returns ( uint256 ); Returns the next claimable reward epoch for a reward owner. Parameters Type Description _rewardOwner address Address of the reward owner to query.","title":"nextClaimableRewardEpoch"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_receiveinflation_06201f1d","text":"Defined in FtsoRewardManager ( Docs , Source ). function receiveInflation ( ) external payable ; Receive native tokens from inflation. Only the inflation contract can call this method.","title":"receiveInflation"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_setdailyauthorizedinflation_e2739563","text":"Defined in FtsoRewardManager ( Docs , Source ). function setDailyAuthorizedInflation ( uint256 _toAuthorizeWei ) external ; Notify the receiver that it is entitled to receive a new inflation amount. Only the inflation contract can call this method. Parameters Type Description _toAuthorizeWei uint256 The amount of inflation that can be awarded in the coming day, in wei.","title":"setDailyAuthorizedInflation"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_setdataproviderfeepercentage_16e69328","text":"Defined in FtsoRewardManager ( Docs , Source ). function setDataProviderFeePercentage ( uint256 _feePercentageBIPS ) external returns ( uint256 ); Sets the fee a data provider keeps from all delegations. Takes effect after feeValueUpdateOffset reward epochs have elapsed. When called multiple times inside the same reward epoch, only the last value remains. Parameters Type Description _feePercentageBIPS uint256 Fee percentage in BIPS. Returns Type Description [0] uint256","title":"setDataProviderFeePercentage"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_setinitialrewarddata_1de56098","text":"Defined in FtsoRewardManager ( Docs , Source ). function setInitialRewardData ( ) external ; Copy initial reward data from oldFtsoRewardManager before starting up this new reward manager. Should be called at the time of switching to the new reward manager, can be called only once, and only by governance .","title":"setInitialRewardData"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_setnewftsorewardmanager_82a2b905","text":"Defined in FtsoRewardManager ( Docs , Source ). function setNewFtsoRewardManager ( address _newFtsoRewardManager ) external ; Sets new ftso reward manager which will take over closing expired reward epochs Should be called at the time of switching to the new reward manager, can be called only once, and only by governance .","title":"setNewFtsoRewardManager"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_switchtoproductionmode_f5a98383","text":"Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered .","title":"switchToProductionMode"},{"location":"apis/smart-contracts/FtsoRewardManager/#fn_updatecontractaddresses_b00c0b76","text":"Defined in AddressUpdatable ( Docs , Source ). function updateContractAddresses ( bytes32 [] _contractNameHashes , address [] _contractAddresses ) external ; External method called from AddressUpdater only.","title":"updateContractAddresses"},{"location":"apis/smart-contracts/FtsoRewardManager/#modifiers","text":"","title":"Modifiers"},{"location":"apis/smart-contracts/FtsoRewardManager/#md_mustbalance","text":"Defined in FtsoRewardManager ( Docs , Source ). modifier mustBalance ()","title":"mustBalance"},{"location":"apis/smart-contracts/FtsoRewardManager/#md_nonreentrant","text":"Defined in ReentrancyGuard ( Source ). modifier nonReentrant () Prevents a contract from calling itself, directly or indirectly. Calling a nonReentrant function from another nonReentrant function is not supported. It is possible to prevent this from happening by making the nonReentrant function external, and make it call a private function that does the actual work.","title":"nonReentrant"},{"location":"apis/smart-contracts/FtsoRewardManager/#md_onlyaddressupdater","text":"Defined in AddressUpdatable ( Docs , Source ). modifier onlyAddressUpdater () Only the AdressUpdater contract can call this method. Its address is set at construction time but it can also update itself.","title":"onlyAddressUpdater"},{"location":"apis/smart-contracts/FtsoRewardManager/#md_onlyexecutorandallowedrecipient","text":"Defined in FtsoRewardManager ( Docs , Source ). modifier onlyExecutorAndAllowedRecipient ( address _rewardOwner , address _recipient ) Only the reward owner and its authorized executors can call this method. Executors can only send rewards to authorized recipients. See ClaimSetupManager .","title":"onlyExecutorAndAllowedRecipient"},{"location":"apis/smart-contracts/FtsoRewardManager/#md_onlyftsomanager","text":"Defined in FtsoRewardManager ( Docs , Source ). modifier onlyFtsoManager () Only the ftsoManager contract can call this method.","title":"onlyFtsoManager"},{"location":"apis/smart-contracts/FtsoRewardManager/#md_onlygovernance","text":"Defined in GovernedBase ( Docs , Source ). modifier onlyGovernance ()","title":"onlyGovernance"},{"location":"apis/smart-contracts/FtsoRewardManager/#md_onlyifactive","text":"Defined in FtsoRewardManager ( Docs , Source ). modifier onlyIfActive () This method can only be called if the contract is active .","title":"onlyIfActive"},{"location":"apis/smart-contracts/FtsoRewardManager/#md_onlyimmediategovernance","text":"Defined in GovernedBase ( Docs , Source ). modifier onlyImmediateGovernance ()","title":"onlyImmediateGovernance"},{"location":"apis/smart-contracts/FtsoRewardManager/#md_onlyinflation","text":"Defined in FtsoRewardManager ( Docs , Source ). modifier onlyInflation () Only the Inflation contract can call this method.","title":"onlyInflation"},{"location":"apis/smart-contracts/FtsoRewardManager/#structures","text":"","title":"Structures"},{"location":"apis/smart-contracts/FtsoRewardManager/#st_rewardclaim","text":"Defined in FtsoRewardManager ( Docs , Source ). struct RewardClaim { bool claimed ; uint128 amount ; }","title":"RewardClaim"},{"location":"apis/smart-contracts/FtsoRewardManager/#st_rewardstate","text":"Defined in FtsoRewardManager ( Docs , Source ). struct RewardState { address [] dataProviders ; uint256 [] weights ; uint256 [] amounts ; bool [] claimed ; }","title":"RewardState"},{"location":"apis/smart-contracts/FtsoRewardManager/#st_timelockedcall","text":"Defined in GovernedBase ( Docs , Source ). struct TimelockedCall { uint256 allowedAfterTimestamp ; bytes encodedCall ; }","title":"TimelockedCall"},{"location":"apis/smart-contracts/FtsoRewardManager/#st_unclaimedrewardstate","text":"Defined in FtsoRewardManager ( Docs , Source ). struct UnclaimedRewardState { uint128 amount ; uint128 weight ; }","title":"UnclaimedRewardState"},{"location":"apis/smart-contracts/FtsoRewardManager/#variables","text":"","title":"Variables"},{"location":"apis/smart-contracts/FtsoRewardManager/#va_active","text":"Defined in FtsoRewardManager ( Docs , Source ). bool active Whether rewards can be claimed from this reward manager.","title":"active"},{"location":"apis/smart-contracts/FtsoRewardManager/#va_claimsetupmanager","text":"Defined in FtsoRewardManager ( Docs , Source ). contract IIClaimSetupManager claimSetupManager The ClaimSetupManager contract that helps automate reward claiming.","title":"claimSetupManager"},{"location":"apis/smart-contracts/FtsoRewardManager/#va_firstclaimablerewardepoch","text":"Defined in FtsoRewardManager ( Docs , Source ). uint256 firstClaimableRewardEpoch Epochs before the token distribution event at Flare launch were not be claimable. This variable holds the first reward epoch that was claimable.","title":"firstClaimableRewardEpoch"},{"location":"apis/smart-contracts/FtsoRewardManager/#va_ftsomanager","text":"Defined in FtsoRewardManager ( Docs , Source ). contract IIFtsoManager ftsoManager The FtsoManager contract that controls reward distribution.","title":"ftsoManager"},{"location":"apis/smart-contracts/FtsoRewardManager/#va_governancesettings","text":"Defined in GovernedBase ( Docs , Source ). contract IGovernanceSettings governanceSettings Governance Settings.","title":"governanceSettings"},{"location":"apis/smart-contracts/FtsoRewardManager/#va_newftsorewardmanager","text":"Defined in FtsoRewardManager ( Docs , Source ). address newFtsoRewardManager Address of the new FtsoRewardManager that replaced this one.","title":"newFtsoRewardManager"},{"location":"apis/smart-contracts/FtsoRewardManager/#va_oldftsorewardmanager","text":"Defined in FtsoRewardManager ( Docs , Source ). address oldFtsoRewardManager Address of the old FtsoRewardManager , replaced by this one.","title":"oldFtsoRewardManager"},{"location":"apis/smart-contracts/FtsoRewardManager/#va_productionmode","text":"Defined in GovernedBase ( Docs , Source ). bool productionMode When true, governance is enabled and cannot be disabled. See switchToProductionMode .","title":"productionMode"},{"location":"apis/smart-contracts/FtsoRewardManager/#va_timelockedcalls","text":"Defined in GovernedBase ( Docs , Source ). mapping ( bytes4 => struct GovernedBase . TimelockedCall ) timelockedCalls List of pending timelocked governance calls.","title":"timelockedCalls"},{"location":"apis/smart-contracts/FtsoRewardManager/#va_wnat","text":"Defined in FtsoRewardManager ( Docs , Source ). contract WNat wNat Address of the wrapped native token ( WNat ) contract.","title":"wNat"},{"location":"apis/smart-contracts/GovernanceSettings/","text":"GovernanceSettings # Source | Inherits from IGovernanceSettings A special contract that holds the Flare governance address and its timelock. All governance calls are delayed by the timelock specified in this contract. This contract enables updating governance address and timelock only by hard-forking the network, this is, only by updating validator code. Events # GovernanceAddressUpdated # Defined in GovernanceSettings ( Docs , Source ). event GovernanceAddressUpdated ( uint256 timestamp , address oldGovernanceAddress , address newGovernanceAddress ) Emitted when the governance address has been changed. Parameters Type Description timestamp uint256 Timestamp of the block where the change happened, in seconds from UNIX epoch. oldGovernanceAddress address Governance address before the change. newGovernanceAddress address Governance address after the change. GovernanceExecutorsUpdated # Defined in GovernanceSettings ( Docs , Source ). event GovernanceExecutorsUpdated ( uint256 timestamp , address [] oldExecutors , address [] newExecutors ) The list of addresses that are allowed to perform governance calls has been changed. Parameters Type Description timestamp uint256 Timestamp of the block where the change happened, in seconds from UNIX epoch. oldExecutors address[] Array of executor addresses before the change. newExecutors address[] Array of executor addresses after the change. GovernanceTimelockUpdated # Defined in GovernanceSettings ( Docs , Source ). event GovernanceTimelockUpdated ( uint256 timestamp , uint256 oldTimelock , uint256 newTimelock ) Emitted when the timelock has been changed. Parameters Type Description timestamp uint256 Timestamp of the block where the change happened, in seconds from UNIX epoch. oldTimelock uint256 Timelock before the change (in seconds). newTimelock uint256 Timelock after the change (in seconds). Functions # getExecutors # Defined in GovernanceSettings ( Docs , Source ). function getExecutors ( ) external view returns ( address []); Gets the addresses of the accounts that are allowed to execute the timelocked governance calls, once the timelock period expires. Executors can be changed without a hard fork, via a normal governance call. Returns Type Description [0] address[] getGovernanceAddress # Defined in GovernanceSettings ( Docs , Source ). function getGovernanceAddress ( ) external view returns ( address ); Gets the governance account address. The governance address can only be changed by a hard fork. Returns Type Description [0] address getTimelock # Defined in GovernanceSettings ( Docs , Source ). function getTimelock ( ) external view returns ( uint256 ); Gets the time in seconds that must pass between a governance call and its execution. The timelock value can only be changed by a hard fork. Returns Type Description [0] uint256 initialise # Defined in GovernanceSettings ( Docs , Source ). function initialise ( address _governanceAddress , uint256 _timelock , address [] _executors ) external ; Perform initialization, which cannot be done in constructor, since this is a genesis contract. Can only be called once. Parameters Type Description _governanceAddress address Initial governance address. _timelock uint256 Initial timelock value, in seconds. _executors address[] Initial list of addresses allowed to perform governance calls. isExecutor # Defined in GovernanceSettings ( Docs , Source ). function isExecutor ( address _address ) external view returns ( bool ); Checks whether an address is one of the allowed executors. See getExecutors . Parameters Type Description _address address The address to check. Returns Type Description [0] bool True if _address is in the executors list. setExecutors # Defined in GovernanceSettings ( Docs , Source ). function setExecutors ( address [] _newExecutors ) external ; Set the addresses of the accounts that are allowed to execute the timelocked governance calls once the timelock period expires. It isn't very dangerous to allow for anyone to execute timelocked calls, but we reserve the right to make sure the timing of the execution is under control. Can only be called by the governance. Parameters Type Description _newExecutors address[] New list of allowed executors. The previous list is replaced. setGovernanceAddress # Defined in GovernanceSettings ( Docs , Source ). function setGovernanceAddress ( address _newGovernance ) external ; Change the governance address. Can only be called by validators via fork. Parameters Type Description _newGovernance address New governance address. setTimelock # Defined in GovernanceSettings ( Docs , Source ). function setTimelock ( uint256 _newTimelock ) external ; Change the timelock, this is, the amount of time between a governance call and its execution. Can only be called by validators via fork. Parameters Type Description _newTimelock uint256 New timelock value, in seconds. Variables # SIGNAL_COINBASE # Defined in GovernanceSettings ( Docs , Source ). address SIGNAL_COINBASE","title":"GovernanceSettings"},{"location":"apis/smart-contracts/GovernanceSettings/#ct_governancesettings","text":"Source | Inherits from IGovernanceSettings A special contract that holds the Flare governance address and its timelock. All governance calls are delayed by the timelock specified in this contract. This contract enables updating governance address and timelock only by hard-forking the network, this is, only by updating validator code.","title":"GovernanceSettings"},{"location":"apis/smart-contracts/GovernanceSettings/#events","text":"","title":"Events"},{"location":"apis/smart-contracts/GovernanceSettings/#ev_governanceaddressupdated","text":"Defined in GovernanceSettings ( Docs , Source ). event GovernanceAddressUpdated ( uint256 timestamp , address oldGovernanceAddress , address newGovernanceAddress ) Emitted when the governance address has been changed. Parameters Type Description timestamp uint256 Timestamp of the block where the change happened, in seconds from UNIX epoch. oldGovernanceAddress address Governance address before the change. newGovernanceAddress address Governance address after the change.","title":"GovernanceAddressUpdated"},{"location":"apis/smart-contracts/GovernanceSettings/#ev_governanceexecutorsupdated","text":"Defined in GovernanceSettings ( Docs , Source ). event GovernanceExecutorsUpdated ( uint256 timestamp , address [] oldExecutors , address [] newExecutors ) The list of addresses that are allowed to perform governance calls has been changed. Parameters Type Description timestamp uint256 Timestamp of the block where the change happened, in seconds from UNIX epoch. oldExecutors address[] Array of executor addresses before the change. newExecutors address[] Array of executor addresses after the change.","title":"GovernanceExecutorsUpdated"},{"location":"apis/smart-contracts/GovernanceSettings/#ev_governancetimelockupdated","text":"Defined in GovernanceSettings ( Docs , Source ). event GovernanceTimelockUpdated ( uint256 timestamp , uint256 oldTimelock , uint256 newTimelock ) Emitted when the timelock has been changed. Parameters Type Description timestamp uint256 Timestamp of the block where the change happened, in seconds from UNIX epoch. oldTimelock uint256 Timelock before the change (in seconds). newTimelock uint256 Timelock after the change (in seconds).","title":"GovernanceTimelockUpdated"},{"location":"apis/smart-contracts/GovernanceSettings/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/GovernanceSettings/#fn_getexecutors_ef09e78f","text":"Defined in GovernanceSettings ( Docs , Source ). function getExecutors ( ) external view returns ( address []); Gets the addresses of the accounts that are allowed to execute the timelocked governance calls, once the timelock period expires. Executors can be changed without a hard fork, via a normal governance call. Returns Type Description [0] address[]","title":"getExecutors"},{"location":"apis/smart-contracts/GovernanceSettings/#fn_getgovernanceaddress_73252494","text":"Defined in GovernanceSettings ( Docs , Source ). function getGovernanceAddress ( ) external view returns ( address ); Gets the governance account address. The governance address can only be changed by a hard fork. Returns Type Description [0] address","title":"getGovernanceAddress"},{"location":"apis/smart-contracts/GovernanceSettings/#fn_gettimelock_6221a54b","text":"Defined in GovernanceSettings ( Docs , Source ). function getTimelock ( ) external view returns ( uint256 ); Gets the time in seconds that must pass between a governance call and its execution. The timelock value can only be changed by a hard fork. Returns Type Description [0] uint256","title":"getTimelock"},{"location":"apis/smart-contracts/GovernanceSettings/#fn_initialise_cf0ea268","text":"Defined in GovernanceSettings ( Docs , Source ). function initialise ( address _governanceAddress , uint256 _timelock , address [] _executors ) external ; Perform initialization, which cannot be done in constructor, since this is a genesis contract. Can only be called once. Parameters Type Description _governanceAddress address Initial governance address. _timelock uint256 Initial timelock value, in seconds. _executors address[] Initial list of addresses allowed to perform governance calls.","title":"initialise"},{"location":"apis/smart-contracts/GovernanceSettings/#fn_isexecutor_debfda30","text":"Defined in GovernanceSettings ( Docs , Source ). function isExecutor ( address _address ) external view returns ( bool ); Checks whether an address is one of the allowed executors. See getExecutors . Parameters Type Description _address address The address to check. Returns Type Description [0] bool True if _address is in the executors list.","title":"isExecutor"},{"location":"apis/smart-contracts/GovernanceSettings/#fn_setexecutors_1d452e46","text":"Defined in GovernanceSettings ( Docs , Source ). function setExecutors ( address [] _newExecutors ) external ; Set the addresses of the accounts that are allowed to execute the timelocked governance calls once the timelock period expires. It isn't very dangerous to allow for anyone to execute timelocked calls, but we reserve the right to make sure the timing of the execution is under control. Can only be called by the governance. Parameters Type Description _newExecutors address[] New list of allowed executors. The previous list is replaced.","title":"setExecutors"},{"location":"apis/smart-contracts/GovernanceSettings/#fn_setgovernanceaddress_cfc16254","text":"Defined in GovernanceSettings ( Docs , Source ). function setGovernanceAddress ( address _newGovernance ) external ; Change the governance address. Can only be called by validators via fork. Parameters Type Description _newGovernance address New governance address.","title":"setGovernanceAddress"},{"location":"apis/smart-contracts/GovernanceSettings/#fn_settimelock_1e891c0a","text":"Defined in GovernanceSettings ( Docs , Source ). function setTimelock ( uint256 _newTimelock ) external ; Change the timelock, this is, the amount of time between a governance call and its execution. Can only be called by validators via fork. Parameters Type Description _newTimelock uint256 New timelock value, in seconds.","title":"setTimelock"},{"location":"apis/smart-contracts/GovernanceSettings/#variables","text":"","title":"Variables"},{"location":"apis/smart-contracts/GovernanceSettings/#va_signal_coinbase","text":"Defined in GovernanceSettings ( Docs , Source ). address SIGNAL_COINBASE","title":"SIGNAL_COINBASE"},{"location":"apis/smart-contracts/GovernanceVotePower/","text":"GovernanceVotePower # Source | Inherits from IIGovernanceVotePower Contract managing governance vote power and its delegation. Functions # constructor # Defined in GovernanceVotePower ( Docs , Source ). constructor ( contract IVPToken _ownerToken ) public ; Construct GovernanceVotePower for given VPToken . delegate # Defined in GovernanceVotePower ( Docs , Source ). function delegate ( address _to ) public ; Delegates all governance vote power of msg.sender to address _to . Parameters Type Description _to address The address of the recipient. delegatedGovernanceVotePowerHistoryCleanup # Defined in GovernanceVotePower ( Docs , Source ). function delegatedGovernanceVotePowerHistoryCleanup ( address _owner , uint256 _count ) external returns ( uint256 ); Delete governance vote power checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _owner address Vote power owner account address. _count uint256 Maximum number of checkpoints to delete. Returns Type Description [0] uint256 The number of deleted checkpoints. delegatesHistoryCleanup # Defined in GovernanceVotePower ( Docs , Source ). function delegatesHistoryCleanup ( address _owner , uint256 _count ) external returns ( uint256 ); Delete delegates checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _owner address Vote power owner account address. _count uint256 Maximum number of checkpoints to delete. Returns Type Description [0] uint256 The number of deleted checkpoints. getCleanupBlockNumber # Defined in GovernanceVotePower ( Docs , Source ). function getCleanupBlockNumber ( ) external view returns ( uint256 ); Get the current cleanup block number set with setCleanupBlockNumber . Returns Type Description [0] uint256 The currently set cleanup block number. getDelegateOfAt # Defined in GovernanceVotePower ( Docs , Source ). function getDelegateOfAt ( address _who , uint256 _blockNumber ) public view returns ( address ); Gets the address an account is delegating its governance vote power to, at a given block number. Parameters Type Description _who address The address being queried. _blockNumber uint256 The block number at which to fetch the address. Returns Type Description [0] address Address where _who was delegating its governance vote power at block _blockNumber . getDelegateOfAtNow # Defined in GovernanceVotePower ( Docs , Source ). function getDelegateOfAtNow ( address _who ) public view returns ( address ); Gets the address an account is delegating its governance vote power to, at the latest block number. Parameters Type Description _who address The address being queried. Returns Type Description [0] address Address where _who is currently delegating its governance vote power. getVotes # Defined in GovernanceVotePower ( Docs , Source ). function getVotes ( address _who ) public view returns ( uint256 ); Gets the governance vote power of an address at the latest block, including all delegations made to it. Parameters Type Description _who address The address being queried. Returns Type Description [0] uint256 Governance vote power of account at the lastest block. ownerToken # Defined in IIGovernanceVotePower ( Docs , Source ). function ownerToken ( ) external view returns ( contract IVPToken ); Get the token that this governance vote power contract belongs to. Returns Type Description [0] contract IVPToken The IVPToken interface owning this contract. setCleanerContract # Defined in GovernanceVotePower ( Docs , Source ). function setCleanerContract ( address _cleanerContract ) external ; Set the contract that is allowed to call history cleaning methods. This method can be called by the ownerToken only. Parameters Type Description _cleanerContract address Address of the cleanup contract. Usually this will be an instance of CleanupBlockNumberManager . setCleanupBlockNumber # Defined in GovernanceVotePower ( Docs , Source ). function setCleanupBlockNumber ( uint256 _blockNumber ) external ; Set the cleanup block number. Historic data for the blocks before cleanupBlockNumber can be erased. History before that block should never be used since it can be inconsistent. In particular, cleanup block number must be lower than the current vote power block. This method can be called by the ownerToken only. Parameters Type Description _blockNumber uint256 The new cleanup block number. undelegate # Defined in GovernanceVotePower ( Docs , Source ). function undelegate ( ) public ; Undelegates all governance vote power of msg.sender . updateAtTokenTransfer # Defined in GovernanceVotePower ( Docs , Source ). function updateAtTokenTransfer ( address _from , address _to , uint256 , uint256 , uint256 _amount ) external ; Update governance vote power of all involved delegates after tokens are transferred. This function MUST be called after each governance token transfer for the delegates to reflect the correct balance. Parameters Type Description _from address Source address of the transfer. _to address Destination address of the transfer. `` uint256 `` uint256 _amount uint256 Amount being transferred. votePowerOfAt # Defined in GovernanceVotePower ( Docs , Source ). function votePowerOfAt ( address _who , uint256 _blockNumber ) public view returns ( uint256 ); Gets the governance vote power of an address at a given block number, including all delegations made to it. Parameters Type Description _who address The address being queried. _blockNumber uint256 The block number at which to fetch the vote power. Returns Type Description [0] uint256 Governance vote power of _who at _blockNumber . Modifiers # onlyCleaner # Defined in GovernanceVotePower ( Docs , Source ). modifier onlyCleaner () History cleaning methods can be called only from the cleaner address. onlyOwnerToken # Defined in GovernanceVotePower ( Docs , Source ). modifier onlyOwnerToken () All external methods in GovernanceVotePower can only be executed by the owner token. Variables # cleanerContract # Defined in GovernanceVotePower ( Docs , Source ). address cleanerContract Address of the contract that is allowed to call methods for history cleaning. Set with setCleanerContract . ownerToken # Defined in GovernanceVotePower ( Docs , Source ). contract IVPToken ownerToken The VPToken (or some other contract) that owns this GovernanceVotePower . All state changing methods may be called only from this address. This is because original msg.sender is typically sent in a parameter and we must make sure that it cannot be faked by directly calling GovernanceVotePower methods.","title":"GovernanceVotePower"},{"location":"apis/smart-contracts/GovernanceVotePower/#ct_governancevotepower","text":"Source | Inherits from IIGovernanceVotePower Contract managing governance vote power and its delegation.","title":"GovernanceVotePower"},{"location":"apis/smart-contracts/GovernanceVotePower/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/GovernanceVotePower/#fn_constructor_undefined","text":"Defined in GovernanceVotePower ( Docs , Source ). constructor ( contract IVPToken _ownerToken ) public ; Construct GovernanceVotePower for given VPToken .","title":"constructor"},{"location":"apis/smart-contracts/GovernanceVotePower/#fn_delegate_5c19a95c","text":"Defined in GovernanceVotePower ( Docs , Source ). function delegate ( address _to ) public ; Delegates all governance vote power of msg.sender to address _to . Parameters Type Description _to address The address of the recipient.","title":"delegate"},{"location":"apis/smart-contracts/GovernanceVotePower/#fn_delegatedgovernancevotepowerhistorycleanup_29a59ff2","text":"Defined in GovernanceVotePower ( Docs , Source ). function delegatedGovernanceVotePowerHistoryCleanup ( address _owner , uint256 _count ) external returns ( uint256 ); Delete governance vote power checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _owner address Vote power owner account address. _count uint256 Maximum number of checkpoints to delete. Returns Type Description [0] uint256 The number of deleted checkpoints.","title":"delegatedGovernanceVotePowerHistoryCleanup"},{"location":"apis/smart-contracts/GovernanceVotePower/#fn_delegateshistorycleanup_f7ce0ddf","text":"Defined in GovernanceVotePower ( Docs , Source ). function delegatesHistoryCleanup ( address _owner , uint256 _count ) external returns ( uint256 ); Delete delegates checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _owner address Vote power owner account address. _count uint256 Maximum number of checkpoints to delete. Returns Type Description [0] uint256 The number of deleted checkpoints.","title":"delegatesHistoryCleanup"},{"location":"apis/smart-contracts/GovernanceVotePower/#fn_getcleanupblocknumber_a72ec4b6","text":"Defined in GovernanceVotePower ( Docs , Source ). function getCleanupBlockNumber ( ) external view returns ( uint256 ); Get the current cleanup block number set with setCleanupBlockNumber . Returns Type Description [0] uint256 The currently set cleanup block number.","title":"getCleanupBlockNumber"},{"location":"apis/smart-contracts/GovernanceVotePower/#fn_getdelegateofat_3c028e9d","text":"Defined in GovernanceVotePower ( Docs , Source ). function getDelegateOfAt ( address _who , uint256 _blockNumber ) public view returns ( address ); Gets the address an account is delegating its governance vote power to, at a given block number. Parameters Type Description _who address The address being queried. _blockNumber uint256 The block number at which to fetch the address. Returns Type Description [0] address Address where _who was delegating its governance vote power at block _blockNumber .","title":"getDelegateOfAt"},{"location":"apis/smart-contracts/GovernanceVotePower/#fn_getdelegateofatnow_b3e871ee","text":"Defined in GovernanceVotePower ( Docs , Source ). function getDelegateOfAtNow ( address _who ) public view returns ( address ); Gets the address an account is delegating its governance vote power to, at the latest block number. Parameters Type Description _who address The address being queried. Returns Type Description [0] address Address where _who is currently delegating its governance vote power.","title":"getDelegateOfAtNow"},{"location":"apis/smart-contracts/GovernanceVotePower/#fn_getvotes_9ab24eb0","text":"Defined in GovernanceVotePower ( Docs , Source ). function getVotes ( address _who ) public view returns ( uint256 ); Gets the governance vote power of an address at the latest block, including all delegations made to it. Parameters Type Description _who address The address being queried. Returns Type Description [0] uint256 Governance vote power of account at the lastest block.","title":"getVotes"},{"location":"apis/smart-contracts/GovernanceVotePower/#fn_ownertoken_65371883","text":"Defined in IIGovernanceVotePower ( Docs , Source ). function ownerToken ( ) external view returns ( contract IVPToken ); Get the token that this governance vote power contract belongs to. Returns Type Description [0] contract IVPToken The IVPToken interface owning this contract.","title":"ownerToken"},{"location":"apis/smart-contracts/GovernanceVotePower/#fn_setcleanercontract_f6a494af","text":"Defined in GovernanceVotePower ( Docs , Source ). function setCleanerContract ( address _cleanerContract ) external ; Set the contract that is allowed to call history cleaning methods. This method can be called by the ownerToken only. Parameters Type Description _cleanerContract address Address of the cleanup contract. Usually this will be an instance of CleanupBlockNumberManager .","title":"setCleanerContract"},{"location":"apis/smart-contracts/GovernanceVotePower/#fn_setcleanupblocknumber_13de97f5","text":"Defined in GovernanceVotePower ( Docs , Source ). function setCleanupBlockNumber ( uint256 _blockNumber ) external ; Set the cleanup block number. Historic data for the blocks before cleanupBlockNumber can be erased. History before that block should never be used since it can be inconsistent. In particular, cleanup block number must be lower than the current vote power block. This method can be called by the ownerToken only. Parameters Type Description _blockNumber uint256 The new cleanup block number.","title":"setCleanupBlockNumber"},{"location":"apis/smart-contracts/GovernanceVotePower/#fn_undelegate_92ab89bb","text":"Defined in GovernanceVotePower ( Docs , Source ). function undelegate ( ) public ; Undelegates all governance vote power of msg.sender .","title":"undelegate"},{"location":"apis/smart-contracts/GovernanceVotePower/#fn_updateattokentransfer_eadb4362","text":"Defined in GovernanceVotePower ( Docs , Source ). function updateAtTokenTransfer ( address _from , address _to , uint256 , uint256 , uint256 _amount ) external ; Update governance vote power of all involved delegates after tokens are transferred. This function MUST be called after each governance token transfer for the delegates to reflect the correct balance. Parameters Type Description _from address Source address of the transfer. _to address Destination address of the transfer. `` uint256 `` uint256 _amount uint256 Amount being transferred.","title":"updateAtTokenTransfer"},{"location":"apis/smart-contracts/GovernanceVotePower/#fn_votepowerofat_92bfe6d8","text":"Defined in GovernanceVotePower ( Docs , Source ). function votePowerOfAt ( address _who , uint256 _blockNumber ) public view returns ( uint256 ); Gets the governance vote power of an address at a given block number, including all delegations made to it. Parameters Type Description _who address The address being queried. _blockNumber uint256 The block number at which to fetch the vote power. Returns Type Description [0] uint256 Governance vote power of _who at _blockNumber .","title":"votePowerOfAt"},{"location":"apis/smart-contracts/GovernanceVotePower/#modifiers","text":"","title":"Modifiers"},{"location":"apis/smart-contracts/GovernanceVotePower/#md_onlycleaner","text":"Defined in GovernanceVotePower ( Docs , Source ). modifier onlyCleaner () History cleaning methods can be called only from the cleaner address.","title":"onlyCleaner"},{"location":"apis/smart-contracts/GovernanceVotePower/#md_onlyownertoken","text":"Defined in GovernanceVotePower ( Docs , Source ). modifier onlyOwnerToken () All external methods in GovernanceVotePower can only be executed by the owner token.","title":"onlyOwnerToken"},{"location":"apis/smart-contracts/GovernanceVotePower/#variables","text":"","title":"Variables"},{"location":"apis/smart-contracts/GovernanceVotePower/#va_cleanercontract","text":"Defined in GovernanceVotePower ( Docs , Source ). address cleanerContract Address of the contract that is allowed to call methods for history cleaning. Set with setCleanerContract .","title":"cleanerContract"},{"location":"apis/smart-contracts/GovernanceVotePower/#va_ownertoken","text":"Defined in GovernanceVotePower ( Docs , Source ). contract IVPToken ownerToken The VPToken (or some other contract) that owns this GovernanceVotePower . All state changing methods may be called only from this address. This is because original msg.sender is typically sent in a parameter and we must make sure that it cannot be faked by directly calling GovernanceVotePower methods.","title":"ownerToken"},{"location":"apis/smart-contracts/Governed/","text":"Governed # Source | Inherits from GovernedBase Defines behaviors for governed contracts that must have a governor set at construction-time. Functions # cancelGovernanceCall # Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector. constructor # Defined in Governed ( Docs , Source ). constructor ( address _governance ) public ; Parameters Type Description _governance address Governance contract. Must not be zero. executeGovernanceCall # Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored). governance # Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address. switchToProductionMode # Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered .","title":"Governed"},{"location":"apis/smart-contracts/Governed/#ct_governed","text":"Source | Inherits from GovernedBase Defines behaviors for governed contracts that must have a governor set at construction-time.","title":"Governed"},{"location":"apis/smart-contracts/Governed/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/Governed/#fn_cancelgovernancecall_67fc4029","text":"Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector.","title":"cancelGovernanceCall"},{"location":"apis/smart-contracts/Governed/#fn_constructor_undefined","text":"Defined in Governed ( Docs , Source ). constructor ( address _governance ) public ; Parameters Type Description _governance address Governance contract. Must not be zero.","title":"constructor"},{"location":"apis/smart-contracts/Governed/#fn_executegovernancecall_5ff27079","text":"Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored).","title":"executeGovernanceCall"},{"location":"apis/smart-contracts/Governed/#fn_governance_5aa6e675","text":"Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address.","title":"governance"},{"location":"apis/smart-contracts/Governed/#fn_switchtoproductionmode_f5a98383","text":"Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered .","title":"switchToProductionMode"},{"location":"apis/smart-contracts/GovernedAndFlareDaemonized/","text":"GovernedAndFlareDaemonized # Source | Inherits from Governed Base class for contracts that are governed and triggered from the FlareDaemon . See Governed and IFlareDaemonize . Functions # cancelGovernanceCall # Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector. constructor # Defined in GovernedAndFlareDaemonized ( Docs , Source ). constructor ( address _governance , contract FlareDaemon _flareDaemon ) public ; constructor # Defined in Governed ( Docs , Source ). constructor ( address _governance ) public ; Parameters Type Description _governance address Governance contract. Must not be zero. executeGovernanceCall # Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored). governance # Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address. switchToProductionMode # Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered . Modifiers # onlyFlareDaemon # Defined in GovernedAndFlareDaemonized ( Docs , Source ). modifier onlyFlareDaemon () Only the flareDaemon can call this method. onlyGovernance # Defined in GovernedBase ( Docs , Source ). modifier onlyGovernance () onlyImmediateGovernance # Defined in GovernedBase ( Docs , Source ). modifier onlyImmediateGovernance () Variables # flareDaemon # Defined in GovernedAndFlareDaemonized ( Docs , Source ). contract FlareDaemon flareDaemon The FlareDaemon contract, set at construction time. governanceSettings # Defined in GovernedBase ( Docs , Source ). contract IGovernanceSettings governanceSettings Governance Settings. productionMode # Defined in GovernedBase ( Docs , Source ). bool productionMode When true, governance is enabled and cannot be disabled. See switchToProductionMode . timelockedCalls # Defined in GovernedBase ( Docs , Source ). mapping ( bytes4 => struct GovernedBase . TimelockedCall ) timelockedCalls List of pending timelocked governance calls.","title":"GovernedAndFlareDaemonized"},{"location":"apis/smart-contracts/GovernedAndFlareDaemonized/#ct_governedandflaredaemonized","text":"Source | Inherits from Governed Base class for contracts that are governed and triggered from the FlareDaemon . See Governed and IFlareDaemonize .","title":"GovernedAndFlareDaemonized"},{"location":"apis/smart-contracts/GovernedAndFlareDaemonized/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/GovernedAndFlareDaemonized/#fn_cancelgovernancecall_67fc4029","text":"Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector.","title":"cancelGovernanceCall"},{"location":"apis/smart-contracts/GovernedAndFlareDaemonized/#fn_constructor_undefined","text":"Defined in GovernedAndFlareDaemonized ( Docs , Source ). constructor ( address _governance , contract FlareDaemon _flareDaemon ) public ;","title":"constructor"},{"location":"apis/smart-contracts/GovernedAndFlareDaemonized/#fn_constructor_undefined","text":"Defined in Governed ( Docs , Source ). constructor ( address _governance ) public ; Parameters Type Description _governance address Governance contract. Must not be zero.","title":"constructor"},{"location":"apis/smart-contracts/GovernedAndFlareDaemonized/#fn_executegovernancecall_5ff27079","text":"Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored).","title":"executeGovernanceCall"},{"location":"apis/smart-contracts/GovernedAndFlareDaemonized/#fn_governance_5aa6e675","text":"Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address.","title":"governance"},{"location":"apis/smart-contracts/GovernedAndFlareDaemonized/#fn_switchtoproductionmode_f5a98383","text":"Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered .","title":"switchToProductionMode"},{"location":"apis/smart-contracts/GovernedAndFlareDaemonized/#modifiers","text":"","title":"Modifiers"},{"location":"apis/smart-contracts/GovernedAndFlareDaemonized/#md_onlyflaredaemon","text":"Defined in GovernedAndFlareDaemonized ( Docs , Source ). modifier onlyFlareDaemon () Only the flareDaemon can call this method.","title":"onlyFlareDaemon"},{"location":"apis/smart-contracts/GovernedAndFlareDaemonized/#md_onlygovernance","text":"Defined in GovernedBase ( Docs , Source ). modifier onlyGovernance ()","title":"onlyGovernance"},{"location":"apis/smart-contracts/GovernedAndFlareDaemonized/#md_onlyimmediategovernance","text":"Defined in GovernedBase ( Docs , Source ). modifier onlyImmediateGovernance ()","title":"onlyImmediateGovernance"},{"location":"apis/smart-contracts/GovernedAndFlareDaemonized/#variables","text":"","title":"Variables"},{"location":"apis/smart-contracts/GovernedAndFlareDaemonized/#va_flaredaemon","text":"Defined in GovernedAndFlareDaemonized ( Docs , Source ). contract FlareDaemon flareDaemon The FlareDaemon contract, set at construction time.","title":"flareDaemon"},{"location":"apis/smart-contracts/GovernedAndFlareDaemonized/#va_governancesettings","text":"Defined in GovernedBase ( Docs , Source ). contract IGovernanceSettings governanceSettings Governance Settings.","title":"governanceSettings"},{"location":"apis/smart-contracts/GovernedAndFlareDaemonized/#va_productionmode","text":"Defined in GovernedBase ( Docs , Source ). bool productionMode When true, governance is enabled and cannot be disabled. See switchToProductionMode .","title":"productionMode"},{"location":"apis/smart-contracts/GovernedAndFlareDaemonized/#va_timelockedcalls","text":"Defined in GovernedBase ( Docs , Source ). mapping ( bytes4 => struct GovernedBase . TimelockedCall ) timelockedCalls List of pending timelocked governance calls.","title":"timelockedCalls"},{"location":"apis/smart-contracts/GovernedAtGenesis/","text":"GovernedAtGenesis # Source | Inherits from GovernedBase Defines behaviors for governed contracts that have their governor set at genesis. This contract enforces a fixed governance address when the constructor is not executed on a contract (for instance when directly loaded to the genesis block). This is required to fix governance on a contract when the network starts, at such point where theoretically no accounts yet exist, and leaving it ungoverned could result in a race to claim governance by an unauthorized address. Functions # cancelGovernanceCall # Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector. constructor # Defined in GovernedAtGenesis ( Docs , Source ). constructor ( address _governance ) public ; executeGovernanceCall # Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored). governance # Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address. initialise # Defined in GovernedAtGenesis ( Docs , Source ). function initialise ( address _governance ) public pure ; Disallow initialise to be called. Parameters Type Description _governance address The governance address for initial claiming. switchToProductionMode # Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered .","title":"GovernedAtGenesis"},{"location":"apis/smart-contracts/GovernedAtGenesis/#ct_governedatgenesis","text":"Source | Inherits from GovernedBase Defines behaviors for governed contracts that have their governor set at genesis. This contract enforces a fixed governance address when the constructor is not executed on a contract (for instance when directly loaded to the genesis block). This is required to fix governance on a contract when the network starts, at such point where theoretically no accounts yet exist, and leaving it ungoverned could result in a race to claim governance by an unauthorized address.","title":"GovernedAtGenesis"},{"location":"apis/smart-contracts/GovernedAtGenesis/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/GovernedAtGenesis/#fn_cancelgovernancecall_67fc4029","text":"Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector.","title":"cancelGovernanceCall"},{"location":"apis/smart-contracts/GovernedAtGenesis/#fn_constructor_undefined","text":"Defined in GovernedAtGenesis ( Docs , Source ). constructor ( address _governance ) public ;","title":"constructor"},{"location":"apis/smart-contracts/GovernedAtGenesis/#fn_executegovernancecall_5ff27079","text":"Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored).","title":"executeGovernanceCall"},{"location":"apis/smart-contracts/GovernedAtGenesis/#fn_governance_5aa6e675","text":"Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address.","title":"governance"},{"location":"apis/smart-contracts/GovernedAtGenesis/#fn_initialise_9d6a890f","text":"Defined in GovernedAtGenesis ( Docs , Source ). function initialise ( address _governance ) public pure ; Disallow initialise to be called. Parameters Type Description _governance address The governance address for initial claiming.","title":"initialise"},{"location":"apis/smart-contracts/GovernedAtGenesis/#fn_switchtoproductionmode_f5a98383","text":"Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered .","title":"switchToProductionMode"},{"location":"apis/smart-contracts/GovernedBase/","text":"GovernedBase # Source Abstract base class that defines behaviors for governed contracts. This class is abstract so that specific behaviors can be defined for the constructor. Contracts should not be left ungoverned, but not all contract will have a constructor (for example those pre-defined in genesis). Events # GovernanceCallTimelocked # Defined in GovernedBase ( Docs , Source ). event GovernanceCallTimelocked ( bytes4 selector , uint256 allowedAfterTimestamp , bytes encodedCall ) Emitted when a new governance call has been recorded and is now waiting for the time lock to expire. GovernanceInitialised # Defined in GovernedBase ( Docs , Source ). event GovernanceInitialised ( address initialGovernance ) Emitted when the governance address is initialized. This address will be used until production mode is entered (see GovernedProductionModeEntered ). At that point the governance address is taken from GovernanceSettings . GovernedProductionModeEntered # Defined in GovernedBase ( Docs , Source ). event GovernedProductionModeEntered ( address governanceSettings ) Emitted when governance is enabled and the governance address cannot be changed anymore (only through a network fork). TimelockedGovernanceCallCanceled # Defined in GovernedBase ( Docs , Source ). event TimelockedGovernanceCallCanceled ( bytes4 selector , uint256 timestamp ) Emitted when a timelocked governance call is canceled before execution. TimelockedGovernanceCallExecuted # Defined in GovernedBase ( Docs , Source ). event TimelockedGovernanceCallExecuted ( bytes4 selector , uint256 timestamp ) Emitted when a timelocked governance call is executed. Functions # cancelGovernanceCall # Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector. executeGovernanceCall # Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored). governance # Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address. switchToProductionMode # Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered . Modifiers # onlyGovernance # Defined in GovernedBase ( Docs , Source ). modifier onlyGovernance () onlyImmediateGovernance # Defined in GovernedBase ( Docs , Source ). modifier onlyImmediateGovernance () Structures # TimelockedCall # Defined in GovernedBase ( Docs , Source ). struct TimelockedCall { uint256 allowedAfterTimestamp ; bytes encodedCall ; } Variables # governanceSettings # Defined in GovernedBase ( Docs , Source ). contract IGovernanceSettings governanceSettings Governance Settings. productionMode # Defined in GovernedBase ( Docs , Source ). bool productionMode When true, governance is enabled and cannot be disabled. See switchToProductionMode . timelockedCalls # Defined in GovernedBase ( Docs , Source ). mapping ( bytes4 => struct GovernedBase . TimelockedCall ) timelockedCalls List of pending timelocked governance calls.","title":"GovernedBase"},{"location":"apis/smart-contracts/GovernedBase/#ct_governedbase","text":"Source Abstract base class that defines behaviors for governed contracts. This class is abstract so that specific behaviors can be defined for the constructor. Contracts should not be left ungoverned, but not all contract will have a constructor (for example those pre-defined in genesis).","title":"GovernedBase"},{"location":"apis/smart-contracts/GovernedBase/#events","text":"","title":"Events"},{"location":"apis/smart-contracts/GovernedBase/#ev_governancecalltimelocked","text":"Defined in GovernedBase ( Docs , Source ). event GovernanceCallTimelocked ( bytes4 selector , uint256 allowedAfterTimestamp , bytes encodedCall ) Emitted when a new governance call has been recorded and is now waiting for the time lock to expire.","title":"GovernanceCallTimelocked"},{"location":"apis/smart-contracts/GovernedBase/#ev_governanceinitialised","text":"Defined in GovernedBase ( Docs , Source ). event GovernanceInitialised ( address initialGovernance ) Emitted when the governance address is initialized. This address will be used until production mode is entered (see GovernedProductionModeEntered ). At that point the governance address is taken from GovernanceSettings .","title":"GovernanceInitialised"},{"location":"apis/smart-contracts/GovernedBase/#ev_governedproductionmodeentered","text":"Defined in GovernedBase ( Docs , Source ). event GovernedProductionModeEntered ( address governanceSettings ) Emitted when governance is enabled and the governance address cannot be changed anymore (only through a network fork).","title":"GovernedProductionModeEntered"},{"location":"apis/smart-contracts/GovernedBase/#ev_timelockedgovernancecallcanceled","text":"Defined in GovernedBase ( Docs , Source ). event TimelockedGovernanceCallCanceled ( bytes4 selector , uint256 timestamp ) Emitted when a timelocked governance call is canceled before execution.","title":"TimelockedGovernanceCallCanceled"},{"location":"apis/smart-contracts/GovernedBase/#ev_timelockedgovernancecallexecuted","text":"Defined in GovernedBase ( Docs , Source ). event TimelockedGovernanceCallExecuted ( bytes4 selector , uint256 timestamp ) Emitted when a timelocked governance call is executed.","title":"TimelockedGovernanceCallExecuted"},{"location":"apis/smart-contracts/GovernedBase/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/GovernedBase/#fn_cancelgovernancecall_67fc4029","text":"Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector.","title":"cancelGovernanceCall"},{"location":"apis/smart-contracts/GovernedBase/#fn_executegovernancecall_5ff27079","text":"Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored).","title":"executeGovernanceCall"},{"location":"apis/smart-contracts/GovernedBase/#fn_governance_5aa6e675","text":"Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address.","title":"governance"},{"location":"apis/smart-contracts/GovernedBase/#fn_switchtoproductionmode_f5a98383","text":"Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered .","title":"switchToProductionMode"},{"location":"apis/smart-contracts/GovernedBase/#modifiers","text":"","title":"Modifiers"},{"location":"apis/smart-contracts/GovernedBase/#md_onlygovernance","text":"Defined in GovernedBase ( Docs , Source ). modifier onlyGovernance ()","title":"onlyGovernance"},{"location":"apis/smart-contracts/GovernedBase/#md_onlyimmediategovernance","text":"Defined in GovernedBase ( Docs , Source ). modifier onlyImmediateGovernance ()","title":"onlyImmediateGovernance"},{"location":"apis/smart-contracts/GovernedBase/#structures","text":"","title":"Structures"},{"location":"apis/smart-contracts/GovernedBase/#st_timelockedcall","text":"Defined in GovernedBase ( Docs , Source ). struct TimelockedCall { uint256 allowedAfterTimestamp ; bytes encodedCall ; }","title":"TimelockedCall"},{"location":"apis/smart-contracts/GovernedBase/#variables","text":"","title":"Variables"},{"location":"apis/smart-contracts/GovernedBase/#va_governancesettings","text":"Defined in GovernedBase ( Docs , Source ). contract IGovernanceSettings governanceSettings Governance Settings.","title":"governanceSettings"},{"location":"apis/smart-contracts/GovernedBase/#va_productionmode","text":"Defined in GovernedBase ( Docs , Source ). bool productionMode When true, governance is enabled and cannot be disabled. See switchToProductionMode .","title":"productionMode"},{"location":"apis/smart-contracts/GovernedBase/#va_timelockedcalls","text":"Defined in GovernedBase ( Docs , Source ). mapping ( bytes4 => struct GovernedBase . TimelockedCall ) timelockedCalls List of pending timelocked governance calls.","title":"timelockedCalls"},{"location":"apis/smart-contracts/IClaimSetupManager/","text":"IClaimSetupManager # Source Public interface for the ClaimSetupManager contract. Events # AllowedClaimRecipientsChanged # Defined in IClaimSetupManager ( Docs , Source ). event AllowedClaimRecipientsChanged ( address owner , address [] recipients ) ClaimExecutorFeeValueChanged # Defined in IClaimSetupManager ( Docs , Source ). event ClaimExecutorFeeValueChanged ( address executor , uint256 validFromRewardEpoch , uint256 feeValueWei ) ClaimExecutorsChanged # Defined in IClaimSetupManager ( Docs , Source ). event ClaimExecutorsChanged ( address owner , address [] executors ) DelegationAccountCreated # Defined in IClaimSetupManager ( Docs , Source ). event DelegationAccountCreated ( address owner , contract IDelegationAccount delegationAccount ) DelegationAccountUpdated # Defined in IClaimSetupManager ( Docs , Source ). event DelegationAccountUpdated ( address owner , contract IDelegationAccount delegationAccount , bool enabled ) ExecutorRegistered # Defined in IClaimSetupManager ( Docs , Source ). event ExecutorRegistered ( address executor ) ExecutorUnregistered # Defined in IClaimSetupManager ( Docs , Source ). event ExecutorUnregistered ( address executor , uint256 validFromRewardEpoch ) MaxFeeSet # Defined in IClaimSetupManager ( Docs , Source ). event MaxFeeSet ( uint256 maxFeeValueWei ) MinFeeSet # Defined in IClaimSetupManager ( Docs , Source ). event MinFeeSet ( uint256 minFeeValueWei ) RegisterExecutorFeeSet # Defined in IClaimSetupManager ( Docs , Source ). event RegisterExecutorFeeSet ( uint256 registerExecutorFeeValueWei ) SetExecutorsExcessAmountRefunded # Defined in IClaimSetupManager ( Docs , Source ). event SetExecutorsExcessAmountRefunded ( address owner , uint256 excessAmount ) Functions # accountToDelegationAccount # Defined in IClaimSetupManager ( Docs , Source ). function accountToDelegationAccount ( address _owner ) external view returns ( address ); Gets the PDA of an account. Parameters Type Description _owner address Account to query. Returns Type Description [0] address Address of its PDA or address(0) if it has not been created yet. allowedClaimRecipients # Defined in IClaimSetupManager ( Docs , Source ). function allowedClaimRecipients ( address _rewardOwner ) external view returns ( address []); Gets the addresses of recipients allowed to receive rewards on behalf of an account. Beside these, the owner of the rewards is always authorized. See setAllowedClaimRecipients . Parameters Type Description _rewardOwner address The account to query. Returns Type Description [0] address[] Addresses of all set authorized recipients. batchDelegate # Defined in IClaimSetupManager ( Docs , Source ). function batchDelegate ( address [] _delegatees , uint256 [] _bips ) external ; Undelegates all percentage delegations from the caller's PDA and then delegate to a list of accounts. See delegate . Parameters Type Description _delegatees address[] The addresses of the new recipients. _bips uint256[] The percentage of voting power to be delegated to each delegatee, expressed in basis points (1/100 of one percent). Total of all _bips values must be lower than 10000. claimExecutors # Defined in IClaimSetupManager ( Docs , Source ). function claimExecutors ( address _owner ) external view returns ( address []); Gets the addresses of executors authorized to claim for an account. See setClaimExecutors . Parameters Type Description _owner address The account to query. Returns Type Description [0] address[] Addresses of all set executors. delegate # Defined in IClaimSetupManager ( Docs , Source ). function delegate ( address _to , uint256 _bips ) external ; Delegates a percentage of the caller's PDA 's voting power to another address. Parameters Type Description _to address The address of the recipient. _bips uint256 The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: Every call resets the delegation value. A value of 0 revokes delegation. delegateGovernance # Defined in IClaimSetupManager ( Docs , Source ). function delegateGovernance ( address _to ) external ; Delegates all the governance vote power of the caller's PDA to another account. Parameters Type Description _to address Address of the recipient of the delegation. disableDelegationAccount # Defined in IClaimSetupManager ( Docs , Source ). function disableDelegationAccount ( ) external ; Disables the Personal Delegation Account (PDA). When using automatic claiming, all airdrops and FTSO rewards will be sent to the owner's account. Rewards accrued by the PDA will no longer be automatically claimed. Reverts if there is no PDA. enableDelegationAccount # Defined in IClaimSetupManager ( Docs , Source ). function enableDelegationAccount ( ) external returns ( contract IDelegationAccount ); Enables (or creates) a Personal Delegation Account (PDA). When using automatic claiming, all airdrops and FTSO rewards will be sent to the PDA, and any rewards accrued by the PDA will be claimed too. Returns Type Description [0] contract IDelegationAccount Address of the delegation account contract. getDelegationAccountData # Defined in IClaimSetupManager ( Docs , Source ). function getDelegationAccountData ( address _owner ) external view returns ( contract IDelegationAccount _delegationAccount , bool _enabled ); Gets PDA data for an account. Parameters Type Description _owner address Account to query. Returns Type Description _delegationAccount contract IDelegationAccount Account's PDA address or address(0) if it has not been created yet. _enabled bool Whether the PDA is enabled. getExecutorCurrentFeeValue # Defined in IClaimSetupManager ( Docs , Source ). function getExecutorCurrentFeeValue ( address _executor ) external view returns ( uint256 ); Returns the current fee of a registered executor. Reverts if the executor is not registered. Parameters Type Description _executor address The executor to query. Returns Type Description [0] uint256 Fee in wei. getExecutorFeeValue # Defined in IClaimSetupManager ( Docs , Source ). function getExecutorFeeValue ( address _executor , uint256 _rewardEpoch ) external view returns ( uint256 ); Returns the fee of an executor at a given reward epoch. Parameters Type Description _executor address The executor to query. _rewardEpoch uint256 Reward Epoch ID to query. Returns Type Description [0] uint256 Fee in wei at that reward epoch. getExecutorInfo # Defined in IClaimSetupManager ( Docs , Source ). function getExecutorInfo ( address _executor ) external view returns ( bool _registered , uint256 _currentFeeValue ); Returns information about an executor. Parameters Type Description _executor address The executor to query. Returns Type Description _registered bool Whether the executor is registered. _currentFeeValue uint256 Executor's current fee value, if registered. getExecutorScheduledFeeValueChanges # Defined in IClaimSetupManager ( Docs , Source ). function getExecutorScheduledFeeValueChanges ( address _executor ) external view returns ( uint256 [] _feeValue , uint256 [] _validFromEpoch , bool [] _fixed ); Returns the currently scheduled fee changes of an executor. Parameters Type Description _executor address Executor to query. Returns Type Description _feeValue uint256[] Array of scheduled fees. _validFromEpoch uint256[] Array of reward epochs ID where the scheduled fees will become effective. _fixed bool[] Array of booleans indicating if an scheduled fee change is fixed or it might still be changed. getRegisteredExecutors # Defined in IClaimSetupManager ( Docs , Source ). function getRegisteredExecutors ( uint256 _start , uint256 _end ) external view returns ( address [] _registeredExecutors , uint256 _totalLength ); Returns the list of executors registered through registerExecutor . Supports paging. Parameters Type Description _start uint256 First executor to return. _end uint256 Last executor to return. Returns Type Description _registeredExecutors address[] Addresses of the registered executors. _totalLength uint256 Total amount of executors. isClaimExecutor # Defined in IClaimSetupManager ( Docs , Source ). function isClaimExecutor ( address _owner , address _executor ) external view returns ( bool ); Returns whether an executor is authorized to claim on behalf of a reward owner. See setClaimExecutors . Parameters Type Description _owner address The reward owner to query. _executor address The executor to query. registerExecutor # Defined in IClaimSetupManager ( Docs , Source ). function registerExecutor ( uint256 _feeValue ) external payable returns ( uint256 ); Registers the caller as an executor and sets its initial fee value. If the executor was already registered, this method only updates the fee, which will take effect after feeValueUpdateOffset reward epochs have elapsed. Executor must pay a fee in order to register. See registerExecutorFeeValueWei . Parameters Type Description _feeValue uint256 Desired fee, in wei. Must be between minFeeValueWei and maxFeeValueWei . 0 means no fee. Returns Type Description [0] uint256 Reward epoch ID when the changes become effective. revokeDelegationAt # Defined in IClaimSetupManager ( Docs , Source ). function revokeDelegationAt ( address _who , uint256 _blockNumber ) external ; Revokes all delegation from the caller's PDA to a given account at a given block. Only affects the reads via votePowerOfAtCached() in the specified block. This method should be used only to prevent rogue delegate voting in the current voting block. To stop delegating use delegate with percentage of 0 or undelegateAll . Parameters Type Description _who address The account to revoke. _blockNumber uint256 Block number where the revoking will take place. Must be in the past. setAllowedClaimRecipients # Defined in IClaimSetupManager ( Docs , Source ). function setAllowedClaimRecipients ( address [] _recipients ) external ; Set the addresses of allowed recipients. The reward owner is always an allowed recipient. Parameters Type Description _recipients address[] The new allowed recipients. All old recipients will be deleted and replaced by these. setAutoClaiming # Defined in IClaimSetupManager ( Docs , Source ). function setAutoClaiming ( address [] _executors , bool _enableDelegationAccount ) external payable ; Sets the addresses of executors and optionally enables (creates) a Personal Delegation Account (PDA). If any of the executors is a registered executor, some fee needs to be paid. Parameters Type Description _executors address[] The new executors. All old executors will be deleted and replaced by these. _enableDelegationAccount bool Whether the PDA should be enabled. setClaimExecutors # Defined in IClaimSetupManager ( Docs , Source ). function setClaimExecutors ( address [] _executors ) external payable ; Sets the addresses of executors. If any of the executors is a registered executor, some fee needs to be paid. Parameters Type Description _executors address[] The new executors. All old executors will be deleted and replaced by these. transferExternalToken # Defined in IClaimSetupManager ( Docs , Source ). function transferExternalToken ( contract IERC20 _token , uint256 _amount ) external ; Allows the caller to transfer ERC-20 tokens from their PDA to the owner account. The main use case is to move ERC-20 tokes received by mistake (by an airdrop, for example) out of the PDA and into the main account, where they can be more easily managed. Reverts if the target token is the WNat contract: use method withdraw for that. Parameters Type Description _token contract IERC20 Target token contract address. _amount uint256 Amount of tokens to transfer. undelegateAll # Defined in IClaimSetupManager ( Docs , Source ). function undelegateAll ( ) external ; Removes all delegations from the caller's PDA . undelegateGovernance # Defined in IClaimSetupManager ( Docs , Source ). function undelegateGovernance ( ) external ; Undelegates all governance vote power currently delegated by the caller's PDA . unregisterExecutor # Defined in IClaimSetupManager ( Docs , Source ). function unregisterExecutor ( ) external returns ( uint256 ); Unregisters the caller as an executor. Returns Type Description [0] uint256 Reward epoch ID when the change becomes effective. updateExecutorFeeValue # Defined in IClaimSetupManager ( Docs , Source ). function updateExecutorFeeValue ( uint256 _feeValue ) external returns ( uint256 ); Sets the caller's executor fee. The caller must be an executor registered through registerExecutor . When called multiple times inside the same reward epoch, only the last value remains. Parameters Type Description _feeValue uint256 Desired fee, in wei. Must be between minFeeValueWei and maxFeeValueWei . 0 means no fee. Returns Type Description [0] uint256 Reward epoch ID when the changes become effective. withdraw # Defined in IClaimSetupManager ( Docs , Source ). function withdraw ( uint256 _amount ) external ; Allows the caller to transfer WNat wrapped tokens from their PDA to the owner account. Parameters Type Description _amount uint256 Amount of tokens to transfer, in wei.","title":"IClaimSetupManager"},{"location":"apis/smart-contracts/IClaimSetupManager/#ct_iclaimsetupmanager","text":"Source Public interface for the ClaimSetupManager contract.","title":"IClaimSetupManager"},{"location":"apis/smart-contracts/IClaimSetupManager/#events","text":"","title":"Events"},{"location":"apis/smart-contracts/IClaimSetupManager/#ev_allowedclaimrecipientschanged","text":"Defined in IClaimSetupManager ( Docs , Source ). event AllowedClaimRecipientsChanged ( address owner , address [] recipients )","title":"AllowedClaimRecipientsChanged"},{"location":"apis/smart-contracts/IClaimSetupManager/#ev_claimexecutorfeevaluechanged","text":"Defined in IClaimSetupManager ( Docs , Source ). event ClaimExecutorFeeValueChanged ( address executor , uint256 validFromRewardEpoch , uint256 feeValueWei )","title":"ClaimExecutorFeeValueChanged"},{"location":"apis/smart-contracts/IClaimSetupManager/#ev_claimexecutorschanged","text":"Defined in IClaimSetupManager ( Docs , Source ). event ClaimExecutorsChanged ( address owner , address [] executors )","title":"ClaimExecutorsChanged"},{"location":"apis/smart-contracts/IClaimSetupManager/#ev_delegationaccountcreated","text":"Defined in IClaimSetupManager ( Docs , Source ). event DelegationAccountCreated ( address owner , contract IDelegationAccount delegationAccount )","title":"DelegationAccountCreated"},{"location":"apis/smart-contracts/IClaimSetupManager/#ev_delegationaccountupdated","text":"Defined in IClaimSetupManager ( Docs , Source ). event DelegationAccountUpdated ( address owner , contract IDelegationAccount delegationAccount , bool enabled )","title":"DelegationAccountUpdated"},{"location":"apis/smart-contracts/IClaimSetupManager/#ev_executorregistered","text":"Defined in IClaimSetupManager ( Docs , Source ). event ExecutorRegistered ( address executor )","title":"ExecutorRegistered"},{"location":"apis/smart-contracts/IClaimSetupManager/#ev_executorunregistered","text":"Defined in IClaimSetupManager ( Docs , Source ). event ExecutorUnregistered ( address executor , uint256 validFromRewardEpoch )","title":"ExecutorUnregistered"},{"location":"apis/smart-contracts/IClaimSetupManager/#ev_maxfeeset","text":"Defined in IClaimSetupManager ( Docs , Source ). event MaxFeeSet ( uint256 maxFeeValueWei )","title":"MaxFeeSet"},{"location":"apis/smart-contracts/IClaimSetupManager/#ev_minfeeset","text":"Defined in IClaimSetupManager ( Docs , Source ). event MinFeeSet ( uint256 minFeeValueWei )","title":"MinFeeSet"},{"location":"apis/smart-contracts/IClaimSetupManager/#ev_registerexecutorfeeset","text":"Defined in IClaimSetupManager ( Docs , Source ). event RegisterExecutorFeeSet ( uint256 registerExecutorFeeValueWei )","title":"RegisterExecutorFeeSet"},{"location":"apis/smart-contracts/IClaimSetupManager/#ev_setexecutorsexcessamountrefunded","text":"Defined in IClaimSetupManager ( Docs , Source ). event SetExecutorsExcessAmountRefunded ( address owner , uint256 excessAmount )","title":"SetExecutorsExcessAmountRefunded"},{"location":"apis/smart-contracts/IClaimSetupManager/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IClaimSetupManager/#fn_accounttodelegationaccount_69ea2387","text":"Defined in IClaimSetupManager ( Docs , Source ). function accountToDelegationAccount ( address _owner ) external view returns ( address ); Gets the PDA of an account. Parameters Type Description _owner address Account to query. Returns Type Description [0] address Address of its PDA or address(0) if it has not been created yet.","title":"accountToDelegationAccount"},{"location":"apis/smart-contracts/IClaimSetupManager/#fn_allowedclaimrecipients_dfd14c34","text":"Defined in IClaimSetupManager ( Docs , Source ). function allowedClaimRecipients ( address _rewardOwner ) external view returns ( address []); Gets the addresses of recipients allowed to receive rewards on behalf of an account. Beside these, the owner of the rewards is always authorized. See setAllowedClaimRecipients . Parameters Type Description _rewardOwner address The account to query. Returns Type Description [0] address[] Addresses of all set authorized recipients.","title":"allowedClaimRecipients"},{"location":"apis/smart-contracts/IClaimSetupManager/#fn_batchdelegate_dc4fcda7","text":"Defined in IClaimSetupManager ( Docs , Source ). function batchDelegate ( address [] _delegatees , uint256 [] _bips ) external ; Undelegates all percentage delegations from the caller's PDA and then delegate to a list of accounts. See delegate . Parameters Type Description _delegatees address[] The addresses of the new recipients. _bips uint256[] The percentage of voting power to be delegated to each delegatee, expressed in basis points (1/100 of one percent). Total of all _bips values must be lower than 10000.","title":"batchDelegate"},{"location":"apis/smart-contracts/IClaimSetupManager/#fn_claimexecutors_3f317fe1","text":"Defined in IClaimSetupManager ( Docs , Source ). function claimExecutors ( address _owner ) external view returns ( address []); Gets the addresses of executors authorized to claim for an account. See setClaimExecutors . Parameters Type Description _owner address The account to query. Returns Type Description [0] address[] Addresses of all set executors.","title":"claimExecutors"},{"location":"apis/smart-contracts/IClaimSetupManager/#fn_delegate_026e402b","text":"Defined in IClaimSetupManager ( Docs , Source ). function delegate ( address _to , uint256 _bips ) external ; Delegates a percentage of the caller's PDA 's voting power to another address. Parameters Type Description _to address The address of the recipient. _bips uint256 The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: Every call resets the delegation value. A value of 0 revokes delegation.","title":"delegate"},{"location":"apis/smart-contracts/IClaimSetupManager/#fn_delegategovernance_7a68a508","text":"Defined in IClaimSetupManager ( Docs , Source ). function delegateGovernance ( address _to ) external ; Delegates all the governance vote power of the caller's PDA to another account. Parameters Type Description _to address Address of the recipient of the delegation.","title":"delegateGovernance"},{"location":"apis/smart-contracts/IClaimSetupManager/#fn_disabledelegationaccount_2394deb1","text":"Defined in IClaimSetupManager ( Docs , Source ). function disableDelegationAccount ( ) external ; Disables the Personal Delegation Account (PDA). When using automatic claiming, all airdrops and FTSO rewards will be sent to the owner's account. Rewards accrued by the PDA will no longer be automatically claimed. Reverts if there is no PDA.","title":"disableDelegationAccount"},{"location":"apis/smart-contracts/IClaimSetupManager/#fn_enabledelegationaccount_f0977215","text":"Defined in IClaimSetupManager ( Docs , Source ). function enableDelegationAccount ( ) external returns ( contract IDelegationAccount ); Enables (or creates) a Personal Delegation Account (PDA). When using automatic claiming, all airdrops and FTSO rewards will be sent to the PDA, and any rewards accrued by the PDA will be claimed too. Returns Type Description [0] contract IDelegationAccount Address of the delegation account contract.","title":"enableDelegationAccount"},{"location":"apis/smart-contracts/IClaimSetupManager/#fn_getdelegationaccountdata_17a1e3fc","text":"Defined in IClaimSetupManager ( Docs , Source ). function getDelegationAccountData ( address _owner ) external view returns ( contract IDelegationAccount _delegationAccount , bool _enabled ); Gets PDA data for an account. Parameters Type Description _owner address Account to query. Returns Type Description _delegationAccount contract IDelegationAccount Account's PDA address or address(0) if it has not been created yet. _enabled bool Whether the PDA is enabled.","title":"getDelegationAccountData"},{"location":"apis/smart-contracts/IClaimSetupManager/#fn_getexecutorcurrentfeevalue_e25547f8","text":"Defined in IClaimSetupManager ( Docs , Source ). function getExecutorCurrentFeeValue ( address _executor ) external view returns ( uint256 ); Returns the current fee of a registered executor. Reverts if the executor is not registered. Parameters Type Description _executor address The executor to query. Returns Type Description [0] uint256 Fee in wei.","title":"getExecutorCurrentFeeValue"},{"location":"apis/smart-contracts/IClaimSetupManager/#fn_getexecutorfeevalue_3f8f784c","text":"Defined in IClaimSetupManager ( Docs , Source ). function getExecutorFeeValue ( address _executor , uint256 _rewardEpoch ) external view returns ( uint256 ); Returns the fee of an executor at a given reward epoch. Parameters Type Description _executor address The executor to query. _rewardEpoch uint256 Reward Epoch ID to query. Returns Type Description [0] uint256 Fee in wei at that reward epoch.","title":"getExecutorFeeValue"},{"location":"apis/smart-contracts/IClaimSetupManager/#fn_getexecutorinfo_8e28b923","text":"Defined in IClaimSetupManager ( Docs , Source ). function getExecutorInfo ( address _executor ) external view returns ( bool _registered , uint256 _currentFeeValue ); Returns information about an executor. Parameters Type Description _executor address The executor to query. Returns Type Description _registered bool Whether the executor is registered. _currentFeeValue uint256 Executor's current fee value, if registered.","title":"getExecutorInfo"},{"location":"apis/smart-contracts/IClaimSetupManager/#fn_getexecutorscheduledfeevaluechanges_950b028c","text":"Defined in IClaimSetupManager ( Docs , Source ). function getExecutorScheduledFeeValueChanges ( address _executor ) external view returns ( uint256 [] _feeValue , uint256 [] _validFromEpoch , bool [] _fixed ); Returns the currently scheduled fee changes of an executor. Parameters Type Description _executor address Executor to query. Returns Type Description _feeValue uint256[] Array of scheduled fees. _validFromEpoch uint256[] Array of reward epochs ID where the scheduled fees will become effective. _fixed bool[] Array of booleans indicating if an scheduled fee change is fixed or it might still be changed.","title":"getExecutorScheduledFeeValueChanges"},{"location":"apis/smart-contracts/IClaimSetupManager/#fn_getregisteredexecutors_6e927e61","text":"Defined in IClaimSetupManager ( Docs , Source ). function getRegisteredExecutors ( uint256 _start , uint256 _end ) external view returns ( address [] _registeredExecutors , uint256 _totalLength ); Returns the list of executors registered through registerExecutor . Supports paging. Parameters Type Description _start uint256 First executor to return. _end uint256 Last executor to return. Returns Type Description _registeredExecutors address[] Addresses of the registered executors. _totalLength uint256 Total amount of executors.","title":"getRegisteredExecutors"},{"location":"apis/smart-contracts/IClaimSetupManager/#fn_isclaimexecutor_87962abe","text":"Defined in IClaimSetupManager ( Docs , Source ). function isClaimExecutor ( address _owner , address _executor ) external view returns ( bool ); Returns whether an executor is authorized to claim on behalf of a reward owner. See setClaimExecutors . Parameters Type Description _owner address The reward owner to query. _executor address The executor to query.","title":"isClaimExecutor"},{"location":"apis/smart-contracts/IClaimSetupManager/#fn_registerexecutor_ccce7e86","text":"Defined in IClaimSetupManager ( Docs , Source ). function registerExecutor ( uint256 _feeValue ) external payable returns ( uint256 ); Registers the caller as an executor and sets its initial fee value. If the executor was already registered, this method only updates the fee, which will take effect after feeValueUpdateOffset reward epochs have elapsed. Executor must pay a fee in order to register. See registerExecutorFeeValueWei . Parameters Type Description _feeValue uint256 Desired fee, in wei. Must be between minFeeValueWei and maxFeeValueWei . 0 means no fee. Returns Type Description [0] uint256 Reward epoch ID when the changes become effective.","title":"registerExecutor"},{"location":"apis/smart-contracts/IClaimSetupManager/#fn_revokedelegationat_bbd6fbf8","text":"Defined in IClaimSetupManager ( Docs , Source ). function revokeDelegationAt ( address _who , uint256 _blockNumber ) external ; Revokes all delegation from the caller's PDA to a given account at a given block. Only affects the reads via votePowerOfAtCached() in the specified block. This method should be used only to prevent rogue delegate voting in the current voting block. To stop delegating use delegate with percentage of 0 or undelegateAll . Parameters Type Description _who address The account to revoke. _blockNumber uint256 Block number where the revoking will take place. Must be in the past.","title":"revokeDelegationAt"},{"location":"apis/smart-contracts/IClaimSetupManager/#fn_setallowedclaimrecipients_d2a4ac61","text":"Defined in IClaimSetupManager ( Docs , Source ). function setAllowedClaimRecipients ( address [] _recipients ) external ; Set the addresses of allowed recipients. The reward owner is always an allowed recipient. Parameters Type Description _recipients address[] The new allowed recipients. All old recipients will be deleted and replaced by these.","title":"setAllowedClaimRecipients"},{"location":"apis/smart-contracts/IClaimSetupManager/#fn_setautoclaiming_e72dcdbb","text":"Defined in IClaimSetupManager ( Docs , Source ). function setAutoClaiming ( address [] _executors , bool _enableDelegationAccount ) external payable ; Sets the addresses of executors and optionally enables (creates) a Personal Delegation Account (PDA). If any of the executors is a registered executor, some fee needs to be paid. Parameters Type Description _executors address[] The new executors. All old executors will be deleted and replaced by these. _enableDelegationAccount bool Whether the PDA should be enabled.","title":"setAutoClaiming"},{"location":"apis/smart-contracts/IClaimSetupManager/#fn_setclaimexecutors_9119c494","text":"Defined in IClaimSetupManager ( Docs , Source ). function setClaimExecutors ( address [] _executors ) external payable ; Sets the addresses of executors. If any of the executors is a registered executor, some fee needs to be paid. Parameters Type Description _executors address[] The new executors. All old executors will be deleted and replaced by these.","title":"setClaimExecutors"},{"location":"apis/smart-contracts/IClaimSetupManager/#fn_transferexternaltoken_489a8a47","text":"Defined in IClaimSetupManager ( Docs , Source ). function transferExternalToken ( contract IERC20 _token , uint256 _amount ) external ; Allows the caller to transfer ERC-20 tokens from their PDA to the owner account. The main use case is to move ERC-20 tokes received by mistake (by an airdrop, for example) out of the PDA and into the main account, where they can be more easily managed. Reverts if the target token is the WNat contract: use method withdraw for that. Parameters Type Description _token contract IERC20 Target token contract address. _amount uint256 Amount of tokens to transfer.","title":"transferExternalToken"},{"location":"apis/smart-contracts/IClaimSetupManager/#fn_undelegateall_b302f393","text":"Defined in IClaimSetupManager ( Docs , Source ). function undelegateAll ( ) external ; Removes all delegations from the caller's PDA .","title":"undelegateAll"},{"location":"apis/smart-contracts/IClaimSetupManager/#fn_undelegategovernance_87a2a0dc","text":"Defined in IClaimSetupManager ( Docs , Source ). function undelegateGovernance ( ) external ; Undelegates all governance vote power currently delegated by the caller's PDA .","title":"undelegateGovernance"},{"location":"apis/smart-contracts/IClaimSetupManager/#fn_unregisterexecutor_868a660f","text":"Defined in IClaimSetupManager ( Docs , Source ). function unregisterExecutor ( ) external returns ( uint256 ); Unregisters the caller as an executor. Returns Type Description [0] uint256 Reward epoch ID when the change becomes effective.","title":"unregisterExecutor"},{"location":"apis/smart-contracts/IClaimSetupManager/#fn_updateexecutorfeevalue_831f16af","text":"Defined in IClaimSetupManager ( Docs , Source ). function updateExecutorFeeValue ( uint256 _feeValue ) external returns ( uint256 ); Sets the caller's executor fee. The caller must be an executor registered through registerExecutor . When called multiple times inside the same reward epoch, only the last value remains. Parameters Type Description _feeValue uint256 Desired fee, in wei. Must be between minFeeValueWei and maxFeeValueWei . 0 means no fee. Returns Type Description [0] uint256 Reward epoch ID when the changes become effective.","title":"updateExecutorFeeValue"},{"location":"apis/smart-contracts/IClaimSetupManager/#fn_withdraw_2e1a7d4d","text":"Defined in IClaimSetupManager ( Docs , Source ). function withdraw ( uint256 _amount ) external ; Allows the caller to transfer WNat wrapped tokens from their PDA to the owner account. Parameters Type Description _amount uint256 Amount of tokens to transfer, in wei.","title":"withdraw"},{"location":"apis/smart-contracts/IFlareContractRegistry/","text":"IFlareContractRegistry # Source Interface for the FlareContractRegistry . Entry point for all external dapps that need the latest contract addresses deployed by Flare. Functions # getAllContracts # Defined in IFlareContractRegistry ( Docs , Source ). function getAllContracts ( ) external view returns ( string [] _names , address [] _addresses ); Returns all contract names and their corresponding addresses. Returns Type Description _names string[] Array of contract names. _addresses address[] Array of corresponding contract addresses. getContractAddressByHash # Defined in IFlareContractRegistry ( Docs , Source ). function getContractAddressByHash ( bytes32 _nameHash ) external view returns ( address ); Returns the address of a given contract hash. Parameters Type Description _nameHash bytes32 Hash of the contract name as: keccak256(abi.encode(name)) . Returns Type Description [0] address Address of the contract, or address(0) if not found. getContractAddressByName # Defined in IFlareContractRegistry ( Docs , Source ). function getContractAddressByName ( string _name ) external view returns ( address ); Returns the address of a given contract name. Parameters Type Description _name string Name of the contract. Returns Type Description [0] address Address of the contract, or address(0) if not found. getContractAddressesByHash # Defined in IFlareContractRegistry ( Docs , Source ). function getContractAddressesByHash ( bytes32 [] _nameHashes ) external view returns ( address []); Returns the addresses of a list of contract hashes. Parameters Type Description _nameHashes bytes32[] Array of contract name hashes as: keccak256(abi.encode(name)) . Returns Type Description [0] address[] Array of addresses of the contracts. Any of them might be address(0) if not found. getContractAddressesByName # Defined in IFlareContractRegistry ( Docs , Source ). function getContractAddressesByName ( string [] _names ) external view returns ( address []); Returns the addresses of a list of contract names. Parameters Type Description _names string[] Array of contract names. Returns Type Description [0] address[] Array of addresses of the contracts. Any of them might be address(0) if not found.","title":"IFlareContractRegistry"},{"location":"apis/smart-contracts/IFlareContractRegistry/#ct_iflarecontractregistry","text":"Source Interface for the FlareContractRegistry . Entry point for all external dapps that need the latest contract addresses deployed by Flare.","title":"IFlareContractRegistry"},{"location":"apis/smart-contracts/IFlareContractRegistry/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IFlareContractRegistry/#fn_getallcontracts_18d3ce96","text":"Defined in IFlareContractRegistry ( Docs , Source ). function getAllContracts ( ) external view returns ( string [] _names , address [] _addresses ); Returns all contract names and their corresponding addresses. Returns Type Description _names string[] Array of contract names. _addresses address[] Array of corresponding contract addresses.","title":"getAllContracts"},{"location":"apis/smart-contracts/IFlareContractRegistry/#fn_getcontractaddressbyhash_159354a2","text":"Defined in IFlareContractRegistry ( Docs , Source ). function getContractAddressByHash ( bytes32 _nameHash ) external view returns ( address ); Returns the address of a given contract hash. Parameters Type Description _nameHash bytes32 Hash of the contract name as: keccak256(abi.encode(name)) . Returns Type Description [0] address Address of the contract, or address(0) if not found.","title":"getContractAddressByHash"},{"location":"apis/smart-contracts/IFlareContractRegistry/#fn_getcontractaddressbyname_82760fca","text":"Defined in IFlareContractRegistry ( Docs , Source ). function getContractAddressByName ( string _name ) external view returns ( address ); Returns the address of a given contract name. Parameters Type Description _name string Name of the contract. Returns Type Description [0] address Address of the contract, or address(0) if not found.","title":"getContractAddressByName"},{"location":"apis/smart-contracts/IFlareContractRegistry/#fn_getcontractaddressesbyhash_5e11e2d1","text":"Defined in IFlareContractRegistry ( Docs , Source ). function getContractAddressesByHash ( bytes32 [] _nameHashes ) external view returns ( address []); Returns the addresses of a list of contract hashes. Parameters Type Description _nameHashes bytes32[] Array of contract name hashes as: keccak256(abi.encode(name)) . Returns Type Description [0] address[] Array of addresses of the contracts. Any of them might be address(0) if not found.","title":"getContractAddressesByHash"},{"location":"apis/smart-contracts/IFlareContractRegistry/#fn_getcontractaddressesbyname_76d2b1af","text":"Defined in IFlareContractRegistry ( Docs , Source ). function getContractAddressesByName ( string [] _names ) external view returns ( address []); Returns the addresses of a list of contract names. Parameters Type Description _names string[] Array of contract names. Returns Type Description [0] address[] Array of addresses of the contracts. Any of them might be address(0) if not found.","title":"getContractAddressesByName"},{"location":"apis/smart-contracts/IFlareDaemonize/","text":"IFlareDaemonize # Source Interface for contracts that receive triggers from the FlareDaemon contract. Functions # daemonize # Defined in IFlareDaemonize ( Docs , Source ). function daemonize ( ) external returns ( bool ); Implement this function to receive a trigger from the FlareDaemon . The trigger method is called by the validator right at the end of block state transition. Returns Type Description [0] bool bool Whether the contract is still active after the call. Currently unused. getContractName # Defined in IFlareDaemonize ( Docs , Source ). function getContractName ( ) external view returns ( string ); Implement this function to allow updating daemonized contracts through the AddressUpdater . Returns Type Description [0] string string Contract name. switchToFallbackMode # Defined in IFlareDaemonize ( Docs , Source ). function switchToFallbackMode ( ) external returns ( bool ); This function will be called after an error is caught in daemonize . It will switch the contract to a simpler fallback mode, which hopefully works when full mode doesn't. Not every contract needs to support fallback mode ( FtsoManager does), so this method may be empty. Switching back to normal mode is left to the contract (typically a governed method call). This function may be called due to low-gas error, so it shouldn't use more than ~30.000 gas. Returns Type Description [0] bool True if switched to fallback mode, false if already in fallback mode or if fallback mode is not supported.","title":"IFlareDaemonize"},{"location":"apis/smart-contracts/IFlareDaemonize/#ct_iflaredaemonize","text":"Source Interface for contracts that receive triggers from the FlareDaemon contract.","title":"IFlareDaemonize"},{"location":"apis/smart-contracts/IFlareDaemonize/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IFlareDaemonize/#fn_daemonize_6d0e8c34","text":"Defined in IFlareDaemonize ( Docs , Source ). function daemonize ( ) external returns ( bool ); Implement this function to receive a trigger from the FlareDaemon . The trigger method is called by the validator right at the end of block state transition. Returns Type Description [0] bool bool Whether the contract is still active after the call. Currently unused.","title":"daemonize"},{"location":"apis/smart-contracts/IFlareDaemonize/#fn_getcontractname_f5f5ba72","text":"Defined in IFlareDaemonize ( Docs , Source ). function getContractName ( ) external view returns ( string ); Implement this function to allow updating daemonized contracts through the AddressUpdater . Returns Type Description [0] string string Contract name.","title":"getContractName"},{"location":"apis/smart-contracts/IFlareDaemonize/#fn_switchtofallbackmode_e22fdece","text":"Defined in IFlareDaemonize ( Docs , Source ). function switchToFallbackMode ( ) external returns ( bool ); This function will be called after an error is caught in daemonize . It will switch the contract to a simpler fallback mode, which hopefully works when full mode doesn't. Not every contract needs to support fallback mode ( FtsoManager does), so this method may be empty. Switching back to normal mode is left to the contract (typically a governed method call). This function may be called due to low-gas error, so it shouldn't use more than ~30.000 gas. Returns Type Description [0] bool True if switched to fallback mode, false if already in fallback mode or if fallback mode is not supported.","title":"switchToFallbackMode"},{"location":"apis/smart-contracts/IFtso/","text":"IFtso # Source Interface for each of the FTSO contracts that handles an asset. Read the FTSO documentation page for general information about the FTSO system. Enums # PriceFinalizationType # Defined in IFtso ( Docs , Source ). enum PriceFinalizationType { NOT_FINALIZED , WEIGHTED_MEDIAN , TRUSTED_ADDRESSES , PREVIOUS_PRICE_COPIED , TRUSTED_ADDRESSES_EXCEPTION , PREVIOUS_PRICE_COPIED_EXCEPTION } How did a price epoch finalize. NOT_FINALIZED : The epoch has not been finalized yet. This is the initial state. WEIGHTED_MEDIAN : The median was used to calculate the final price. This is the most common state in normal operation. TRUSTED_ADDRESSES : Due to low turnout, the final price was calculated using only the median of trusted addresses. PREVIOUS_PRICE_COPIED : Due to low turnout and absence of votes from trusted addresses, the final price was copied from the previous epoch. TRUSTED_ADDRESSES_EXCEPTION : Due to an exception, the final price was calculated using only the median of trusted addresses. PREVIOUS_PRICE_COPIED_EXCEPTION : Due to an exception, the final price was copied from the previous epoch. Events # LowTurnout # Defined in IFtso ( Docs , Source ). event LowTurnout ( uint256 epochId , uint256 natTurnout , uint256 lowNatTurnoutThresholdBIPS , uint256 timestamp ) Not enough votes were received for this asset during a price epoch that has just ended. Parameters Type Description epochId uint256 The ID of the epoch. natTurnout uint256 Total received vote power, as a percentage of the circulating supply in BIPS. lowNatTurnoutThresholdBIPS uint256 Minimum required vote power, as a percentage of the circulating supply in BIPS. The fact that this number is higher than natTurnout is what triggered this event. timestamp uint256 Timestamp of the block where the price epoch ended. PriceEpochInitializedOnFtso # Defined in IFtso ( Docs , Source ). event PriceEpochInitializedOnFtso ( uint256 epochId , uint256 endTime , uint256 timestamp ) All necessary parameters have been set for an epoch and prices can start being revealed . Note that prices can already be submitted immediately after the previous price epoch submit end time is over. This event is not emitted in fallback mode (see getPriceEpochData ). Parameters Type Description epochId uint256 The ID of the epoch that has just started. endTime uint256 Deadline to submit prices, in seconds since UNIX epoch. timestamp uint256 Current on-chain timestamp. PriceFinalized # Defined in IFtso ( Docs , Source ). event PriceFinalized ( uint256 epochId , uint256 price , bool rewardedFtso , uint256 lowIQRRewardPrice , uint256 highIQRRewardPrice , uint256 lowElasticBandRewardPrice , uint256 highElasticBandRewardPrice , enum IFtso . PriceFinalizationType finalizationType , uint256 timestamp ) An epoch has ended and the asset price is available. Parameters Type Description epochId uint256 The ID of the epoch that has just ended. price uint256 The asset's price for that epoch. rewardedFtso bool Whether the next 4 parameters contain data. lowIQRRewardPrice uint256 Lowest price in the primary (inter-quartile) reward band. highIQRRewardPrice uint256 Highest price in the primary (inter-quartile) reward band. lowElasticBandRewardPrice uint256 Lowest price in the secondary (elastic) reward band. highElasticBandRewardPrice uint256 Highest price in the secondary (elastic) reward band. finalizationType enum IFtso.PriceFinalizationType Reason for the finalization of the epoch. timestamp uint256 Timestamp of the block where the price has been finalized. PriceRevealed # Defined in IFtso ( Docs , Source ). event PriceRevealed ( address voter , uint256 epochId , uint256 price , uint256 timestamp , uint256 votePowerNat , uint256 votePowerAsset ) A voter has revealed its price. Parameters Type Description voter address The voter. epochId uint256 The ID of the epoch for which the price has been revealed. price uint256 The revealed price. timestamp uint256 Timestamp of the block where the reveal happened. votePowerNat uint256 Vote power of the voter in this epoch. This includes the vote power derived from its WNat holdings and the delegations. votePowerAsset uint256 Unused . Functions # active # Defined in IFtso ( Docs , Source ). function active ( ) external view returns ( bool ); Returns whether FTSO is active or not. getCurrentEpochId # Defined in IFtso ( Docs , Source ). function getCurrentEpochId ( ) external view returns ( uint256 ); Returns the current epoch ID. Returns Type Description [0] uint256 Currently running epoch ID. IDs are consecutive numbers starting from zero. getCurrentPrice # Defined in IFtso ( Docs , Source ). function getCurrentPrice ( ) external view returns ( uint256 _price , uint256 _timestamp ); Returns the current asset price. Returns Type Description _price uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Time when price was updated for the last time, in seconds from UNIX epoch. getCurrentPriceDetails # Defined in IFtso ( Docs , Source ). function getCurrentPriceDetails ( ) external view returns ( uint256 _price , uint256 _priceTimestamp , enum IFtso . PriceFinalizationType _priceFinalizationType , uint256 _lastPriceEpochFinalizationTimestamp , enum IFtso . PriceFinalizationType _lastPriceEpochFinalizationType ); Returns asset's current price details. All timestamps are in seconds from UNIX epoch. Returns Type Description _price uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _priceTimestamp uint256 Time when price was updated for the last time. _priceFinalizationType enum IFtso.PriceFinalizationType Finalization type when price was updated for the last time. _lastPriceEpochFinalizationTimestamp uint256 Time when last price epoch was finalized. _lastPriceEpochFinalizationType enum IFtso.PriceFinalizationType Finalization type of last finalized price epoch. getCurrentPriceFromTrustedProviders # Defined in IFtso ( Docs , Source ). function getCurrentPriceFromTrustedProviders ( ) external view returns ( uint256 _price , uint256 _timestamp ); Returns current asset price calculated only using input from trusted providers. Returns Type Description _price uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Time when price was updated for the last time, in seconds from UNIX epoch. getCurrentPriceWithDecimals # Defined in IFtso ( Docs , Source ). function getCurrentPriceWithDecimals ( ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Returns current asset price and number of decimals. Returns Type Description _price uint256 Price in USD multiplied by 10^ _assetPriceUsdDecimals . _timestamp uint256 Time when price was updated for the last time, in seconds from UNIX epoch. _assetPriceUsdDecimals uint256 Number of decimals used to return the USD price. getCurrentPriceWithDecimalsFromTrustedProviders # Defined in IFtso ( Docs , Source ). function getCurrentPriceWithDecimalsFromTrustedProviders ( ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Returns current asset price calculated only using input from trusted providers and number of decimals. Returns Type Description _price uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Time when price was updated for the last time, in seconds from UNIX epoch. _assetPriceUsdDecimals uint256 Number of decimals used to return the USD price. getCurrentRandom # Defined in IFtso ( Docs , Source ). function getCurrentRandom ( ) external view returns ( uint256 ); Returns the random number for the previous price epoch, obtained from the random numbers provided by all data providers along with their data submissions. getEpochId # Defined in IFtso ( Docs , Source ). function getEpochId ( uint256 _timestamp ) external view returns ( uint256 ); Returns the ID of the epoch that was opened for price submission at the specified timestamp. Parameters Type Description _timestamp uint256 Queried timestamp in seconds from UNIX epoch. Returns Type Description [0] uint256 Epoch ID corresponding to that timestamp. IDs are consecutive numbers starting from zero. getEpochPrice # Defined in IFtso ( Docs , Source ). function getEpochPrice ( uint256 _epochId ) external view returns ( uint256 ); Returns agreed asset price in the specified epoch. Parameters Type Description _epochId uint256 ID of the epoch. Only the last 200 epochs can be queried. Out-of-bounds queries revert. Returns Type Description [0] uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . getEpochPriceForVoter # Defined in IFtso ( Docs , Source ). function getEpochPriceForVoter ( uint256 _epochId , address _voter ) external view returns ( uint256 ); Returns asset price submitted by a voter in the specified epoch. Parameters Type Description _epochId uint256 ID of the epoch being queried. Only the last 200 epochs can be queried. Out-of-bounds queries revert. _voter address Address of the voter being queried. Returns Type Description [0] uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . getPriceEpochConfiguration # Defined in IFtso ( Docs , Source ). function getPriceEpochConfiguration ( ) external view returns ( uint256 _firstEpochStartTs , uint256 _submitPeriodSeconds , uint256 _revealPeriodSeconds ); Returns current epoch's configuration. Returns Type Description _firstEpochStartTs uint256 First epoch start timestamp in seconds from UNIX epoch. _submitPeriodSeconds uint256 Submit period in seconds. _revealPeriodSeconds uint256 Reveal period in seconds. getPriceEpochData # Defined in IFtso ( Docs , Source ). function getPriceEpochData ( ) external view returns ( uint256 _epochId , uint256 _epochSubmitEndTime , uint256 _epochRevealEndTime , uint256 _votePowerBlock , bool _fallbackMode ); Returns current epoch data. Intervals are open on the right: End times are not included. Returns Type Description _epochId uint256 Current epoch ID. _epochSubmitEndTime uint256 End time of the price submission window in seconds from UNIX epoch. _epochRevealEndTime uint256 End time of the price reveal window in seconds from UNIX epoch. _votePowerBlock uint256 Vote power block for the current epoch. _fallbackMode bool Whether the current epoch is in fallback mode. Only votes from trusted addresses are used in this mode. getRandom # Defined in IFtso ( Docs , Source ). function getRandom ( uint256 _epochId ) external view returns ( uint256 ); Returns the random number used in a specific past epoch, obtained from the random numbers provided by all data providers along with their data submissions. Parameters Type Description _epochId uint256 ID of the queried epoch. Current epoch cannot be queried, and the previous epoch is constantly updated as data providers reveal their prices and random numbers. Only the last 50 epochs can be queried and there is no bounds checking for this parameter. Out-of-bounds queries return undefined values. Returns Type Description [0] uint256 The random number used in that epoch. symbol # Defined in IFtso ( Docs , Source ). function symbol ( ) external view returns ( string ); Returns the FTSO symbol .","title":"IFtso"},{"location":"apis/smart-contracts/IFtso/#ct_iftso","text":"Source Interface for each of the FTSO contracts that handles an asset. Read the FTSO documentation page for general information about the FTSO system.","title":"IFtso"},{"location":"apis/smart-contracts/IFtso/#enums","text":"","title":"Enums"},{"location":"apis/smart-contracts/IFtso/#en_pricefinalizationtype","text":"Defined in IFtso ( Docs , Source ). enum PriceFinalizationType { NOT_FINALIZED , WEIGHTED_MEDIAN , TRUSTED_ADDRESSES , PREVIOUS_PRICE_COPIED , TRUSTED_ADDRESSES_EXCEPTION , PREVIOUS_PRICE_COPIED_EXCEPTION } How did a price epoch finalize. NOT_FINALIZED : The epoch has not been finalized yet. This is the initial state. WEIGHTED_MEDIAN : The median was used to calculate the final price. This is the most common state in normal operation. TRUSTED_ADDRESSES : Due to low turnout, the final price was calculated using only the median of trusted addresses. PREVIOUS_PRICE_COPIED : Due to low turnout and absence of votes from trusted addresses, the final price was copied from the previous epoch. TRUSTED_ADDRESSES_EXCEPTION : Due to an exception, the final price was calculated using only the median of trusted addresses. PREVIOUS_PRICE_COPIED_EXCEPTION : Due to an exception, the final price was copied from the previous epoch.","title":"PriceFinalizationType"},{"location":"apis/smart-contracts/IFtso/#events","text":"","title":"Events"},{"location":"apis/smart-contracts/IFtso/#ev_lowturnout","text":"Defined in IFtso ( Docs , Source ). event LowTurnout ( uint256 epochId , uint256 natTurnout , uint256 lowNatTurnoutThresholdBIPS , uint256 timestamp ) Not enough votes were received for this asset during a price epoch that has just ended. Parameters Type Description epochId uint256 The ID of the epoch. natTurnout uint256 Total received vote power, as a percentage of the circulating supply in BIPS. lowNatTurnoutThresholdBIPS uint256 Minimum required vote power, as a percentage of the circulating supply in BIPS. The fact that this number is higher than natTurnout is what triggered this event. timestamp uint256 Timestamp of the block where the price epoch ended.","title":"LowTurnout"},{"location":"apis/smart-contracts/IFtso/#ev_priceepochinitializedonftso","text":"Defined in IFtso ( Docs , Source ). event PriceEpochInitializedOnFtso ( uint256 epochId , uint256 endTime , uint256 timestamp ) All necessary parameters have been set for an epoch and prices can start being revealed . Note that prices can already be submitted immediately after the previous price epoch submit end time is over. This event is not emitted in fallback mode (see getPriceEpochData ). Parameters Type Description epochId uint256 The ID of the epoch that has just started. endTime uint256 Deadline to submit prices, in seconds since UNIX epoch. timestamp uint256 Current on-chain timestamp.","title":"PriceEpochInitializedOnFtso"},{"location":"apis/smart-contracts/IFtso/#ev_pricefinalized","text":"Defined in IFtso ( Docs , Source ). event PriceFinalized ( uint256 epochId , uint256 price , bool rewardedFtso , uint256 lowIQRRewardPrice , uint256 highIQRRewardPrice , uint256 lowElasticBandRewardPrice , uint256 highElasticBandRewardPrice , enum IFtso . PriceFinalizationType finalizationType , uint256 timestamp ) An epoch has ended and the asset price is available. Parameters Type Description epochId uint256 The ID of the epoch that has just ended. price uint256 The asset's price for that epoch. rewardedFtso bool Whether the next 4 parameters contain data. lowIQRRewardPrice uint256 Lowest price in the primary (inter-quartile) reward band. highIQRRewardPrice uint256 Highest price in the primary (inter-quartile) reward band. lowElasticBandRewardPrice uint256 Lowest price in the secondary (elastic) reward band. highElasticBandRewardPrice uint256 Highest price in the secondary (elastic) reward band. finalizationType enum IFtso.PriceFinalizationType Reason for the finalization of the epoch. timestamp uint256 Timestamp of the block where the price has been finalized.","title":"PriceFinalized"},{"location":"apis/smart-contracts/IFtso/#ev_pricerevealed","text":"Defined in IFtso ( Docs , Source ). event PriceRevealed ( address voter , uint256 epochId , uint256 price , uint256 timestamp , uint256 votePowerNat , uint256 votePowerAsset ) A voter has revealed its price. Parameters Type Description voter address The voter. epochId uint256 The ID of the epoch for which the price has been revealed. price uint256 The revealed price. timestamp uint256 Timestamp of the block where the reveal happened. votePowerNat uint256 Vote power of the voter in this epoch. This includes the vote power derived from its WNat holdings and the delegations. votePowerAsset uint256 Unused .","title":"PriceRevealed"},{"location":"apis/smart-contracts/IFtso/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IFtso/#fn_active_02fb0c5e","text":"Defined in IFtso ( Docs , Source ). function active ( ) external view returns ( bool ); Returns whether FTSO is active or not.","title":"active"},{"location":"apis/smart-contracts/IFtso/#fn_getcurrentepochid_a29a839f","text":"Defined in IFtso ( Docs , Source ). function getCurrentEpochId ( ) external view returns ( uint256 ); Returns the current epoch ID. Returns Type Description [0] uint256 Currently running epoch ID. IDs are consecutive numbers starting from zero.","title":"getCurrentEpochId"},{"location":"apis/smart-contracts/IFtso/#fn_getcurrentprice_eb91d37e","text":"Defined in IFtso ( Docs , Source ). function getCurrentPrice ( ) external view returns ( uint256 _price , uint256 _timestamp ); Returns the current asset price. Returns Type Description _price uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Time when price was updated for the last time, in seconds from UNIX epoch.","title":"getCurrentPrice"},{"location":"apis/smart-contracts/IFtso/#fn_getcurrentpricedetails_040d73b8","text":"Defined in IFtso ( Docs , Source ). function getCurrentPriceDetails ( ) external view returns ( uint256 _price , uint256 _priceTimestamp , enum IFtso . PriceFinalizationType _priceFinalizationType , uint256 _lastPriceEpochFinalizationTimestamp , enum IFtso . PriceFinalizationType _lastPriceEpochFinalizationType ); Returns asset's current price details. All timestamps are in seconds from UNIX epoch. Returns Type Description _price uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _priceTimestamp uint256 Time when price was updated for the last time. _priceFinalizationType enum IFtso.PriceFinalizationType Finalization type when price was updated for the last time. _lastPriceEpochFinalizationTimestamp uint256 Time when last price epoch was finalized. _lastPriceEpochFinalizationType enum IFtso.PriceFinalizationType Finalization type of last finalized price epoch.","title":"getCurrentPriceDetails"},{"location":"apis/smart-contracts/IFtso/#fn_getcurrentpricefromtrustedproviders_af52df08","text":"Defined in IFtso ( Docs , Source ). function getCurrentPriceFromTrustedProviders ( ) external view returns ( uint256 _price , uint256 _timestamp ); Returns current asset price calculated only using input from trusted providers. Returns Type Description _price uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Time when price was updated for the last time, in seconds from UNIX epoch.","title":"getCurrentPriceFromTrustedProviders"},{"location":"apis/smart-contracts/IFtso/#fn_getcurrentpricewithdecimals_65f5cd86","text":"Defined in IFtso ( Docs , Source ). function getCurrentPriceWithDecimals ( ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Returns current asset price and number of decimals. Returns Type Description _price uint256 Price in USD multiplied by 10^ _assetPriceUsdDecimals . _timestamp uint256 Time when price was updated for the last time, in seconds from UNIX epoch. _assetPriceUsdDecimals uint256 Number of decimals used to return the USD price.","title":"getCurrentPriceWithDecimals"},{"location":"apis/smart-contracts/IFtso/#fn_getcurrentpricewithdecimalsfromtrustedproviders_3cacb3ae","text":"Defined in IFtso ( Docs , Source ). function getCurrentPriceWithDecimalsFromTrustedProviders ( ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Returns current asset price calculated only using input from trusted providers and number of decimals. Returns Type Description _price uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Time when price was updated for the last time, in seconds from UNIX epoch. _assetPriceUsdDecimals uint256 Number of decimals used to return the USD price.","title":"getCurrentPriceWithDecimalsFromTrustedProviders"},{"location":"apis/smart-contracts/IFtso/#fn_getcurrentrandom_d89601fd","text":"Defined in IFtso ( Docs , Source ). function getCurrentRandom ( ) external view returns ( uint256 ); Returns the random number for the previous price epoch, obtained from the random numbers provided by all data providers along with their data submissions.","title":"getCurrentRandom"},{"location":"apis/smart-contracts/IFtso/#fn_getepochid_5303548b","text":"Defined in IFtso ( Docs , Source ). function getEpochId ( uint256 _timestamp ) external view returns ( uint256 ); Returns the ID of the epoch that was opened for price submission at the specified timestamp. Parameters Type Description _timestamp uint256 Queried timestamp in seconds from UNIX epoch. Returns Type Description [0] uint256 Epoch ID corresponding to that timestamp. IDs are consecutive numbers starting from zero.","title":"getEpochId"},{"location":"apis/smart-contracts/IFtso/#fn_getepochprice_7d1d6f12","text":"Defined in IFtso ( Docs , Source ). function getEpochPrice ( uint256 _epochId ) external view returns ( uint256 ); Returns agreed asset price in the specified epoch. Parameters Type Description _epochId uint256 ID of the epoch. Only the last 200 epochs can be queried. Out-of-bounds queries revert. Returns Type Description [0] uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS .","title":"getEpochPrice"},{"location":"apis/smart-contracts/IFtso/#fn_getepochpriceforvoter_c5d8b9e7","text":"Defined in IFtso ( Docs , Source ). function getEpochPriceForVoter ( uint256 _epochId , address _voter ) external view returns ( uint256 ); Returns asset price submitted by a voter in the specified epoch. Parameters Type Description _epochId uint256 ID of the epoch being queried. Only the last 200 epochs can be queried. Out-of-bounds queries revert. _voter address Address of the voter being queried. Returns Type Description [0] uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS .","title":"getEpochPriceForVoter"},{"location":"apis/smart-contracts/IFtso/#fn_getpriceepochconfiguration_144e1591","text":"Defined in IFtso ( Docs , Source ). function getPriceEpochConfiguration ( ) external view returns ( uint256 _firstEpochStartTs , uint256 _submitPeriodSeconds , uint256 _revealPeriodSeconds ); Returns current epoch's configuration. Returns Type Description _firstEpochStartTs uint256 First epoch start timestamp in seconds from UNIX epoch. _submitPeriodSeconds uint256 Submit period in seconds. _revealPeriodSeconds uint256 Reveal period in seconds.","title":"getPriceEpochConfiguration"},{"location":"apis/smart-contracts/IFtso/#fn_getpriceepochdata_e3b3a3b3","text":"Defined in IFtso ( Docs , Source ). function getPriceEpochData ( ) external view returns ( uint256 _epochId , uint256 _epochSubmitEndTime , uint256 _epochRevealEndTime , uint256 _votePowerBlock , bool _fallbackMode ); Returns current epoch data. Intervals are open on the right: End times are not included. Returns Type Description _epochId uint256 Current epoch ID. _epochSubmitEndTime uint256 End time of the price submission window in seconds from UNIX epoch. _epochRevealEndTime uint256 End time of the price reveal window in seconds from UNIX epoch. _votePowerBlock uint256 Vote power block for the current epoch. _fallbackMode bool Whether the current epoch is in fallback mode. Only votes from trusted addresses are used in this mode.","title":"getPriceEpochData"},{"location":"apis/smart-contracts/IFtso/#fn_getrandom_cd4b6914","text":"Defined in IFtso ( Docs , Source ). function getRandom ( uint256 _epochId ) external view returns ( uint256 ); Returns the random number used in a specific past epoch, obtained from the random numbers provided by all data providers along with their data submissions. Parameters Type Description _epochId uint256 ID of the queried epoch. Current epoch cannot be queried, and the previous epoch is constantly updated as data providers reveal their prices and random numbers. Only the last 50 epochs can be queried and there is no bounds checking for this parameter. Out-of-bounds queries return undefined values. Returns Type Description [0] uint256 The random number used in that epoch.","title":"getRandom"},{"location":"apis/smart-contracts/IFtso/#fn_symbol_95d89b41","text":"Defined in IFtso ( Docs , Source ). function symbol ( ) external view returns ( string ); Returns the FTSO symbol .","title":"symbol"},{"location":"apis/smart-contracts/IFtsoGenesis/","text":"IFtsoGenesis # Source Portion of the IFtso interface that is available to contracts deployed at genesis. Functions # revealPriceSubmitter # Defined in IFtsoGenesis ( Docs , Source ). function revealPriceSubmitter ( address _voter , uint256 _epochId , uint256 _price , uint256 _voterWNatVP ) external ; Reveals the price submitted by a voter on a specific epoch. The hash of _price and _random must be equal to the submitted hash Parameters Type Description _voter address Voter address. _epochId uint256 ID of the epoch in which the price hash was submitted. _price uint256 Submitted price. _voterWNatVP uint256 Voter's vote power in WNat units. wNatVotePowerCached # Defined in IFtsoGenesis ( Docs , Source ). function wNatVotePowerCached ( address _voter , uint256 _epochId ) external returns ( uint256 ); Get and cache the vote power of a voter on a specific epoch, in WNat units. Parameters Type Description _voter address Voter address. _epochId uint256 ID of the epoch in which the price hash was submitted. Returns Type Description [0] uint256 Voter's vote power in WNat units.","title":"IFtsoGenesis"},{"location":"apis/smart-contracts/IFtsoGenesis/#ct_iftsogenesis","text":"Source Portion of the IFtso interface that is available to contracts deployed at genesis.","title":"IFtsoGenesis"},{"location":"apis/smart-contracts/IFtsoGenesis/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IFtsoGenesis/#fn_revealpricesubmitter_c1f6c36e","text":"Defined in IFtsoGenesis ( Docs , Source ). function revealPriceSubmitter ( address _voter , uint256 _epochId , uint256 _price , uint256 _voterWNatVP ) external ; Reveals the price submitted by a voter on a specific epoch. The hash of _price and _random must be equal to the submitted hash Parameters Type Description _voter address Voter address. _epochId uint256 ID of the epoch in which the price hash was submitted. _price uint256 Submitted price. _voterWNatVP uint256 Voter's vote power in WNat units.","title":"revealPriceSubmitter"},{"location":"apis/smart-contracts/IFtsoGenesis/#fn_wnatvotepowercached_f72cab28","text":"Defined in IFtsoGenesis ( Docs , Source ). function wNatVotePowerCached ( address _voter , uint256 _epochId ) external returns ( uint256 ); Get and cache the vote power of a voter on a specific epoch, in WNat units. Parameters Type Description _voter address Voter address. _epochId uint256 ID of the epoch in which the price hash was submitted. Returns Type Description [0] uint256 Voter's vote power in WNat units.","title":"wNatVotePowerCached"},{"location":"apis/smart-contracts/IFtsoManager/","text":"IFtsoManager # Source | Inherits from IFtsoManagerGenesis Interface for the FtsoManager contract. Events # AccruingUnearnedRewardsFailed # Defined in IFtsoManager ( Docs , Source ). event AccruingUnearnedRewardsFailed ( uint256 epochId ) Unexpected failure while accruing unearned rewards. This should be a rare occurrence. Parameters Type Description epochId uint256 Epoch ID of the failure. DistributingRewardsFailed # Defined in IFtsoManager ( Docs , Source ). event DistributingRewardsFailed ( address ftso , uint256 epochId ) Unexpected failure while distributing rewards. This should be a rare occurrence. Parameters Type Description ftso address Contract address of the FTSO where the failure happened. epochId uint256 Epoch ID of the failure. FallbackMode # Defined in IFtsoManager ( Docs , Source ). event FallbackMode ( bool fallbackMode ) Emitted when the fallback mode of the FTSO manager changes its state. Fallback mode is a recovery mode, where only data from a trusted subset of FTSO data providers is used to calculate the final price. The FTSO Manager enters the fallback mode when ALL FTSOs are in fallback mode. Parameters Type Description fallbackMode bool New state of the FTSO Manager fallback mode. FinalizingPriceEpochFailed # Defined in IFtsoManager ( Docs , Source ). event FinalizingPriceEpochFailed ( contract IIFtso ftso , uint256 epochId , enum IFtso . PriceFinalizationType failingType ) Unexpected failure while finalizing a price epoch. This should be a rare occurrence. Parameters Type Description ftso contract IIFtso Contract address of the FTSO where the failure happened. epochId uint256 Epoch ID of the failure. failingType enum IFtso.PriceFinalizationType How was the epoch finalized. FtsoAdded # Defined in IFtsoManager ( Docs , Source ). event FtsoAdded ( contract IIFtso ftso , bool add ) Emitted when a new FTSO has been added or an existing one has been removed. Parameters Type Description ftso contract IIFtso Contract address of the FTSO. add bool True if added, removed otherwise. FtsoFallbackMode # Defined in IFtsoManager ( Docs , Source ). event FtsoFallbackMode ( contract IIFtso ftso , bool fallbackMode ) Emitted when the fallback mode of an FTSO changes its state. Parameters Type Description ftso contract IIFtso Contract address of the FTSO. fallbackMode bool New state of its fallback mode. InitializingCurrentEpochStateForRevealFailed # Defined in IFtsoManager ( Docs , Source ). event InitializingCurrentEpochStateForRevealFailed ( contract IIFtso ftso , uint256 epochId ) Unexpected failure while initializing a price epoch. This should be a rare occurrence. Parameters Type Description ftso contract IIFtso Contract address of the FTSO where the failure happened. epochId uint256 Epoch ID that failed initialization. PriceEpochFinalized # Defined in IFtsoManager ( Docs , Source ). event PriceEpochFinalized ( address chosenFtso , uint256 rewardEpochId ) Emitted when a price epoch ends, this is, after the reveal phase, when final prices are calculated. Parameters Type Description chosenFtso address Contract address of the FTSO asset that was randomly chosen to be the basis for reward calculation. On this price epoch, rewards will be calculated based on how close each data provider was to the median of all submitted prices FOR THIS FTSO. rewardEpochId uint256 Reward epoch ID this price epoch belongs to. RewardEpochFinalized # Defined in IFtsoManager ( Docs , Source ). event RewardEpochFinalized ( uint256 votepowerBlock , uint256 startBlock ) Emitted when a reward epoch ends and rewards are available. Parameters Type Description votepowerBlock uint256 The vote power block of the epoch. startBlock uint256 The first block of the epoch. UseGoodRandomSet # Defined in IFtsoManager ( Docs , Source ). event UseGoodRandomSet ( bool useGoodRandom , uint256 maxWaitForGoodRandomSeconds ) Emitted when the requirement to provide good random numbers has changed. As part of the FTSO protocol , data providers must submit a random number along with their price reveals. When good random numbers are enforced, all providers that submit a hash must then submit a reveal with a random number or they will be punished. This is a measure against random number manipulation. Parameters Type Description useGoodRandom bool Whether good random numbers are now enforced or not. maxWaitForGoodRandomSeconds uint256 Max number of seconds to wait for a good random number to be submitted. Functions # active # Defined in IFtsoManager ( Docs , Source ). function active ( ) external view returns ( bool ); Returns whether the FTSO Manager is active or not. Returns Type Description [0] bool bool Active status. getCurrentPriceEpochData # Defined in IFtsoManager ( Docs , Source ). function getCurrentPriceEpochData ( ) external view returns ( uint256 _priceEpochId , uint256 _priceEpochStartTimestamp , uint256 _priceEpochEndTimestamp , uint256 _priceEpochRevealEndTimestamp , uint256 _currentTimestamp ); Returns timing information for the current price epoch. All intervals are half-closed: end time is not included. All timestamps are in seconds since UNIX epoch. See the FTSO page for information about the different submission phases. Returns Type Description _priceEpochId uint256 Price epoch ID. _priceEpochStartTimestamp uint256 Beginning of the commit phase. _priceEpochEndTimestamp uint256 End of the commit phase. _priceEpochRevealEndTimestamp uint256 End of the reveal phase. _currentTimestamp uint256 Current time. getCurrentPriceEpochId # Defined in IFtsoManagerGenesis ( Docs , Source ). function getCurrentPriceEpochId ( ) external view returns ( uint256 _priceEpochId ); Returns current price epoch ID. Returns Type Description _priceEpochId uint256 Currently running epoch ID. IDs are consecutive numbers starting from zero. getCurrentRewardEpoch # Defined in IFtsoManager ( Docs , Source ). function getCurrentRewardEpoch ( ) external view returns ( uint256 ); Returns current reward epoch ID (the one currently running). Returns Type Description [0] uint256 Reward epoch ID. A monotonically increasing integer. getFallbackMode # Defined in IFtsoManager ( Docs , Source ). function getFallbackMode ( ) external view returns ( bool _fallbackMode , contract IIFtso [] _ftsos , bool [] _ftsoInFallbackMode ); Returns whether the FTSO Manager is currently in fallback mode. In this mode only submissions from trusted providers are used. Returns Type Description _fallbackMode bool True if fallback mode is enabled for the manager. _ftsos contract IIFtso[] Array of all currently active FTSO assets. _ftsoInFallbackMode bool[] Boolean array indicating which FTSO assets are in fallback mode. If the FTSO Manager is in fallback mode then ALL FTSOs are in fallback mode. getFtsos # Defined in IFtsoManager ( Docs , Source ). function getFtsos ( ) external view returns ( contract IIFtso [] _ftsos ); Returns the list of currently active FTSOs. Returns Type Description _ftsos contract IIFtso[] Array of contract addresses for the FTSOs. getPriceEpochConfiguration # Defined in IFtsoManager ( Docs , Source ). function getPriceEpochConfiguration ( ) external view returns ( uint256 _firstPriceEpochStartTs , uint256 _priceEpochDurationSeconds , uint256 _revealEpochDurationSeconds ); Returns the current values for price epoch timing configuration. See the FTSO page for information about the different submission phases. Returns Type Description _firstPriceEpochStartTs uint256 Timestamp, in seconds since UNIX epoch, of the first price epoch. _priceEpochDurationSeconds uint256 Duration in seconds of the commit phase. _revealEpochDurationSeconds uint256 Duration in seconds of the reveal phase. getRewardEpochConfiguration # Defined in IFtsoManager ( Docs , Source ). function getRewardEpochConfiguration ( ) external view returns ( uint256 _firstRewardEpochStartTs , uint256 _rewardEpochDurationSeconds ); Returns the current values for reward epoch timing configuration. See the Reward epochs box. Returns Type Description _firstRewardEpochStartTs uint256 Timestamp, in seconds since UNIX epoch, of the first reward epoch. _rewardEpochDurationSeconds uint256 Duration in seconds of the reward epochs. getRewardEpochToExpireNext # Defined in IFtsoManager ( Docs , Source ). function getRewardEpochToExpireNext ( ) external view returns ( uint256 ); Return reward epoch that will expire next, when a new reward epoch is initialized. Reward epochs older than 90 days expire, and any unclaimed rewards in them become inaccessible. Returns Type Description [0] uint256 uint256 Reward epoch ID. getRewardEpochVotePowerBlock # Defined in IFtsoManager ( Docs , Source ). function getRewardEpochVotePowerBlock ( uint256 _rewardEpoch ) external view returns ( uint256 ); Returns the vote power block that was used for a past reward epoch. Parameters Type Description _rewardEpoch uint256 The queried reward epoch ID. Returns Type Description [0] uint256 uint256 The block number of that reward epoch's vote power block.","title":"IFtsoManager"},{"location":"apis/smart-contracts/IFtsoManager/#ct_iftsomanager","text":"Source | Inherits from IFtsoManagerGenesis Interface for the FtsoManager contract.","title":"IFtsoManager"},{"location":"apis/smart-contracts/IFtsoManager/#events","text":"","title":"Events"},{"location":"apis/smart-contracts/IFtsoManager/#ev_accruingunearnedrewardsfailed","text":"Defined in IFtsoManager ( Docs , Source ). event AccruingUnearnedRewardsFailed ( uint256 epochId ) Unexpected failure while accruing unearned rewards. This should be a rare occurrence. Parameters Type Description epochId uint256 Epoch ID of the failure.","title":"AccruingUnearnedRewardsFailed"},{"location":"apis/smart-contracts/IFtsoManager/#ev_distributingrewardsfailed","text":"Defined in IFtsoManager ( Docs , Source ). event DistributingRewardsFailed ( address ftso , uint256 epochId ) Unexpected failure while distributing rewards. This should be a rare occurrence. Parameters Type Description ftso address Contract address of the FTSO where the failure happened. epochId uint256 Epoch ID of the failure.","title":"DistributingRewardsFailed"},{"location":"apis/smart-contracts/IFtsoManager/#ev_fallbackmode","text":"Defined in IFtsoManager ( Docs , Source ). event FallbackMode ( bool fallbackMode ) Emitted when the fallback mode of the FTSO manager changes its state. Fallback mode is a recovery mode, where only data from a trusted subset of FTSO data providers is used to calculate the final price. The FTSO Manager enters the fallback mode when ALL FTSOs are in fallback mode. Parameters Type Description fallbackMode bool New state of the FTSO Manager fallback mode.","title":"FallbackMode"},{"location":"apis/smart-contracts/IFtsoManager/#ev_finalizingpriceepochfailed","text":"Defined in IFtsoManager ( Docs , Source ). event FinalizingPriceEpochFailed ( contract IIFtso ftso , uint256 epochId , enum IFtso . PriceFinalizationType failingType ) Unexpected failure while finalizing a price epoch. This should be a rare occurrence. Parameters Type Description ftso contract IIFtso Contract address of the FTSO where the failure happened. epochId uint256 Epoch ID of the failure. failingType enum IFtso.PriceFinalizationType How was the epoch finalized.","title":"FinalizingPriceEpochFailed"},{"location":"apis/smart-contracts/IFtsoManager/#ev_ftsoadded","text":"Defined in IFtsoManager ( Docs , Source ). event FtsoAdded ( contract IIFtso ftso , bool add ) Emitted when a new FTSO has been added or an existing one has been removed. Parameters Type Description ftso contract IIFtso Contract address of the FTSO. add bool True if added, removed otherwise.","title":"FtsoAdded"},{"location":"apis/smart-contracts/IFtsoManager/#ev_ftsofallbackmode","text":"Defined in IFtsoManager ( Docs , Source ). event FtsoFallbackMode ( contract IIFtso ftso , bool fallbackMode ) Emitted when the fallback mode of an FTSO changes its state. Parameters Type Description ftso contract IIFtso Contract address of the FTSO. fallbackMode bool New state of its fallback mode.","title":"FtsoFallbackMode"},{"location":"apis/smart-contracts/IFtsoManager/#ev_initializingcurrentepochstateforrevealfailed","text":"Defined in IFtsoManager ( Docs , Source ). event InitializingCurrentEpochStateForRevealFailed ( contract IIFtso ftso , uint256 epochId ) Unexpected failure while initializing a price epoch. This should be a rare occurrence. Parameters Type Description ftso contract IIFtso Contract address of the FTSO where the failure happened. epochId uint256 Epoch ID that failed initialization.","title":"InitializingCurrentEpochStateForRevealFailed"},{"location":"apis/smart-contracts/IFtsoManager/#ev_priceepochfinalized","text":"Defined in IFtsoManager ( Docs , Source ). event PriceEpochFinalized ( address chosenFtso , uint256 rewardEpochId ) Emitted when a price epoch ends, this is, after the reveal phase, when final prices are calculated. Parameters Type Description chosenFtso address Contract address of the FTSO asset that was randomly chosen to be the basis for reward calculation. On this price epoch, rewards will be calculated based on how close each data provider was to the median of all submitted prices FOR THIS FTSO. rewardEpochId uint256 Reward epoch ID this price epoch belongs to.","title":"PriceEpochFinalized"},{"location":"apis/smart-contracts/IFtsoManager/#ev_rewardepochfinalized","text":"Defined in IFtsoManager ( Docs , Source ). event RewardEpochFinalized ( uint256 votepowerBlock , uint256 startBlock ) Emitted when a reward epoch ends and rewards are available. Parameters Type Description votepowerBlock uint256 The vote power block of the epoch. startBlock uint256 The first block of the epoch.","title":"RewardEpochFinalized"},{"location":"apis/smart-contracts/IFtsoManager/#ev_usegoodrandomset","text":"Defined in IFtsoManager ( Docs , Source ). event UseGoodRandomSet ( bool useGoodRandom , uint256 maxWaitForGoodRandomSeconds ) Emitted when the requirement to provide good random numbers has changed. As part of the FTSO protocol , data providers must submit a random number along with their price reveals. When good random numbers are enforced, all providers that submit a hash must then submit a reveal with a random number or they will be punished. This is a measure against random number manipulation. Parameters Type Description useGoodRandom bool Whether good random numbers are now enforced or not. maxWaitForGoodRandomSeconds uint256 Max number of seconds to wait for a good random number to be submitted.","title":"UseGoodRandomSet"},{"location":"apis/smart-contracts/IFtsoManager/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IFtsoManager/#fn_active_02fb0c5e","text":"Defined in IFtsoManager ( Docs , Source ). function active ( ) external view returns ( bool ); Returns whether the FTSO Manager is active or not. Returns Type Description [0] bool bool Active status.","title":"active"},{"location":"apis/smart-contracts/IFtsoManager/#fn_getcurrentpriceepochdata_93a79025","text":"Defined in IFtsoManager ( Docs , Source ). function getCurrentPriceEpochData ( ) external view returns ( uint256 _priceEpochId , uint256 _priceEpochStartTimestamp , uint256 _priceEpochEndTimestamp , uint256 _priceEpochRevealEndTimestamp , uint256 _currentTimestamp ); Returns timing information for the current price epoch. All intervals are half-closed: end time is not included. All timestamps are in seconds since UNIX epoch. See the FTSO page for information about the different submission phases. Returns Type Description _priceEpochId uint256 Price epoch ID. _priceEpochStartTimestamp uint256 Beginning of the commit phase. _priceEpochEndTimestamp uint256 End of the commit phase. _priceEpochRevealEndTimestamp uint256 End of the reveal phase. _currentTimestamp uint256 Current time.","title":"getCurrentPriceEpochData"},{"location":"apis/smart-contracts/IFtsoManager/#fn_getcurrentpriceepochid_08a7f402","text":"Defined in IFtsoManagerGenesis ( Docs , Source ). function getCurrentPriceEpochId ( ) external view returns ( uint256 _priceEpochId ); Returns current price epoch ID. Returns Type Description _priceEpochId uint256 Currently running epoch ID. IDs are consecutive numbers starting from zero.","title":"getCurrentPriceEpochId"},{"location":"apis/smart-contracts/IFtsoManager/#fn_getcurrentrewardepoch_e7c830d4","text":"Defined in IFtsoManager ( Docs , Source ). function getCurrentRewardEpoch ( ) external view returns ( uint256 ); Returns current reward epoch ID (the one currently running). Returns Type Description [0] uint256 Reward epoch ID. A monotonically increasing integer.","title":"getCurrentRewardEpoch"},{"location":"apis/smart-contracts/IFtsoManager/#fn_getfallbackmode_4b48dd5e","text":"Defined in IFtsoManager ( Docs , Source ). function getFallbackMode ( ) external view returns ( bool _fallbackMode , contract IIFtso [] _ftsos , bool [] _ftsoInFallbackMode ); Returns whether the FTSO Manager is currently in fallback mode. In this mode only submissions from trusted providers are used. Returns Type Description _fallbackMode bool True if fallback mode is enabled for the manager. _ftsos contract IIFtso[] Array of all currently active FTSO assets. _ftsoInFallbackMode bool[] Boolean array indicating which FTSO assets are in fallback mode. If the FTSO Manager is in fallback mode then ALL FTSOs are in fallback mode.","title":"getFallbackMode"},{"location":"apis/smart-contracts/IFtsoManager/#fn_getftsos_ce69f833","text":"Defined in IFtsoManager ( Docs , Source ). function getFtsos ( ) external view returns ( contract IIFtso [] _ftsos ); Returns the list of currently active FTSOs. Returns Type Description _ftsos contract IIFtso[] Array of contract addresses for the FTSOs.","title":"getFtsos"},{"location":"apis/smart-contracts/IFtsoManager/#fn_getpriceepochconfiguration_144e1591","text":"Defined in IFtsoManager ( Docs , Source ). function getPriceEpochConfiguration ( ) external view returns ( uint256 _firstPriceEpochStartTs , uint256 _priceEpochDurationSeconds , uint256 _revealEpochDurationSeconds ); Returns the current values for price epoch timing configuration. See the FTSO page for information about the different submission phases. Returns Type Description _firstPriceEpochStartTs uint256 Timestamp, in seconds since UNIX epoch, of the first price epoch. _priceEpochDurationSeconds uint256 Duration in seconds of the commit phase. _revealEpochDurationSeconds uint256 Duration in seconds of the reveal phase.","title":"getPriceEpochConfiguration"},{"location":"apis/smart-contracts/IFtsoManager/#fn_getrewardepochconfiguration_1cb513f7","text":"Defined in IFtsoManager ( Docs , Source ). function getRewardEpochConfiguration ( ) external view returns ( uint256 _firstRewardEpochStartTs , uint256 _rewardEpochDurationSeconds ); Returns the current values for reward epoch timing configuration. See the Reward epochs box. Returns Type Description _firstRewardEpochStartTs uint256 Timestamp, in seconds since UNIX epoch, of the first reward epoch. _rewardEpochDurationSeconds uint256 Duration in seconds of the reward epochs.","title":"getRewardEpochConfiguration"},{"location":"apis/smart-contracts/IFtsoManager/#fn_getrewardepochtoexpirenext_3e7ff857","text":"Defined in IFtsoManager ( Docs , Source ). function getRewardEpochToExpireNext ( ) external view returns ( uint256 ); Return reward epoch that will expire next, when a new reward epoch is initialized. Reward epochs older than 90 days expire, and any unclaimed rewards in them become inaccessible. Returns Type Description [0] uint256 uint256 Reward epoch ID.","title":"getRewardEpochToExpireNext"},{"location":"apis/smart-contracts/IFtsoManager/#fn_getrewardepochvotepowerblock_f2edab5a","text":"Defined in IFtsoManager ( Docs , Source ). function getRewardEpochVotePowerBlock ( uint256 _rewardEpoch ) external view returns ( uint256 ); Returns the vote power block that was used for a past reward epoch. Parameters Type Description _rewardEpoch uint256 The queried reward epoch ID. Returns Type Description [0] uint256 uint256 The block number of that reward epoch's vote power block.","title":"getRewardEpochVotePowerBlock"},{"location":"apis/smart-contracts/IFtsoManagerGenesis/","text":"IFtsoManagerGenesis # Source Portion of the IFtsoManager interface that is available to contracts deployed at genesis. Functions # getCurrentPriceEpochId # Defined in IFtsoManagerGenesis ( Docs , Source ). function getCurrentPriceEpochId ( ) external view returns ( uint256 _priceEpochId ); Returns current price epoch ID. Returns Type Description _priceEpochId uint256 Currently running epoch ID. IDs are consecutive numbers starting from zero.","title":"IFtsoManagerGenesis"},{"location":"apis/smart-contracts/IFtsoManagerGenesis/#ct_iftsomanagergenesis","text":"Source Portion of the IFtsoManager interface that is available to contracts deployed at genesis.","title":"IFtsoManagerGenesis"},{"location":"apis/smart-contracts/IFtsoManagerGenesis/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IFtsoManagerGenesis/#fn_getcurrentpriceepochid_08a7f402","text":"Defined in IFtsoManagerGenesis ( Docs , Source ). function getCurrentPriceEpochId ( ) external view returns ( uint256 _priceEpochId ); Returns current price epoch ID. Returns Type Description _priceEpochId uint256 Currently running epoch ID. IDs are consecutive numbers starting from zero.","title":"getCurrentPriceEpochId"},{"location":"apis/smart-contracts/IFtsoRegistry/","text":"IFtsoRegistry # Source | Inherits from IFtsoRegistryGenesis Interface for the FtsoRegistry contract. Functions # getAllCurrentPrices # Defined in IFtsoRegistry ( Docs , Source ). function getAllCurrentPrices ( ) external view returns ( struct IFtsoRegistry . PriceInfo []); Returns the current price of all supported assets. Returns Type Description [0] struct IFtsoRegistry.PriceInfo[] Array of PriceInfo structures. getCurrentPrice # Defined in IFtsoRegistry ( Docs , Source ). function getCurrentPrice ( uint256 _ftsoIndex ) external view returns ( uint256 _price , uint256 _timestamp ); Public view function to get the current price of a given active FTSO index. Reverts if the index is not supported. Parameters Type Description _ftsoIndex uint256 Index to query. Returns Type Description _price uint256 Current price of the asset in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Timestamp for when this price was updated, in seconds since UNIX epoch. getCurrentPrice # Defined in IFtsoRegistry ( Docs , Source ). function getCurrentPrice ( string _symbol ) external view returns ( uint256 _price , uint256 _timestamp ); Public view function to get the current price of a given active asset symbol. Reverts if the symbol is not supported. Parameters Type Description _symbol string Symbol to query. Returns Type Description _price uint256 Current price of the asset in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Timestamp for when this price was updated, in seconds since UNIX epoch. getCurrentPriceWithDecimals # Defined in IFtsoRegistry ( Docs , Source ). function getCurrentPriceWithDecimals ( uint256 _assetIndex ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Public view function to get the current price and decimals of a given active FTSO index. Reverts if the index is not supported. Parameters Type Description _assetIndex uint256 Index to query. Returns Type Description _price uint256 Current price of the asset in USD multiplied by 10^ _assetPriceUsdDecimals . _timestamp uint256 Timestamp for when this price was updated, in seconds since UNIX epoch. _assetPriceUsdDecimals uint256 Number of decimals used to return the _price . getCurrentPriceWithDecimals # Defined in IFtsoRegistry ( Docs , Source ). function getCurrentPriceWithDecimals ( string _symbol ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Public view function to get the current price and decimals of a given active asset symbol. Reverts if the symbol is not supported. Parameters Type Description _symbol string Symbol to query. Returns Type Description _price uint256 Current price of the asset in USD multiplied by 10^ _assetPriceUsdDecimals . _timestamp uint256 Timestamp for when this price was updated, in seconds since UNIX epoch. _assetPriceUsdDecimals uint256 Number of decimals used to return the _price . getCurrentPricesByIndices # Defined in IFtsoRegistry ( Docs , Source ). function getCurrentPricesByIndices ( uint256 [] _indices ) external view returns ( struct IFtsoRegistry . PriceInfo []); Returns the current price of a list of indices. Reverts if any of the indices is not supported. Parameters Type Description _indices uint256[] Array of indices to query. Returns Type Description [0] struct IFtsoRegistry.PriceInfo[] Array of PriceInfo structures. getCurrentPricesBySymbols # Defined in IFtsoRegistry ( Docs , Source ). function getCurrentPricesBySymbols ( string [] _symbols ) external view returns ( struct IFtsoRegistry . PriceInfo []); Returns the current price of a list of asset symbols. Reverts if any of the symbols is not supported. Parameters Type Description _symbols string[] Array of symbols to query. Returns Type Description [0] struct IFtsoRegistry.PriceInfo[] Array of PriceInfo structures. getFtso # Defined in IFtsoRegistry ( Docs , Source ). function getFtso ( uint256 _activeFtso ) external view returns ( contract IIFtso _activeFtsoAddress ); Returns the address of the FTSO contract for a given index. Reverts if unsupported index is passed. Parameters Type Description _activeFtso uint256 The queried index. Returns Type Description _activeFtsoAddress contract IIFtso FTSO contract address for the queried index. getFtsoBySymbol # Defined in IFtsoRegistry ( Docs , Source ). function getFtsoBySymbol ( string _symbol ) external view returns ( contract IIFtso _activeFtsoAddress ); Returns the address of the FTSO contract for a given symbol. Reverts if unsupported symbol is passed. Parameters Type Description _symbol string The queried symbol. Returns Type Description _activeFtsoAddress contract IIFtso FTSO contract address for the queried symbol. getFtsoIndex # Defined in IFtsoRegistry ( Docs , Source ). function getFtsoIndex ( string _symbol ) external view returns ( uint256 _assetIndex ); Returns the FTSO index corresponding to a given asset symbol. Reverts if the symbol is not supported. Parameters Type Description _symbol string Symbol to query. Returns Type Description _assetIndex uint256 The corresponding asset index. getFtsoSymbol # Defined in IFtsoRegistry ( Docs , Source ). function getFtsoSymbol ( uint256 _ftsoIndex ) external view returns ( string _symbol ); Returns the asset symbol corresponding to a given FTSO index. Reverts if the index is not supported. Parameters Type Description _ftsoIndex uint256 Index to query. Returns Type Description _symbol string The corresponding asset symbol. getFtsos # Defined in IFtsoRegistryGenesis ( Docs , Source ). function getFtsos ( uint256 [] _indices ) external view returns ( contract IFtsoGenesis [] _ftsos ); Get the addresses of the active FTSOs at the given indices. Reverts if any of the provided indices is non-existing or inactive. Parameters Type Description _indices uint256[] Array of FTSO indices to query. Returns Type Description _ftsos contract IFtsoGenesis[] The array of FTSO addresses. getSupportedFtsos # Defined in IFtsoRegistry ( Docs , Source ). function getSupportedFtsos ( ) external view returns ( contract IIFtso [] _ftsos ); Get array of all FTSO contracts for all supported asset indices. The index of FTSO in returned array does not necessarily correspond to the asset's index. Due to deletion, some indices might be unsupported. Use getSupportedIndicesAndFtsos to retrieve pairs of correct indices and FTSOs, where possible \"null\" holes are readily apparent. Returns Type Description _ftsos contract IIFtso[] Array of all supported FTSOs. getSupportedIndices # Defined in IFtsoRegistry ( Docs , Source ). function getSupportedIndices ( ) external view returns ( uint256 [] _supportedIndices ); Returns the indices of the currently supported FTSOs. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedIndices uint256[] Array of all active FTSO indices in increasing order. getSupportedIndicesAndFtsos # Defined in IFtsoRegistry ( Docs , Source ). function getSupportedIndicesAndFtsos ( ) external view returns ( uint256 [] _supportedIndices , contract IIFtso [] _ftsos ); Get all supported indices and corresponding FTSO addresses. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedIndices uint256[] Array of all supported indices. _ftsos contract IIFtso[] Array of all supported FTSO addresses. getSupportedIndicesAndSymbols # Defined in IFtsoRegistry ( Docs , Source ). function getSupportedIndicesAndSymbols ( ) external view returns ( uint256 [] _supportedIndices , string [] _supportedSymbols ); Get all supported indices and corresponding symbols. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedIndices uint256[] Array of all supported indices. _supportedSymbols string[] Array of all supported symbols. getSupportedIndicesSymbolsAndFtsos # Defined in IFtsoRegistry ( Docs , Source ). function getSupportedIndicesSymbolsAndFtsos ( ) external view returns ( uint256 [] _supportedIndices , string [] _supportedSymbols , contract IIFtso [] _ftsos ); Get all supported indices, symbols, and corresponding FTSO addresses. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedIndices uint256[] Array of all supported indices. _supportedSymbols string[] Array of all supported symbols. _ftsos contract IIFtso[] Array of all supported FTSO addresses. getSupportedSymbols # Defined in IFtsoRegistry ( Docs , Source ). function getSupportedSymbols ( ) external view returns ( string [] _supportedSymbols ); Returns the symbols of the currently supported FTSOs. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedSymbols string[] Array of all active FTSO symbols in increasing order. getSupportedSymbolsAndFtsos # Defined in IFtsoRegistry ( Docs , Source ). function getSupportedSymbolsAndFtsos ( ) external view returns ( string [] _supportedSymbols , contract IIFtso [] _ftsos ); Get all supported symbols and corresponding FTSO addresses. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedSymbols string[] Array of all supported symbols. _ftsos contract IIFtso[] Array of all supported FTSO addresses. Structures # PriceInfo # Defined in IFtsoRegistry ( Docs , Source ). struct PriceInfo { uint256 ftsoIndex ; uint256 price ; uint256 decimals ; uint256 timestamp ; }","title":"IFtsoRegistry"},{"location":"apis/smart-contracts/IFtsoRegistry/#ct_iftsoregistry","text":"Source | Inherits from IFtsoRegistryGenesis Interface for the FtsoRegistry contract.","title":"IFtsoRegistry"},{"location":"apis/smart-contracts/IFtsoRegistry/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IFtsoRegistry/#fn_getallcurrentprices_58f9296f","text":"Defined in IFtsoRegistry ( Docs , Source ). function getAllCurrentPrices ( ) external view returns ( struct IFtsoRegistry . PriceInfo []); Returns the current price of all supported assets. Returns Type Description [0] struct IFtsoRegistry.PriceInfo[] Array of PriceInfo structures.","title":"getAllCurrentPrices"},{"location":"apis/smart-contracts/IFtsoRegistry/#fn_getcurrentprice_c55d0f56","text":"Defined in IFtsoRegistry ( Docs , Source ). function getCurrentPrice ( uint256 _ftsoIndex ) external view returns ( uint256 _price , uint256 _timestamp ); Public view function to get the current price of a given active FTSO index. Reverts if the index is not supported. Parameters Type Description _ftsoIndex uint256 Index to query. Returns Type Description _price uint256 Current price of the asset in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Timestamp for when this price was updated, in seconds since UNIX epoch.","title":"getCurrentPrice"},{"location":"apis/smart-contracts/IFtsoRegistry/#fn_getcurrentprice_42a0f243","text":"Defined in IFtsoRegistry ( Docs , Source ). function getCurrentPrice ( string _symbol ) external view returns ( uint256 _price , uint256 _timestamp ); Public view function to get the current price of a given active asset symbol. Reverts if the symbol is not supported. Parameters Type Description _symbol string Symbol to query. Returns Type Description _price uint256 Current price of the asset in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Timestamp for when this price was updated, in seconds since UNIX epoch.","title":"getCurrentPrice"},{"location":"apis/smart-contracts/IFtsoRegistry/#fn_getcurrentpricewithdecimals_257cbd3a","text":"Defined in IFtsoRegistry ( Docs , Source ). function getCurrentPriceWithDecimals ( uint256 _assetIndex ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Public view function to get the current price and decimals of a given active FTSO index. Reverts if the index is not supported. Parameters Type Description _assetIndex uint256 Index to query. Returns Type Description _price uint256 Current price of the asset in USD multiplied by 10^ _assetPriceUsdDecimals . _timestamp uint256 Timestamp for when this price was updated, in seconds since UNIX epoch. _assetPriceUsdDecimals uint256 Number of decimals used to return the _price .","title":"getCurrentPriceWithDecimals"},{"location":"apis/smart-contracts/IFtsoRegistry/#fn_getcurrentpricewithdecimals_a69afdc6","text":"Defined in IFtsoRegistry ( Docs , Source ). function getCurrentPriceWithDecimals ( string _symbol ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Public view function to get the current price and decimals of a given active asset symbol. Reverts if the symbol is not supported. Parameters Type Description _symbol string Symbol to query. Returns Type Description _price uint256 Current price of the asset in USD multiplied by 10^ _assetPriceUsdDecimals . _timestamp uint256 Timestamp for when this price was updated, in seconds since UNIX epoch. _assetPriceUsdDecimals uint256 Number of decimals used to return the _price .","title":"getCurrentPriceWithDecimals"},{"location":"apis/smart-contracts/IFtsoRegistry/#fn_getcurrentpricesbyindices_6ba31fa1","text":"Defined in IFtsoRegistry ( Docs , Source ). function getCurrentPricesByIndices ( uint256 [] _indices ) external view returns ( struct IFtsoRegistry . PriceInfo []); Returns the current price of a list of indices. Reverts if any of the indices is not supported. Parameters Type Description _indices uint256[] Array of indices to query. Returns Type Description [0] struct IFtsoRegistry.PriceInfo[] Array of PriceInfo structures.","title":"getCurrentPricesByIndices"},{"location":"apis/smart-contracts/IFtsoRegistry/#fn_getcurrentpricesbysymbols_79d5ea4b","text":"Defined in IFtsoRegistry ( Docs , Source ). function getCurrentPricesBySymbols ( string [] _symbols ) external view returns ( struct IFtsoRegistry . PriceInfo []); Returns the current price of a list of asset symbols. Reverts if any of the symbols is not supported. Parameters Type Description _symbols string[] Array of symbols to query. Returns Type Description [0] struct IFtsoRegistry.PriceInfo[] Array of PriceInfo structures.","title":"getCurrentPricesBySymbols"},{"location":"apis/smart-contracts/IFtsoRegistry/#fn_getftso_d75f6d81","text":"Defined in IFtsoRegistry ( Docs , Source ). function getFtso ( uint256 _activeFtso ) external view returns ( contract IIFtso _activeFtsoAddress ); Returns the address of the FTSO contract for a given index. Reverts if unsupported index is passed. Parameters Type Description _activeFtso uint256 The queried index. Returns Type Description _activeFtsoAddress contract IIFtso FTSO contract address for the queried index.","title":"getFtso"},{"location":"apis/smart-contracts/IFtsoRegistry/#fn_getftsobysymbol_97da6af4","text":"Defined in IFtsoRegistry ( Docs , Source ). function getFtsoBySymbol ( string _symbol ) external view returns ( contract IIFtso _activeFtsoAddress ); Returns the address of the FTSO contract for a given symbol. Reverts if unsupported symbol is passed. Parameters Type Description _symbol string The queried symbol. Returns Type Description _activeFtsoAddress contract IIFtso FTSO contract address for the queried symbol.","title":"getFtsoBySymbol"},{"location":"apis/smart-contracts/IFtsoRegistry/#fn_getftsoindex_e848da30","text":"Defined in IFtsoRegistry ( Docs , Source ). function getFtsoIndex ( string _symbol ) external view returns ( uint256 _assetIndex ); Returns the FTSO index corresponding to a given asset symbol. Reverts if the symbol is not supported. Parameters Type Description _symbol string Symbol to query. Returns Type Description _assetIndex uint256 The corresponding asset index.","title":"getFtsoIndex"},{"location":"apis/smart-contracts/IFtsoRegistry/#fn_getftsosymbol_136d3f64","text":"Defined in IFtsoRegistry ( Docs , Source ). function getFtsoSymbol ( uint256 _ftsoIndex ) external view returns ( string _symbol ); Returns the asset symbol corresponding to a given FTSO index. Reverts if the index is not supported. Parameters Type Description _ftsoIndex uint256 Index to query. Returns Type Description _symbol string The corresponding asset symbol.","title":"getFtsoSymbol"},{"location":"apis/smart-contracts/IFtsoRegistry/#fn_getftsos_9cb47538","text":"Defined in IFtsoRegistryGenesis ( Docs , Source ). function getFtsos ( uint256 [] _indices ) external view returns ( contract IFtsoGenesis [] _ftsos ); Get the addresses of the active FTSOs at the given indices. Reverts if any of the provided indices is non-existing or inactive. Parameters Type Description _indices uint256[] Array of FTSO indices to query. Returns Type Description _ftsos contract IFtsoGenesis[] The array of FTSO addresses.","title":"getFtsos"},{"location":"apis/smart-contracts/IFtsoRegistry/#fn_getsupportedftsos_a40060ba","text":"Defined in IFtsoRegistry ( Docs , Source ). function getSupportedFtsos ( ) external view returns ( contract IIFtso [] _ftsos ); Get array of all FTSO contracts for all supported asset indices. The index of FTSO in returned array does not necessarily correspond to the asset's index. Due to deletion, some indices might be unsupported. Use getSupportedIndicesAndFtsos to retrieve pairs of correct indices and FTSOs, where possible \"null\" holes are readily apparent. Returns Type Description _ftsos contract IIFtso[] Array of all supported FTSOs.","title":"getSupportedFtsos"},{"location":"apis/smart-contracts/IFtsoRegistry/#fn_getsupportedindices_798aac5b","text":"Defined in IFtsoRegistry ( Docs , Source ). function getSupportedIndices ( ) external view returns ( uint256 [] _supportedIndices ); Returns the indices of the currently supported FTSOs. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedIndices uint256[] Array of all active FTSO indices in increasing order.","title":"getSupportedIndices"},{"location":"apis/smart-contracts/IFtsoRegistry/#fn_getsupportedindicesandftsos_06a2ba29","text":"Defined in IFtsoRegistry ( Docs , Source ). function getSupportedIndicesAndFtsos ( ) external view returns ( uint256 [] _supportedIndices , contract IIFtso [] _ftsos ); Get all supported indices and corresponding FTSO addresses. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedIndices uint256[] Array of all supported indices. _ftsos contract IIFtso[] Array of all supported FTSO addresses.","title":"getSupportedIndicesAndFtsos"},{"location":"apis/smart-contracts/IFtsoRegistry/#fn_getsupportedindicesandsymbols_e68f283b","text":"Defined in IFtsoRegistry ( Docs , Source ). function getSupportedIndicesAndSymbols ( ) external view returns ( uint256 [] _supportedIndices , string [] _supportedSymbols ); Get all supported indices and corresponding symbols. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedIndices uint256[] Array of all supported indices. _supportedSymbols string[] Array of all supported symbols.","title":"getSupportedIndicesAndSymbols"},{"location":"apis/smart-contracts/IFtsoRegistry/#fn_getsupportedindicessymbolsandftsos_7687542c","text":"Defined in IFtsoRegistry ( Docs , Source ). function getSupportedIndicesSymbolsAndFtsos ( ) external view returns ( uint256 [] _supportedIndices , string [] _supportedSymbols , contract IIFtso [] _ftsos ); Get all supported indices, symbols, and corresponding FTSO addresses. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedIndices uint256[] Array of all supported indices. _supportedSymbols string[] Array of all supported symbols. _ftsos contract IIFtso[] Array of all supported FTSO addresses.","title":"getSupportedIndicesSymbolsAndFtsos"},{"location":"apis/smart-contracts/IFtsoRegistry/#fn_getsupportedsymbols_ce1c0e4d","text":"Defined in IFtsoRegistry ( Docs , Source ). function getSupportedSymbols ( ) external view returns ( string [] _supportedSymbols ); Returns the symbols of the currently supported FTSOs. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedSymbols string[] Array of all active FTSO symbols in increasing order.","title":"getSupportedSymbols"},{"location":"apis/smart-contracts/IFtsoRegistry/#fn_getsupportedsymbolsandftsos_0cf48497","text":"Defined in IFtsoRegistry ( Docs , Source ). function getSupportedSymbolsAndFtsos ( ) external view returns ( string [] _supportedSymbols , contract IIFtso [] _ftsos ); Get all supported symbols and corresponding FTSO addresses. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedSymbols string[] Array of all supported symbols. _ftsos contract IIFtso[] Array of all supported FTSO addresses.","title":"getSupportedSymbolsAndFtsos"},{"location":"apis/smart-contracts/IFtsoRegistry/#structures","text":"","title":"Structures"},{"location":"apis/smart-contracts/IFtsoRegistry/#st_priceinfo","text":"Defined in IFtsoRegistry ( Docs , Source ). struct PriceInfo { uint256 ftsoIndex ; uint256 price ; uint256 decimals ; uint256 timestamp ; }","title":"PriceInfo"},{"location":"apis/smart-contracts/IFtsoRegistryGenesis/","text":"IFtsoRegistryGenesis # Source Portion of the IFtsoRegistry interface that is available to contracts deployed at genesis. Functions # getFtsos # Defined in IFtsoRegistryGenesis ( Docs , Source ). function getFtsos ( uint256 [] _indices ) external view returns ( contract IFtsoGenesis [] _ftsos ); Get the addresses of the active FTSOs at the given indices. Reverts if any of the provided indices is non-existing or inactive. Parameters Type Description _indices uint256[] Array of FTSO indices to query. Returns Type Description _ftsos contract IFtsoGenesis[] The array of FTSO addresses.","title":"IFtsoRegistryGenesis"},{"location":"apis/smart-contracts/IFtsoRegistryGenesis/#ct_iftsoregistrygenesis","text":"Source Portion of the IFtsoRegistry interface that is available to contracts deployed at genesis.","title":"IFtsoRegistryGenesis"},{"location":"apis/smart-contracts/IFtsoRegistryGenesis/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IFtsoRegistryGenesis/#fn_getftsos_9cb47538","text":"Defined in IFtsoRegistryGenesis ( Docs , Source ). function getFtsos ( uint256 [] _indices ) external view returns ( contract IFtsoGenesis [] _ftsos ); Get the addresses of the active FTSOs at the given indices. Reverts if any of the provided indices is non-existing or inactive. Parameters Type Description _indices uint256[] Array of FTSO indices to query. Returns Type Description _ftsos contract IFtsoGenesis[] The array of FTSO addresses.","title":"getFtsos"},{"location":"apis/smart-contracts/IFtsoRewardManager/","text":"IFtsoRewardManager # Source Interface for the FtsoRewardManager contract. Events # FeePercentageChanged # Defined in IFtsoRewardManager ( Docs , Source ). event FeePercentageChanged ( address dataProvider , uint256 value , uint256 validFromEpoch ) Emitted when a data provider changes its fee. Parameters Type Description dataProvider address Address of the data provider. value uint256 New fee, in BIPS. validFromEpoch uint256 Epoch ID where the new fee takes effect. FtsoRewardManagerActivated # Defined in IFtsoRewardManager ( Docs , Source ). event FtsoRewardManagerActivated ( address ftsoRewardManager ) Emitted when the reward manager contract is activated. Parameters Type Description ftsoRewardManager address The reward manager contract. FtsoRewardManagerDeactivated # Defined in IFtsoRewardManager ( Docs , Source ). event FtsoRewardManagerDeactivated ( address ftsoRewardManager ) Emitted when the reward manager contract is deactivated. Parameters Type Description ftsoRewardManager address The reward manager contract. RewardClaimed # Defined in IFtsoRewardManager ( Docs , Source ). event RewardClaimed ( address dataProvider , address whoClaimed , address sentTo , uint256 rewardEpoch , uint256 amount ) Emitted when a data provider claims its FTSO rewards. Parameters Type Description dataProvider address Address of the data provider that accrued the reward. whoClaimed address Address that actually performed the claim. sentTo address Address that received the reward. rewardEpoch uint256 ID of the reward epoch where the reward was accrued. amount uint256 Amount of rewarded native tokens (wei). RewardClaimsEnabled # Defined in IFtsoRewardManager ( Docs , Source ). event RewardClaimsEnabled ( uint256 rewardEpochId ) Emitted when reward claims have been enabled. Parameters Type Description rewardEpochId uint256 First claimable reward epoch. RewardClaimsExpired # Defined in IFtsoRewardManager ( Docs , Source ). event RewardClaimsExpired ( uint256 rewardEpochId ) Unclaimed rewards have expired and are now inaccessible. getUnclaimedReward() can be used to retrieve more information. Parameters Type Description rewardEpochId uint256 ID of the reward epoch that has just expired. RewardsDistributed # Defined in IFtsoRewardManager ( Docs , Source ). event RewardsDistributed ( address ftso , uint256 epochId , address [] addresses , uint256 [] rewards ) Emitted every price epoch, when rewards have been distributed to each contributing data provider. Note that rewards are not claimable until the reward epoch finishes. Parameters Type Description ftso address Address of the FTSO that generated the rewards. epochId uint256 ID of the reward epoch where the rewards were accrued. addresses address[] Data provider addresses that have rewards to claim. rewards uint256[] Amounts available for claiming (wei). UnearnedRewardsAccrued # Defined in IFtsoRewardManager ( Docs , Source ). event UnearnedRewardsAccrued ( uint256 epochId , uint256 reward ) Emitted when rewards cannot be distributed during a reward epoch (for example, because the FTSO went into fallback mode) and they are accrued for later burning. Parameters Type Description epochId uint256 ID of the reward epoch where the reward was accrued. reward uint256 Total amount of accrued rewards (wei). Functions # active # Defined in IFtsoRewardManager ( Docs , Source ). function active ( ) external view returns ( bool ); Whether rewards can be claimed from this reward manager. autoClaim # Defined in IFtsoRewardManager ( Docs , Source ). function autoClaim ( address [] _rewardOwners , uint256 _rewardEpoch ) external ; Allows claiming rewards simultaneously for a list of reward owners and all unclaimed epochs before the specified one. This is meant as a convenience all-in-one reward claiming method to be used both by reward owners and registered executors . It performs a series of operations, besides claiming rewards: If a reward owner has enabled its Personal Delegation Account , rewards are also claimed for the PDA and the total claimed amount is sent to that PDA. Otherwise, the claimed amount is sent to the reward owner's account. Claimed amount is automatically wrapped through the WNat contract. If the caller is a registered executor with a non-zero fee, the fee is paid to the executor for each claimed address. Parameters Type Description _rewardOwners address[] List of reward owners to claim for. _rewardEpoch uint256 Last reward epoch ID to claim for. All previous epochs with pending rewards will be claimed too. claim # Defined in IFtsoRewardManager ( Docs , Source ). function claim ( address _rewardOwner , address payable _recipient , uint256 _rewardEpoch , bool _wrap ) external returns ( uint256 _rewardAmount ); Allows the caller to claim rewards for a reward owner. The caller does not have to be the owner of the rewards, but must be approved by the owner to claim on his behalf by using setClaimExecutors on the claimSetupManager . This function is intended to be used to claim rewards in case of delegation by percentage. Reverts if msg.sender is delegating by amount. Anybody can call this method, but rewards can only be sent to the reward owner, therefore no funds can be stolen. However, by limiting the authorized callers, the owner can control the timing of the calls. When the reward owner is the caller, rewards can be sent to any recipient set by setAllowedClaimRecipients on the claimSetupManager . The reward owner's Personal Delegation Account is always an authorized recipient. Parameters Type Description _rewardOwner address Address of the reward owner. _recipient address payable Address to transfer claimed rewards to. _rewardEpoch uint256 Last reward epoch to claim for. All previous epochs with pending rewards will be claimed too. _wrap bool Whether claimed rewards should be wrapped through the WNat contract before transferring them to the _recipient . This parameter is offered as a convenience. Returns Type Description _rewardAmount uint256 Total amount of claimed rewards (wei). claimFromDataProviders # Defined in IFtsoRewardManager ( Docs , Source ). function claimFromDataProviders ( address _rewardOwner , address payable _recipient , uint256 [] _rewardEpochs , address [] _dataProviders , bool _wrap ) external returns ( uint256 _rewardAmount ); Allows the caller to claim rewards for a reward owner from specific data providers. The caller does not have to be the owner of the rewards, but must be approved by the owner to claim on his behalf by using setClaimExecutors on the claimSetupManager . This function is intended to be used to claim rewards in case of delegation by amount (explicit delegation). Reverts if msg.sender is delegating by percentage. Anybody can call this method, but rewards can only be sent to the reward owner, therefore no funds can be stolen. However, by limiting the authorized callers, the owner can control the timing of the calls. When the reward owner is the caller, rewards can be sent to any recipient set by setAllowedClaimRecipients on the claimSetupManager . The reward owner's Personal Delegation Account is always an authorized recipient. Parameters Type Description _rewardOwner address Address of the reward owner. _recipient address payable Address to transfer claimed rewards to. _rewardEpochs uint256[] Array of reward epoch IDs to claim for. _dataProviders address[] Array of addresses of the data providers to claim the reward from. _wrap bool Whether claimed rewards should be wrapped through the WNat contract before transferring them to the _recipient . This parameter is offered as a convenience. Returns Type Description _rewardAmount uint256 Total amount of claimed rewards (wei). claimReward # Defined in IFtsoRewardManager ( Docs , Source ). function claimReward ( address payable _recipient , uint256 [] _rewardEpochs ) external returns ( uint256 _rewardAmount ); Allows a percentage delegator to claim rewards. This function is intended to be used to claim rewards in case of delegation by percentage. This function is deprecated : use claim instead. Reverts if msg.sender is delegating by amount. Claims for all unclaimed reward epochs to the 'max(_rewardEpochs)'. Retained for backward compatibility. Parameters Type Description _recipient address payable Address to transfer funds to. _rewardEpochs uint256[] Array of reward epoch numbers to claim for. Returns Type Description _rewardAmount uint256 Amount of total claimed rewards (wei). claimRewardFromDataProviders # Defined in IFtsoRewardManager ( Docs , Source ). function claimRewardFromDataProviders ( address payable _recipient , uint256 [] _rewardEpochs , address [] _dataProviders ) external returns ( uint256 _rewardAmount ); Allows the caller to claim rewards from specific data providers. This function is intended to be used to claim rewards in case of delegation by amount. This function is deprecated : use claimFromDataProviders instead. Parameters Type Description _recipient address payable Address to transfer funds to. _rewardEpochs uint256[] Array of reward epoch numbers to claim for. _dataProviders address[] Array of addresses of the data providers to claim the reward from. Returns Type Description _rewardAmount uint256 Total amount of claimed rewards (wei). getClaimedReward # Defined in IFtsoRewardManager ( Docs , Source ). function getClaimedReward ( uint256 _rewardEpoch , address _dataProvider , address _claimer ) external view returns ( bool _claimed , uint256 _amount ); Returns information on the rewards accrued by a reward owner from a specific data provider at a specific reward epoch. Parameters Type Description _rewardEpoch uint256 Reward epoch ID to query. _dataProvider address Address of the data provider to query. _claimer address Address of the reward owner to query. Returns Type Description _claimed bool Whether the reward has been claimed or not. _amount uint256 Accrued amount in wei. getCurrentRewardEpoch # Defined in IFtsoRewardManager ( Docs , Source ). function getCurrentRewardEpoch ( ) external view returns ( uint256 ); Returns the current reward epoch ID. getDataProviderCurrentFeePercentage # Defined in IFtsoRewardManager ( Docs , Source ). function getDataProviderCurrentFeePercentage ( address _dataProvider ) external view returns ( uint256 _feePercentageBIPS ); Returns the current fee percentage of a data provider. Parameters Type Description _dataProvider address Address of the queried data provider. Returns Type Description _feePercentageBIPS uint256 Fee percentage in BIPS. getDataProviderFeePercentage # Defined in IFtsoRewardManager ( Docs , Source ). function getDataProviderFeePercentage ( address _dataProvider , uint256 _rewardEpoch ) external view returns ( uint256 _feePercentageBIPS ); Returns the fee percentage of a data provider at a given reward epoch. Parameters Type Description _dataProvider address Address of the queried data provider. _rewardEpoch uint256 Reward epoch ID. Returns Type Description _feePercentageBIPS uint256 Fee percentage in BIPS. getDataProviderPerformanceInfo # Defined in IFtsoRewardManager ( Docs , Source ). function getDataProviderPerformanceInfo ( uint256 _rewardEpoch , address _dataProvider ) external view returns ( uint256 _rewardAmount , uint256 _votePowerIgnoringRevocation ); Returns information on rewards and vote power of a data provider at a given reward epoch. Parameters Type Description _rewardEpoch uint256 Reward epoch ID. _dataProvider address Address of the data provider to query. Returns Type Description _rewardAmount uint256 Amount of rewards (wei). _votePowerIgnoringRevocation uint256 Vote power, not including revocations. getDataProviderScheduledFeePercentageChanges # Defined in IFtsoRewardManager ( Docs , Source ). function getDataProviderScheduledFeePercentageChanges ( address _dataProvider ) external view returns ( uint256 [] _feePercentageBIPS , uint256 [] _validFromEpoch , bool [] _fixed ); Returns the scheduled fee percentage changes for a data provider. Parameters Type Description _dataProvider address Address of the queried data provider. Returns Type Description _feePercentageBIPS uint256[] Array of fee percentages in BIPS. _validFromEpoch uint256[] Array of block numbers from which the fee settings are effective. _fixed bool[] Array of boolean values indicating whether settings are subject to change or not. getEpochReward # Defined in IFtsoRewardManager ( Docs , Source ). function getEpochReward ( uint256 _rewardEpoch ) external view returns ( uint256 _totalReward , uint256 _claimedReward ); Returns information on an epoch's rewards. Parameters Type Description _rewardEpoch uint256 Reward epoch ID. Returns Type Description _totalReward uint256 Total amount of rewards accrued on that epoch, in wei. _claimedReward uint256 Total amount of rewards that have already been claimed, in wei. getEpochsWithClaimableRewards # Defined in IFtsoRewardManager ( Docs , Source ). function getEpochsWithClaimableRewards ( ) external view returns ( uint256 _startEpochId , uint256 _endEpochId ); Returns the reward epoch range for which rewards can be claimed. Rewards outside this range are unclaimable, either because they have expired or because the reward epoch is still ongoing. Returns Type Description _startEpochId uint256 The oldest epoch ID that allows reward claiming. _endEpochId uint256 The newest epoch ID that allows reward claiming. getEpochsWithUnclaimedRewards # Defined in IFtsoRewardManager ( Docs , Source ). function getEpochsWithUnclaimedRewards ( address _beneficiary ) external view returns ( uint256 [] _epochIds ); Returns the array of claimable epoch IDs for which the rewards of a reward owner have not yet been claimed. Parameters Type Description _beneficiary address Address of the reward owner to query. Reverts if it uses delegation by amount. Returns Type Description _epochIds uint256[] Array of epoch IDs. getInitialRewardEpoch # Defined in IFtsoRewardManager ( Docs , Source ). function getInitialRewardEpoch ( ) external view returns ( uint256 ); Returns the initial reward epoch ID for this reward manager contract. This corresponds to the oldest reward epoch with claimable rewards in the previous reward manager when this one took over. Set by governance through setInitialRewardData . getRewardEpochToExpireNext # Defined in IFtsoRewardManager ( Docs , Source ). function getRewardEpochToExpireNext ( ) external view returns ( uint256 ); Returns the reward epoch that will expire next once a new reward epoch starts. getRewardEpochVotePowerBlock # Defined in IFtsoRewardManager ( Docs , Source ). function getRewardEpochVotePowerBlock ( uint256 _rewardEpoch ) external view returns ( uint256 ); Returns the vote power block of a given reward epoch. Parameters Type Description _rewardEpoch uint256 Reward epoch ID. getStateOfRewards # Defined in IFtsoRewardManager ( Docs , Source ). function getStateOfRewards ( address _beneficiary , uint256 _rewardEpoch ) external view returns ( address [] _dataProviders , uint256 [] _rewardAmounts , bool [] _claimed , bool _claimable ); Returns the state of rewards for a given address at a specific reward epoch. Parameters Type Description _beneficiary address Address of the beneficiary to query. It can be a data provider or a delegator, for example. Reverts if the queried address is delegating by amount. _rewardEpoch uint256 Reward epoch ID to query. Returns Type Description _dataProviders address[] Array of addresses of data providers. _rewardAmounts uint256[] Array of reward amounts received from each provider, in wei. _claimed bool[] Array of boolean values indicating whether each reward has been claimed or not. _claimable bool Boolean value indicating whether rewards are claimable or not. getStateOfRewardsFromDataProviders # Defined in IFtsoRewardManager ( Docs , Source ). function getStateOfRewardsFromDataProviders ( address _beneficiary , uint256 _rewardEpoch , address [] _dataProviders ) external view returns ( uint256 [] _rewardAmounts , bool [] _claimed , bool _claimable ); Returns the state of rewards for a given address coming from a specific set of data providers, at a specific reward epoch. Parameters Type Description _beneficiary address Address of beneficiary to query. _rewardEpoch uint256 Reward epoch ID to query. _dataProviders address[] Array of addresses of the data providers to query. Returns Type Description _rewardAmounts uint256[] Array of reward amounts received from each provider, in wei. _claimed bool[] Array of boolean values indicating whether each reward has been claimed or not. _claimable bool Boolean value indicating whether rewards are claimable or not. nextClaimableRewardEpoch # Defined in IFtsoRewardManager ( Docs , Source ). function nextClaimableRewardEpoch ( address _rewardOwner ) external view returns ( uint256 ); Returns the next claimable reward epoch for a reward owner. Parameters Type Description _rewardOwner address Address of the reward owner to query. setDataProviderFeePercentage # Defined in IFtsoRewardManager ( Docs , Source ). function setDataProviderFeePercentage ( uint256 _feePercentageBIPS ) external returns ( uint256 _validFromEpoch ); Sets the fee a data provider keeps from all delegations. Takes effect after feeValueUpdateOffset reward epochs have elapsed. When called multiple times inside the same reward epoch, only the last value remains. Parameters Type Description _feePercentageBIPS uint256 Fee percentage in BIPS. Returns Type Description _validFromEpoch uint256 Reward epoch number when the new fee percentage will become effective.","title":"IFtsoRewardManager"},{"location":"apis/smart-contracts/IFtsoRewardManager/#ct_iftsorewardmanager","text":"Source Interface for the FtsoRewardManager contract.","title":"IFtsoRewardManager"},{"location":"apis/smart-contracts/IFtsoRewardManager/#events","text":"","title":"Events"},{"location":"apis/smart-contracts/IFtsoRewardManager/#ev_feepercentagechanged","text":"Defined in IFtsoRewardManager ( Docs , Source ). event FeePercentageChanged ( address dataProvider , uint256 value , uint256 validFromEpoch ) Emitted when a data provider changes its fee. Parameters Type Description dataProvider address Address of the data provider. value uint256 New fee, in BIPS. validFromEpoch uint256 Epoch ID where the new fee takes effect.","title":"FeePercentageChanged"},{"location":"apis/smart-contracts/IFtsoRewardManager/#ev_ftsorewardmanageractivated","text":"Defined in IFtsoRewardManager ( Docs , Source ). event FtsoRewardManagerActivated ( address ftsoRewardManager ) Emitted when the reward manager contract is activated. Parameters Type Description ftsoRewardManager address The reward manager contract.","title":"FtsoRewardManagerActivated"},{"location":"apis/smart-contracts/IFtsoRewardManager/#ev_ftsorewardmanagerdeactivated","text":"Defined in IFtsoRewardManager ( Docs , Source ). event FtsoRewardManagerDeactivated ( address ftsoRewardManager ) Emitted when the reward manager contract is deactivated. Parameters Type Description ftsoRewardManager address The reward manager contract.","title":"FtsoRewardManagerDeactivated"},{"location":"apis/smart-contracts/IFtsoRewardManager/#ev_rewardclaimed","text":"Defined in IFtsoRewardManager ( Docs , Source ). event RewardClaimed ( address dataProvider , address whoClaimed , address sentTo , uint256 rewardEpoch , uint256 amount ) Emitted when a data provider claims its FTSO rewards. Parameters Type Description dataProvider address Address of the data provider that accrued the reward. whoClaimed address Address that actually performed the claim. sentTo address Address that received the reward. rewardEpoch uint256 ID of the reward epoch where the reward was accrued. amount uint256 Amount of rewarded native tokens (wei).","title":"RewardClaimed"},{"location":"apis/smart-contracts/IFtsoRewardManager/#ev_rewardclaimsenabled","text":"Defined in IFtsoRewardManager ( Docs , Source ). event RewardClaimsEnabled ( uint256 rewardEpochId ) Emitted when reward claims have been enabled. Parameters Type Description rewardEpochId uint256 First claimable reward epoch.","title":"RewardClaimsEnabled"},{"location":"apis/smart-contracts/IFtsoRewardManager/#ev_rewardclaimsexpired","text":"Defined in IFtsoRewardManager ( Docs , Source ). event RewardClaimsExpired ( uint256 rewardEpochId ) Unclaimed rewards have expired and are now inaccessible. getUnclaimedReward() can be used to retrieve more information. Parameters Type Description rewardEpochId uint256 ID of the reward epoch that has just expired.","title":"RewardClaimsExpired"},{"location":"apis/smart-contracts/IFtsoRewardManager/#ev_rewardsdistributed","text":"Defined in IFtsoRewardManager ( Docs , Source ). event RewardsDistributed ( address ftso , uint256 epochId , address [] addresses , uint256 [] rewards ) Emitted every price epoch, when rewards have been distributed to each contributing data provider. Note that rewards are not claimable until the reward epoch finishes. Parameters Type Description ftso address Address of the FTSO that generated the rewards. epochId uint256 ID of the reward epoch where the rewards were accrued. addresses address[] Data provider addresses that have rewards to claim. rewards uint256[] Amounts available for claiming (wei).","title":"RewardsDistributed"},{"location":"apis/smart-contracts/IFtsoRewardManager/#ev_unearnedrewardsaccrued","text":"Defined in IFtsoRewardManager ( Docs , Source ). event UnearnedRewardsAccrued ( uint256 epochId , uint256 reward ) Emitted when rewards cannot be distributed during a reward epoch (for example, because the FTSO went into fallback mode) and they are accrued for later burning. Parameters Type Description epochId uint256 ID of the reward epoch where the reward was accrued. reward uint256 Total amount of accrued rewards (wei).","title":"UnearnedRewardsAccrued"},{"location":"apis/smart-contracts/IFtsoRewardManager/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IFtsoRewardManager/#fn_active_02fb0c5e","text":"Defined in IFtsoRewardManager ( Docs , Source ). function active ( ) external view returns ( bool ); Whether rewards can be claimed from this reward manager.","title":"active"},{"location":"apis/smart-contracts/IFtsoRewardManager/#fn_autoclaim_8dc305fa","text":"Defined in IFtsoRewardManager ( Docs , Source ). function autoClaim ( address [] _rewardOwners , uint256 _rewardEpoch ) external ; Allows claiming rewards simultaneously for a list of reward owners and all unclaimed epochs before the specified one. This is meant as a convenience all-in-one reward claiming method to be used both by reward owners and registered executors . It performs a series of operations, besides claiming rewards: If a reward owner has enabled its Personal Delegation Account , rewards are also claimed for the PDA and the total claimed amount is sent to that PDA. Otherwise, the claimed amount is sent to the reward owner's account. Claimed amount is automatically wrapped through the WNat contract. If the caller is a registered executor with a non-zero fee, the fee is paid to the executor for each claimed address. Parameters Type Description _rewardOwners address[] List of reward owners to claim for. _rewardEpoch uint256 Last reward epoch ID to claim for. All previous epochs with pending rewards will be claimed too.","title":"autoClaim"},{"location":"apis/smart-contracts/IFtsoRewardManager/#fn_claim_b2c12192","text":"Defined in IFtsoRewardManager ( Docs , Source ). function claim ( address _rewardOwner , address payable _recipient , uint256 _rewardEpoch , bool _wrap ) external returns ( uint256 _rewardAmount ); Allows the caller to claim rewards for a reward owner. The caller does not have to be the owner of the rewards, but must be approved by the owner to claim on his behalf by using setClaimExecutors on the claimSetupManager . This function is intended to be used to claim rewards in case of delegation by percentage. Reverts if msg.sender is delegating by amount. Anybody can call this method, but rewards can only be sent to the reward owner, therefore no funds can be stolen. However, by limiting the authorized callers, the owner can control the timing of the calls. When the reward owner is the caller, rewards can be sent to any recipient set by setAllowedClaimRecipients on the claimSetupManager . The reward owner's Personal Delegation Account is always an authorized recipient. Parameters Type Description _rewardOwner address Address of the reward owner. _recipient address payable Address to transfer claimed rewards to. _rewardEpoch uint256 Last reward epoch to claim for. All previous epochs with pending rewards will be claimed too. _wrap bool Whether claimed rewards should be wrapped through the WNat contract before transferring them to the _recipient . This parameter is offered as a convenience. Returns Type Description _rewardAmount uint256 Total amount of claimed rewards (wei).","title":"claim"},{"location":"apis/smart-contracts/IFtsoRewardManager/#fn_claimfromdataproviders_21bb25af","text":"Defined in IFtsoRewardManager ( Docs , Source ). function claimFromDataProviders ( address _rewardOwner , address payable _recipient , uint256 [] _rewardEpochs , address [] _dataProviders , bool _wrap ) external returns ( uint256 _rewardAmount ); Allows the caller to claim rewards for a reward owner from specific data providers. The caller does not have to be the owner of the rewards, but must be approved by the owner to claim on his behalf by using setClaimExecutors on the claimSetupManager . This function is intended to be used to claim rewards in case of delegation by amount (explicit delegation). Reverts if msg.sender is delegating by percentage. Anybody can call this method, but rewards can only be sent to the reward owner, therefore no funds can be stolen. However, by limiting the authorized callers, the owner can control the timing of the calls. When the reward owner is the caller, rewards can be sent to any recipient set by setAllowedClaimRecipients on the claimSetupManager . The reward owner's Personal Delegation Account is always an authorized recipient. Parameters Type Description _rewardOwner address Address of the reward owner. _recipient address payable Address to transfer claimed rewards to. _rewardEpochs uint256[] Array of reward epoch IDs to claim for. _dataProviders address[] Array of addresses of the data providers to claim the reward from. _wrap bool Whether claimed rewards should be wrapped through the WNat contract before transferring them to the _recipient . This parameter is offered as a convenience. Returns Type Description _rewardAmount uint256 Total amount of claimed rewards (wei).","title":"claimFromDataProviders"},{"location":"apis/smart-contracts/IFtsoRewardManager/#fn_claimreward_b2af870a","text":"Defined in IFtsoRewardManager ( Docs , Source ). function claimReward ( address payable _recipient , uint256 [] _rewardEpochs ) external returns ( uint256 _rewardAmount ); Allows a percentage delegator to claim rewards. This function is intended to be used to claim rewards in case of delegation by percentage. This function is deprecated : use claim instead. Reverts if msg.sender is delegating by amount. Claims for all unclaimed reward epochs to the 'max(_rewardEpochs)'. Retained for backward compatibility. Parameters Type Description _recipient address payable Address to transfer funds to. _rewardEpochs uint256[] Array of reward epoch numbers to claim for. Returns Type Description _rewardAmount uint256 Amount of total claimed rewards (wei).","title":"claimReward"},{"location":"apis/smart-contracts/IFtsoRewardManager/#fn_claimrewardfromdataproviders_d20bb542","text":"Defined in IFtsoRewardManager ( Docs , Source ). function claimRewardFromDataProviders ( address payable _recipient , uint256 [] _rewardEpochs , address [] _dataProviders ) external returns ( uint256 _rewardAmount ); Allows the caller to claim rewards from specific data providers. This function is intended to be used to claim rewards in case of delegation by amount. This function is deprecated : use claimFromDataProviders instead. Parameters Type Description _recipient address payable Address to transfer funds to. _rewardEpochs uint256[] Array of reward epoch numbers to claim for. _dataProviders address[] Array of addresses of the data providers to claim the reward from. Returns Type Description _rewardAmount uint256 Total amount of claimed rewards (wei).","title":"claimRewardFromDataProviders"},{"location":"apis/smart-contracts/IFtsoRewardManager/#fn_getclaimedreward_85b4c538","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getClaimedReward ( uint256 _rewardEpoch , address _dataProvider , address _claimer ) external view returns ( bool _claimed , uint256 _amount ); Returns information on the rewards accrued by a reward owner from a specific data provider at a specific reward epoch. Parameters Type Description _rewardEpoch uint256 Reward epoch ID to query. _dataProvider address Address of the data provider to query. _claimer address Address of the reward owner to query. Returns Type Description _claimed bool Whether the reward has been claimed or not. _amount uint256 Accrued amount in wei.","title":"getClaimedReward"},{"location":"apis/smart-contracts/IFtsoRewardManager/#fn_getcurrentrewardepoch_e7c830d4","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getCurrentRewardEpoch ( ) external view returns ( uint256 ); Returns the current reward epoch ID.","title":"getCurrentRewardEpoch"},{"location":"apis/smart-contracts/IFtsoRewardManager/#fn_getdataprovidercurrentfeepercentage_cfbcd25f","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getDataProviderCurrentFeePercentage ( address _dataProvider ) external view returns ( uint256 _feePercentageBIPS ); Returns the current fee percentage of a data provider. Parameters Type Description _dataProvider address Address of the queried data provider. Returns Type Description _feePercentageBIPS uint256 Fee percentage in BIPS.","title":"getDataProviderCurrentFeePercentage"},{"location":"apis/smart-contracts/IFtsoRewardManager/#fn_getdataproviderfeepercentage_961c00ed","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getDataProviderFeePercentage ( address _dataProvider , uint256 _rewardEpoch ) external view returns ( uint256 _feePercentageBIPS ); Returns the fee percentage of a data provider at a given reward epoch. Parameters Type Description _dataProvider address Address of the queried data provider. _rewardEpoch uint256 Reward epoch ID. Returns Type Description _feePercentageBIPS uint256 Fee percentage in BIPS.","title":"getDataProviderFeePercentage"},{"location":"apis/smart-contracts/IFtsoRewardManager/#fn_getdataproviderperformanceinfo_eb82dd7f","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getDataProviderPerformanceInfo ( uint256 _rewardEpoch , address _dataProvider ) external view returns ( uint256 _rewardAmount , uint256 _votePowerIgnoringRevocation ); Returns information on rewards and vote power of a data provider at a given reward epoch. Parameters Type Description _rewardEpoch uint256 Reward epoch ID. _dataProvider address Address of the data provider to query. Returns Type Description _rewardAmount uint256 Amount of rewards (wei). _votePowerIgnoringRevocation uint256 Vote power, not including revocations.","title":"getDataProviderPerformanceInfo"},{"location":"apis/smart-contracts/IFtsoRewardManager/#fn_getdataproviderscheduledfeepercentagechanges_33b7971e","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getDataProviderScheduledFeePercentageChanges ( address _dataProvider ) external view returns ( uint256 [] _feePercentageBIPS , uint256 [] _validFromEpoch , bool [] _fixed ); Returns the scheduled fee percentage changes for a data provider. Parameters Type Description _dataProvider address Address of the queried data provider. Returns Type Description _feePercentageBIPS uint256[] Array of fee percentages in BIPS. _validFromEpoch uint256[] Array of block numbers from which the fee settings are effective. _fixed bool[] Array of boolean values indicating whether settings are subject to change or not.","title":"getDataProviderScheduledFeePercentageChanges"},{"location":"apis/smart-contracts/IFtsoRewardManager/#fn_getepochreward_d418634a","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getEpochReward ( uint256 _rewardEpoch ) external view returns ( uint256 _totalReward , uint256 _claimedReward ); Returns information on an epoch's rewards. Parameters Type Description _rewardEpoch uint256 Reward epoch ID. Returns Type Description _totalReward uint256 Total amount of rewards accrued on that epoch, in wei. _claimedReward uint256 Total amount of rewards that have already been claimed, in wei.","title":"getEpochReward"},{"location":"apis/smart-contracts/IFtsoRewardManager/#fn_getepochswithclaimablerewards_0441218e","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getEpochsWithClaimableRewards ( ) external view returns ( uint256 _startEpochId , uint256 _endEpochId ); Returns the reward epoch range for which rewards can be claimed. Rewards outside this range are unclaimable, either because they have expired or because the reward epoch is still ongoing. Returns Type Description _startEpochId uint256 The oldest epoch ID that allows reward claiming. _endEpochId uint256 The newest epoch ID that allows reward claiming.","title":"getEpochsWithClaimableRewards"},{"location":"apis/smart-contracts/IFtsoRewardManager/#fn_getepochswithunclaimedrewards_b4a2043d","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getEpochsWithUnclaimedRewards ( address _beneficiary ) external view returns ( uint256 [] _epochIds ); Returns the array of claimable epoch IDs for which the rewards of a reward owner have not yet been claimed. Parameters Type Description _beneficiary address Address of the reward owner to query. Reverts if it uses delegation by amount. Returns Type Description _epochIds uint256[] Array of epoch IDs.","title":"getEpochsWithUnclaimedRewards"},{"location":"apis/smart-contracts/IFtsoRewardManager/#fn_getinitialrewardepoch_3123b7d8","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getInitialRewardEpoch ( ) external view returns ( uint256 ); Returns the initial reward epoch ID for this reward manager contract. This corresponds to the oldest reward epoch with claimable rewards in the previous reward manager when this one took over. Set by governance through setInitialRewardData .","title":"getInitialRewardEpoch"},{"location":"apis/smart-contracts/IFtsoRewardManager/#fn_getrewardepochtoexpirenext_3e7ff857","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getRewardEpochToExpireNext ( ) external view returns ( uint256 ); Returns the reward epoch that will expire next once a new reward epoch starts.","title":"getRewardEpochToExpireNext"},{"location":"apis/smart-contracts/IFtsoRewardManager/#fn_getrewardepochvotepowerblock_f2edab5a","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getRewardEpochVotePowerBlock ( uint256 _rewardEpoch ) external view returns ( uint256 ); Returns the vote power block of a given reward epoch. Parameters Type Description _rewardEpoch uint256 Reward epoch ID.","title":"getRewardEpochVotePowerBlock"},{"location":"apis/smart-contracts/IFtsoRewardManager/#fn_getstateofrewards_a4472c10","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getStateOfRewards ( address _beneficiary , uint256 _rewardEpoch ) external view returns ( address [] _dataProviders , uint256 [] _rewardAmounts , bool [] _claimed , bool _claimable ); Returns the state of rewards for a given address at a specific reward epoch. Parameters Type Description _beneficiary address Address of the beneficiary to query. It can be a data provider or a delegator, for example. Reverts if the queried address is delegating by amount. _rewardEpoch uint256 Reward epoch ID to query. Returns Type Description _dataProviders address[] Array of addresses of data providers. _rewardAmounts uint256[] Array of reward amounts received from each provider, in wei. _claimed bool[] Array of boolean values indicating whether each reward has been claimed or not. _claimable bool Boolean value indicating whether rewards are claimable or not.","title":"getStateOfRewards"},{"location":"apis/smart-contracts/IFtsoRewardManager/#fn_getstateofrewardsfromdataproviders_e416b7e1","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getStateOfRewardsFromDataProviders ( address _beneficiary , uint256 _rewardEpoch , address [] _dataProviders ) external view returns ( uint256 [] _rewardAmounts , bool [] _claimed , bool _claimable ); Returns the state of rewards for a given address coming from a specific set of data providers, at a specific reward epoch. Parameters Type Description _beneficiary address Address of beneficiary to query. _rewardEpoch uint256 Reward epoch ID to query. _dataProviders address[] Array of addresses of the data providers to query. Returns Type Description _rewardAmounts uint256[] Array of reward amounts received from each provider, in wei. _claimed bool[] Array of boolean values indicating whether each reward has been claimed or not. _claimable bool Boolean value indicating whether rewards are claimable or not.","title":"getStateOfRewardsFromDataProviders"},{"location":"apis/smart-contracts/IFtsoRewardManager/#fn_nextclaimablerewardepoch_69b91b59","text":"Defined in IFtsoRewardManager ( Docs , Source ). function nextClaimableRewardEpoch ( address _rewardOwner ) external view returns ( uint256 ); Returns the next claimable reward epoch for a reward owner. Parameters Type Description _rewardOwner address Address of the reward owner to query.","title":"nextClaimableRewardEpoch"},{"location":"apis/smart-contracts/IFtsoRewardManager/#fn_setdataproviderfeepercentage_16e69328","text":"Defined in IFtsoRewardManager ( Docs , Source ). function setDataProviderFeePercentage ( uint256 _feePercentageBIPS ) external returns ( uint256 _validFromEpoch ); Sets the fee a data provider keeps from all delegations. Takes effect after feeValueUpdateOffset reward epochs have elapsed. When called multiple times inside the same reward epoch, only the last value remains. Parameters Type Description _feePercentageBIPS uint256 Fee percentage in BIPS. Returns Type Description _validFromEpoch uint256 Reward epoch number when the new fee percentage will become effective.","title":"setDataProviderFeePercentage"},{"location":"apis/smart-contracts/IGovernanceSettings/","text":"IGovernanceSettings # Source Interface for the GovernanceSettings that hold the Flare governance address and its timelock. All governance calls are delayed by the timelock specified in this contract. NOTE : This contract enables updating the governance address and timelock only by hard-forking the network, meaning only by updating validator code. Functions # getExecutors # Defined in IGovernanceSettings ( Docs , Source ). function getExecutors ( ) external view returns ( address [] _addresses ); Gets the addresses of the accounts that are allowed to execute the timelocked governance calls, once the timelock period expires. Executors can be changed without a hard fork, via a normal governance call. Returns Type Description _addresses address[] Array of executor addresses. getGovernanceAddress # Defined in IGovernanceSettings ( Docs , Source ). function getGovernanceAddress ( ) external view returns ( address _address ); Gets the governance account address. The governance address can only be changed by a hard fork. Returns Type Description _address address The governance account address. getTimelock # Defined in IGovernanceSettings ( Docs , Source ). function getTimelock ( ) external view returns ( uint256 _timelock ); Gets the time in seconds that must pass between a governance call and its execution. The timelock value can only be changed by a hard fork. Returns Type Description _timelock uint256 Time in seconds that passes between the governance call and execution. isExecutor # Defined in IGovernanceSettings ( Docs , Source ). function isExecutor ( address _address ) external view returns ( bool ); Checks whether an address is one of the allowed executors. See getExecutors . Parameters Type Description _address address The address to check. Returns Type Description [0] bool True if _address is in the executors list.","title":"IGovernanceSettings"},{"location":"apis/smart-contracts/IGovernanceSettings/#ct_igovernancesettings","text":"Source Interface for the GovernanceSettings that hold the Flare governance address and its timelock. All governance calls are delayed by the timelock specified in this contract. NOTE : This contract enables updating the governance address and timelock only by hard-forking the network, meaning only by updating validator code.","title":"IGovernanceSettings"},{"location":"apis/smart-contracts/IGovernanceSettings/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IGovernanceSettings/#fn_getexecutors_ef09e78f","text":"Defined in IGovernanceSettings ( Docs , Source ). function getExecutors ( ) external view returns ( address [] _addresses ); Gets the addresses of the accounts that are allowed to execute the timelocked governance calls, once the timelock period expires. Executors can be changed without a hard fork, via a normal governance call. Returns Type Description _addresses address[] Array of executor addresses.","title":"getExecutors"},{"location":"apis/smart-contracts/IGovernanceSettings/#fn_getgovernanceaddress_73252494","text":"Defined in IGovernanceSettings ( Docs , Source ). function getGovernanceAddress ( ) external view returns ( address _address ); Gets the governance account address. The governance address can only be changed by a hard fork. Returns Type Description _address address The governance account address.","title":"getGovernanceAddress"},{"location":"apis/smart-contracts/IGovernanceSettings/#fn_gettimelock_6221a54b","text":"Defined in IGovernanceSettings ( Docs , Source ). function getTimelock ( ) external view returns ( uint256 _timelock ); Gets the time in seconds that must pass between a governance call and its execution. The timelock value can only be changed by a hard fork. Returns Type Description _timelock uint256 Time in seconds that passes between the governance call and execution.","title":"getTimelock"},{"location":"apis/smart-contracts/IGovernanceSettings/#fn_isexecutor_debfda30","text":"Defined in IGovernanceSettings ( Docs , Source ). function isExecutor ( address _address ) external view returns ( bool ); Checks whether an address is one of the allowed executors. See getExecutors . Parameters Type Description _address address The address to check. Returns Type Description [0] bool True if _address is in the executors list.","title":"isExecutor"},{"location":"apis/smart-contracts/IGovernanceVotePower/","text":"IGovernanceVotePower # Source Interface for contracts delegating their governance vote power. Functions # delegate # Defined in IGovernanceVotePower ( Docs , Source ). function delegate ( address _to ) external ; Delegates all governance vote power of msg.sender to address _to . Parameters Type Description _to address The address of the recipient. getDelegateOfAt # Defined in IGovernanceVotePower ( Docs , Source ). function getDelegateOfAt ( address _who , uint256 _blockNumber ) external view returns ( address ); Gets the address an account is delegating its governance vote power to, at a given block number. Parameters Type Description _who address The address being queried. _blockNumber uint256 The block number at which to fetch the address. Returns Type Description [0] address Address where _who was delegating its governance vote power at block _blockNumber . getDelegateOfAtNow # Defined in IGovernanceVotePower ( Docs , Source ). function getDelegateOfAtNow ( address _who ) external view returns ( address ); Gets the address an account is delegating its governance vote power to, at the latest block number. Parameters Type Description _who address The address being queried. Returns Type Description [0] address Address where _who is currently delegating its governance vote power. getVotes # Defined in IGovernanceVotePower ( Docs , Source ). function getVotes ( address _who ) external view returns ( uint256 ); Gets the governance vote power of an address at the latest block, including all delegations made to it. Parameters Type Description _who address The address being queried. Returns Type Description [0] uint256 Governance vote power of account at the lastest block. undelegate # Defined in IGovernanceVotePower ( Docs , Source ). function undelegate ( ) external ; Undelegates all governance vote power of msg.sender . votePowerOfAt # Defined in IGovernanceVotePower ( Docs , Source ). function votePowerOfAt ( address _who , uint256 _blockNumber ) external view returns ( uint256 ); Gets the governance vote power of an address at a given block number, including all delegations made to it. Parameters Type Description _who address The address being queried. _blockNumber uint256 The block number at which to fetch the vote power. Returns Type Description [0] uint256 Governance vote power of _who at _blockNumber .","title":"IGovernanceVotePower"},{"location":"apis/smart-contracts/IGovernanceVotePower/#ct_igovernancevotepower","text":"Source Interface for contracts delegating their governance vote power.","title":"IGovernanceVotePower"},{"location":"apis/smart-contracts/IGovernanceVotePower/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IGovernanceVotePower/#fn_delegate_5c19a95c","text":"Defined in IGovernanceVotePower ( Docs , Source ). function delegate ( address _to ) external ; Delegates all governance vote power of msg.sender to address _to . Parameters Type Description _to address The address of the recipient.","title":"delegate"},{"location":"apis/smart-contracts/IGovernanceVotePower/#fn_getdelegateofat_3c028e9d","text":"Defined in IGovernanceVotePower ( Docs , Source ). function getDelegateOfAt ( address _who , uint256 _blockNumber ) external view returns ( address ); Gets the address an account is delegating its governance vote power to, at a given block number. Parameters Type Description _who address The address being queried. _blockNumber uint256 The block number at which to fetch the address. Returns Type Description [0] address Address where _who was delegating its governance vote power at block _blockNumber .","title":"getDelegateOfAt"},{"location":"apis/smart-contracts/IGovernanceVotePower/#fn_getdelegateofatnow_b3e871ee","text":"Defined in IGovernanceVotePower ( Docs , Source ). function getDelegateOfAtNow ( address _who ) external view returns ( address ); Gets the address an account is delegating its governance vote power to, at the latest block number. Parameters Type Description _who address The address being queried. Returns Type Description [0] address Address where _who is currently delegating its governance vote power.","title":"getDelegateOfAtNow"},{"location":"apis/smart-contracts/IGovernanceVotePower/#fn_getvotes_9ab24eb0","text":"Defined in IGovernanceVotePower ( Docs , Source ). function getVotes ( address _who ) external view returns ( uint256 ); Gets the governance vote power of an address at the latest block, including all delegations made to it. Parameters Type Description _who address The address being queried. Returns Type Description [0] uint256 Governance vote power of account at the lastest block.","title":"getVotes"},{"location":"apis/smart-contracts/IGovernanceVotePower/#fn_undelegate_92ab89bb","text":"Defined in IGovernanceVotePower ( Docs , Source ). function undelegate ( ) external ; Undelegates all governance vote power of msg.sender .","title":"undelegate"},{"location":"apis/smart-contracts/IGovernanceVotePower/#fn_votepowerofat_92bfe6d8","text":"Defined in IGovernanceVotePower ( Docs , Source ). function votePowerOfAt ( address _who , uint256 _blockNumber ) external view returns ( uint256 ); Gets the governance vote power of an address at a given block number, including all delegations made to it. Parameters Type Description _who address The address being queried. _blockNumber uint256 The block number at which to fetch the vote power. Returns Type Description [0] uint256 Governance vote power of _who at _blockNumber .","title":"votePowerOfAt"},{"location":"apis/smart-contracts/IIAddressUpdatable/","text":"IIAddressUpdatable # Source Internal interface for contracts that depend on other contracts whose addresses can change. See AddressUpdatable . Functions # updateContractAddresses # Defined in IIAddressUpdatable ( Docs , Source ). function updateContractAddresses ( bytes32 [] _contractNameHashes , address [] _contractAddresses ) external ; Updates contract addresses. Can only be called from the AddressUpdater contract typically set at construction time. Parameters Type Description _contractNameHashes bytes32[] List of keccak256(abi.encode(...)) contract names. _contractAddresses address[] List of contract addresses corresponding to the contract names.","title":"IIAddressUpdatable"},{"location":"apis/smart-contracts/IIAddressUpdatable/#ct_iiaddressupdatable","text":"Source Internal interface for contracts that depend on other contracts whose addresses can change. See AddressUpdatable .","title":"IIAddressUpdatable"},{"location":"apis/smart-contracts/IIAddressUpdatable/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IIAddressUpdatable/#fn_updatecontractaddresses_b00c0b76","text":"Defined in IIAddressUpdatable ( Docs , Source ). function updateContractAddresses ( bytes32 [] _contractNameHashes , address [] _contractAddresses ) external ; Updates contract addresses. Can only be called from the AddressUpdater contract typically set at construction time. Parameters Type Description _contractNameHashes bytes32[] List of keccak256(abi.encode(...)) contract names. _contractAddresses address[] List of contract addresses corresponding to the contract names.","title":"updateContractAddresses"},{"location":"apis/smart-contracts/IIAddressUpdater/","text":"IIAddressUpdater # Source Internal interface for AddressUpdater . Functions # getContractAddress # Defined in IIAddressUpdater ( Docs , Source ). function getContractAddress ( string _name ) external view returns ( address ); Returns contract address for the given name, which might be address(0). Parameters Type Description _name string Name of the contract to query. Returns Type Description [0] address Current address for the queried contract. getContractAddressByHash # Defined in IIAddressUpdater ( Docs , Source ). function getContractAddressByHash ( bytes32 _nameHash ) external view returns ( address ); Returns contract address for the given name hash, which might be address(0). Parameters Type Description _nameHash bytes32 Hash of the contract name: keccak256(abi.encode(name)) Returns Type Description [0] address Current address for the queried contract. getContractAddresses # Defined in IIAddressUpdater ( Docs , Source ). function getContractAddresses ( string [] _names ) external view returns ( address []); Returns contract addresses for the given names, which might be address(0). Parameters Type Description _names string[] Names of the contracts to query. Returns Type Description [0] address[] Current addresses for the queried contracts. getContractAddressesByHash # Defined in IIAddressUpdater ( Docs , Source ). function getContractAddressesByHash ( bytes32 [] _nameHashes ) external view returns ( address []); Returns contract addresses for the given name hashes, which might be address(0). Parameters Type Description _nameHashes bytes32[] Hashes of the contract names: keccak256(abi.encode(name)) Returns Type Description [0] address[] Current addresses for the queried contracts. getContractNamesAndAddresses # Defined in IIAddressUpdater ( Docs , Source ). function getContractNamesAndAddresses ( ) external view returns ( string [] _contractNames , address [] _contractAddresses ); Returns all contract names and corresponding addresses currently being tracked. Returns Type Description _contractNames string[] Array of contract names. _contractAddresses address[] Array of contract addresses.","title":"IIAddressUpdater"},{"location":"apis/smart-contracts/IIAddressUpdater/#ct_iiaddressupdater","text":"Source Internal interface for AddressUpdater .","title":"IIAddressUpdater"},{"location":"apis/smart-contracts/IIAddressUpdater/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IIAddressUpdater/#fn_getcontractaddress_04433bbc","text":"Defined in IIAddressUpdater ( Docs , Source ). function getContractAddress ( string _name ) external view returns ( address ); Returns contract address for the given name, which might be address(0). Parameters Type Description _name string Name of the contract to query. Returns Type Description [0] address Current address for the queried contract.","title":"getContractAddress"},{"location":"apis/smart-contracts/IIAddressUpdater/#fn_getcontractaddressbyhash_159354a2","text":"Defined in IIAddressUpdater ( Docs , Source ). function getContractAddressByHash ( bytes32 _nameHash ) external view returns ( address ); Returns contract address for the given name hash, which might be address(0). Parameters Type Description _nameHash bytes32 Hash of the contract name: keccak256(abi.encode(name)) Returns Type Description [0] address Current address for the queried contract.","title":"getContractAddressByHash"},{"location":"apis/smart-contracts/IIAddressUpdater/#fn_getcontractaddresses_ee6f63c3","text":"Defined in IIAddressUpdater ( Docs , Source ). function getContractAddresses ( string [] _names ) external view returns ( address []); Returns contract addresses for the given names, which might be address(0). Parameters Type Description _names string[] Names of the contracts to query. Returns Type Description [0] address[] Current addresses for the queried contracts.","title":"getContractAddresses"},{"location":"apis/smart-contracts/IIAddressUpdater/#fn_getcontractaddressesbyhash_5e11e2d1","text":"Defined in IIAddressUpdater ( Docs , Source ). function getContractAddressesByHash ( bytes32 [] _nameHashes ) external view returns ( address []); Returns contract addresses for the given name hashes, which might be address(0). Parameters Type Description _nameHashes bytes32[] Hashes of the contract names: keccak256(abi.encode(name)) Returns Type Description [0] address[] Current addresses for the queried contracts.","title":"getContractAddressesByHash"},{"location":"apis/smart-contracts/IIAddressUpdater/#fn_getcontractnamesandaddresses_2f26c5c3","text":"Defined in IIAddressUpdater ( Docs , Source ). function getContractNamesAndAddresses ( ) external view returns ( string [] _contractNames , address [] _contractAddresses ); Returns all contract names and corresponding addresses currently being tracked. Returns Type Description _contractNames string[] Array of contract names. _contractAddresses address[] Array of contract addresses.","title":"getContractNamesAndAddresses"},{"location":"apis/smart-contracts/IIClaimSetupManager/","text":"IIClaimSetupManager # Source | Inherits from IClaimSetupManager Internal interface for the ClaimSetupManager contract. Events # AllowedClaimRecipientsChanged # Defined in IClaimSetupManager ( Docs , Source ). event AllowedClaimRecipientsChanged ( address owner , address [] recipients ) ClaimExecutorFeeValueChanged # Defined in IClaimSetupManager ( Docs , Source ). event ClaimExecutorFeeValueChanged ( address executor , uint256 validFromRewardEpoch , uint256 feeValueWei ) ClaimExecutorsChanged # Defined in IClaimSetupManager ( Docs , Source ). event ClaimExecutorsChanged ( address owner , address [] executors ) DelegationAccountCreated # Defined in IClaimSetupManager ( Docs , Source ). event DelegationAccountCreated ( address owner , contract IDelegationAccount delegationAccount ) DelegationAccountUpdated # Defined in IClaimSetupManager ( Docs , Source ). event DelegationAccountUpdated ( address owner , contract IDelegationAccount delegationAccount , bool enabled ) ExecutorRegistered # Defined in IClaimSetupManager ( Docs , Source ). event ExecutorRegistered ( address executor ) ExecutorUnregistered # Defined in IClaimSetupManager ( Docs , Source ). event ExecutorUnregistered ( address executor , uint256 validFromRewardEpoch ) MaxFeeSet # Defined in IClaimSetupManager ( Docs , Source ). event MaxFeeSet ( uint256 maxFeeValueWei ) MinFeeSet # Defined in IClaimSetupManager ( Docs , Source ). event MinFeeSet ( uint256 minFeeValueWei ) RegisterExecutorFeeSet # Defined in IClaimSetupManager ( Docs , Source ). event RegisterExecutorFeeSet ( uint256 registerExecutorFeeValueWei ) SetExecutorsExcessAmountRefunded # Defined in IClaimSetupManager ( Docs , Source ). event SetExecutorsExcessAmountRefunded ( address owner , uint256 excessAmount ) SetLibraryAddress # Defined in IIClaimSetupManager ( Docs , Source ). event SetLibraryAddress ( address libraryAddress ) Emitted when the libraryAddress has been set. Functions # accountToDelegationAccount # Defined in IClaimSetupManager ( Docs , Source ). function accountToDelegationAccount ( address _owner ) external view returns ( address ); Gets the PDA of an account. Parameters Type Description _owner address Account to query. Returns Type Description [0] address Address of its PDA or address(0) if it has not been created yet. allowedClaimRecipients # Defined in IClaimSetupManager ( Docs , Source ). function allowedClaimRecipients ( address _rewardOwner ) external view returns ( address []); Gets the addresses of recipients allowed to receive rewards on behalf of an account. Beside these, the owner of the rewards is always authorized. See setAllowedClaimRecipients . Parameters Type Description _rewardOwner address The account to query. Returns Type Description [0] address[] Addresses of all set authorized recipients. batchDelegate # Defined in IClaimSetupManager ( Docs , Source ). function batchDelegate ( address [] _delegatees , uint256 [] _bips ) external ; Undelegates all percentage delegations from the caller's PDA and then delegate to a list of accounts. See delegate . Parameters Type Description _delegatees address[] The addresses of the new recipients. _bips uint256[] The percentage of voting power to be delegated to each delegatee, expressed in basis points (1/100 of one percent). Total of all _bips values must be lower than 10000. checkExecutorAndAllowedRecipient # Defined in IIClaimSetupManager ( Docs , Source ). function checkExecutorAndAllowedRecipient ( address _executor , address _owner , address _recipient ) external view ; Checks if an executor can claim on behalf of a given account and send funds to a given recipient address. Reverts if claiming is not possible, does nothing otherwise. Parameters Type Description _executor address The executor to query. _owner address The reward owner to query. _recipient address The address where the reward would be sent. claimExecutors # Defined in IClaimSetupManager ( Docs , Source ). function claimExecutors ( address _owner ) external view returns ( address []); Gets the addresses of executors authorized to claim for an account. See setClaimExecutors . Parameters Type Description _owner address The account to query. Returns Type Description [0] address[] Addresses of all set executors. delegate # Defined in IClaimSetupManager ( Docs , Source ). function delegate ( address _to , uint256 _bips ) external ; Delegates a percentage of the caller's PDA 's voting power to another address. Parameters Type Description _to address The address of the recipient. _bips uint256 The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: Every call resets the delegation value. A value of 0 revokes delegation. delegateGovernance # Defined in IClaimSetupManager ( Docs , Source ). function delegateGovernance ( address _to ) external ; Delegates all the governance vote power of the caller's PDA to another account. Parameters Type Description _to address Address of the recipient of the delegation. disableDelegationAccount # Defined in IClaimSetupManager ( Docs , Source ). function disableDelegationAccount ( ) external ; Disables the Personal Delegation Account (PDA). When using automatic claiming, all airdrops and FTSO rewards will be sent to the owner's account. Rewards accrued by the PDA will no longer be automatically claimed. Reverts if there is no PDA. enableDelegationAccount # Defined in IClaimSetupManager ( Docs , Source ). function enableDelegationAccount ( ) external returns ( contract IDelegationAccount ); Enables (or creates) a Personal Delegation Account (PDA). When using automatic claiming, all airdrops and FTSO rewards will be sent to the PDA, and any rewards accrued by the PDA will be claimed too. Returns Type Description [0] contract IDelegationAccount Address of the delegation account contract. getAutoClaimAddressesAndExecutorFee # Defined in IIClaimSetupManager ( Docs , Source ). function getAutoClaimAddressesAndExecutorFee ( address _executor , address [] _owners ) external view returns ( address [] _recipients , uint256 _executorFeeValue ); Gets the Personal Delegation Account (PDA) for a list of accounts for which an executor is claiming. Returns owner address instead if the PDA is not created yet or not enabled. Parameters Type Description _executor address Executor to query. _owners address[] Array of reward owners which must have set _executor as their executor. Returns Type Description _recipients address[] Addresses which will receive the claimed rewards. Can be the reward owners or their PDAs. _executorFeeValue uint256 Executor's fee value, in wei. getDelegationAccountData # Defined in IClaimSetupManager ( Docs , Source ). function getDelegationAccountData ( address _owner ) external view returns ( contract IDelegationAccount _delegationAccount , bool _enabled ); Gets PDA data for an account. Parameters Type Description _owner address Account to query. Returns Type Description _delegationAccount contract IDelegationAccount Account's PDA address or address(0) if it has not been created yet. _enabled bool Whether the PDA is enabled. getExecutorCurrentFeeValue # Defined in IClaimSetupManager ( Docs , Source ). function getExecutorCurrentFeeValue ( address _executor ) external view returns ( uint256 ); Returns the current fee of a registered executor. Reverts if the executor is not registered. Parameters Type Description _executor address The executor to query. Returns Type Description [0] uint256 Fee in wei. getExecutorFeeValue # Defined in IClaimSetupManager ( Docs , Source ). function getExecutorFeeValue ( address _executor , uint256 _rewardEpoch ) external view returns ( uint256 ); Returns the fee of an executor at a given reward epoch. Parameters Type Description _executor address The executor to query. _rewardEpoch uint256 Reward Epoch ID to query. Returns Type Description [0] uint256 Fee in wei at that reward epoch. getExecutorInfo # Defined in IClaimSetupManager ( Docs , Source ). function getExecutorInfo ( address _executor ) external view returns ( bool _registered , uint256 _currentFeeValue ); Returns information about an executor. Parameters Type Description _executor address The executor to query. Returns Type Description _registered bool Whether the executor is registered. _currentFeeValue uint256 Executor's current fee value, if registered. getExecutorScheduledFeeValueChanges # Defined in IClaimSetupManager ( Docs , Source ). function getExecutorScheduledFeeValueChanges ( address _executor ) external view returns ( uint256 [] _feeValue , uint256 [] _validFromEpoch , bool [] _fixed ); Returns the currently scheduled fee changes of an executor. Parameters Type Description _executor address Executor to query. Returns Type Description _feeValue uint256[] Array of scheduled fees. _validFromEpoch uint256[] Array of reward epochs ID where the scheduled fees will become effective. _fixed bool[] Array of booleans indicating if an scheduled fee change is fixed or it might still be changed. getRegisteredExecutors # Defined in IClaimSetupManager ( Docs , Source ). function getRegisteredExecutors ( uint256 _start , uint256 _end ) external view returns ( address [] _registeredExecutors , uint256 _totalLength ); Returns the list of executors registered through registerExecutor . Supports paging. Parameters Type Description _start uint256 First executor to return. _end uint256 Last executor to return. Returns Type Description _registeredExecutors address[] Addresses of the registered executors. _totalLength uint256 Total amount of executors. isClaimExecutor # Defined in IClaimSetupManager ( Docs , Source ). function isClaimExecutor ( address _owner , address _executor ) external view returns ( bool ); Returns whether an executor is authorized to claim on behalf of a reward owner. See setClaimExecutors . Parameters Type Description _owner address The reward owner to query. _executor address The executor to query. registerExecutor # Defined in IClaimSetupManager ( Docs , Source ). function registerExecutor ( uint256 _feeValue ) external payable returns ( uint256 ); Registers the caller as an executor and sets its initial fee value. If the executor was already registered, this method only updates the fee, which will take effect after feeValueUpdateOffset reward epochs have elapsed. Executor must pay a fee in order to register. See registerExecutorFeeValueWei . Parameters Type Description _feeValue uint256 Desired fee, in wei. Must be between minFeeValueWei and maxFeeValueWei . 0 means no fee. Returns Type Description [0] uint256 Reward epoch ID when the changes become effective. revokeDelegationAt # Defined in IClaimSetupManager ( Docs , Source ). function revokeDelegationAt ( address _who , uint256 _blockNumber ) external ; Revokes all delegation from the caller's PDA to a given account at a given block. Only affects the reads via votePowerOfAtCached() in the specified block. This method should be used only to prevent rogue delegate voting in the current voting block. To stop delegating use delegate with percentage of 0 or undelegateAll . Parameters Type Description _who address The account to revoke. _blockNumber uint256 Block number where the revoking will take place. Must be in the past. setAllowedClaimRecipients # Defined in IClaimSetupManager ( Docs , Source ). function setAllowedClaimRecipients ( address [] _recipients ) external ; Set the addresses of allowed recipients. The reward owner is always an allowed recipient. Parameters Type Description _recipients address[] The new allowed recipients. All old recipients will be deleted and replaced by these. setAutoClaiming # Defined in IClaimSetupManager ( Docs , Source ). function setAutoClaiming ( address [] _executors , bool _enableDelegationAccount ) external payable ; Sets the addresses of executors and optionally enables (creates) a Personal Delegation Account (PDA). If any of the executors is a registered executor, some fee needs to be paid. Parameters Type Description _executors address[] The new executors. All old executors will be deleted and replaced by these. _enableDelegationAccount bool Whether the PDA should be enabled. setClaimExecutors # Defined in IClaimSetupManager ( Docs , Source ). function setClaimExecutors ( address [] _executors ) external payable ; Sets the addresses of executors. If any of the executors is a registered executor, some fee needs to be paid. Parameters Type Description _executors address[] The new executors. All old executors will be deleted and replaced by these. setLibraryAddress # Defined in IIClaimSetupManager ( Docs , Source ). function setLibraryAddress ( address _libraryAddress ) external ; Sets new library address. setMaxFeeValueWei # Defined in IIClaimSetupManager ( Docs , Source ). function setMaxFeeValueWei ( uint256 _maxFeeValueWei ) external ; Sets maximum fee allowed for executors, in wei. setMinFeeValueWei # Defined in IIClaimSetupManager ( Docs , Source ). function setMinFeeValueWei ( uint256 _minFeeValueWei ) external ; Sets minimum fee allowed for executors, in wei. setRegisterExecutorFeeValueWei # Defined in IIClaimSetupManager ( Docs , Source ). function setRegisterExecutorFeeValueWei ( uint256 _registerExecutorFeeValueWei ) external ; Sets the fee required to register an executor, which must be higher than 0. transferExternalToken # Defined in IClaimSetupManager ( Docs , Source ). function transferExternalToken ( contract IERC20 _token , uint256 _amount ) external ; Allows the caller to transfer ERC-20 tokens from their PDA to the owner account. The main use case is to move ERC-20 tokes received by mistake (by an airdrop, for example) out of the PDA and into the main account, where they can be more easily managed. Reverts if the target token is the WNat contract: use method withdraw for that. Parameters Type Description _token contract IERC20 Target token contract address. _amount uint256 Amount of tokens to transfer. undelegateAll # Defined in IClaimSetupManager ( Docs , Source ). function undelegateAll ( ) external ; Removes all delegations from the caller's PDA . undelegateGovernance # Defined in IClaimSetupManager ( Docs , Source ). function undelegateGovernance ( ) external ; Undelegates all governance vote power currently delegated by the caller's PDA . unregisterExecutor # Defined in IClaimSetupManager ( Docs , Source ). function unregisterExecutor ( ) external returns ( uint256 ); Unregisters the caller as an executor. Returns Type Description [0] uint256 Reward epoch ID when the change becomes effective. updateExecutorFeeValue # Defined in IClaimSetupManager ( Docs , Source ). function updateExecutorFeeValue ( uint256 _feeValue ) external returns ( uint256 ); Sets the caller's executor fee. The caller must be an executor registered through registerExecutor . When called multiple times inside the same reward epoch, only the last value remains. Parameters Type Description _feeValue uint256 Desired fee, in wei. Must be between minFeeValueWei and maxFeeValueWei . 0 means no fee. Returns Type Description [0] uint256 Reward epoch ID when the changes become effective. wNat # Defined in IIClaimSetupManager ( Docs , Source ). function wNat ( ) external view returns ( contract WNat ); Returns the WNat contract. withdraw # Defined in IClaimSetupManager ( Docs , Source ). function withdraw ( uint256 _amount ) external ; Allows the caller to transfer WNat wrapped tokens from their PDA to the owner account. Parameters Type Description _amount uint256 Amount of tokens to transfer, in wei.","title":"IIClaimSetupManager"},{"location":"apis/smart-contracts/IIClaimSetupManager/#ct_iiclaimsetupmanager","text":"Source | Inherits from IClaimSetupManager Internal interface for the ClaimSetupManager contract.","title":"IIClaimSetupManager"},{"location":"apis/smart-contracts/IIClaimSetupManager/#events","text":"","title":"Events"},{"location":"apis/smart-contracts/IIClaimSetupManager/#ev_allowedclaimrecipientschanged","text":"Defined in IClaimSetupManager ( Docs , Source ). event AllowedClaimRecipientsChanged ( address owner , address [] recipients )","title":"AllowedClaimRecipientsChanged"},{"location":"apis/smart-contracts/IIClaimSetupManager/#ev_claimexecutorfeevaluechanged","text":"Defined in IClaimSetupManager ( Docs , Source ). event ClaimExecutorFeeValueChanged ( address executor , uint256 validFromRewardEpoch , uint256 feeValueWei )","title":"ClaimExecutorFeeValueChanged"},{"location":"apis/smart-contracts/IIClaimSetupManager/#ev_claimexecutorschanged","text":"Defined in IClaimSetupManager ( Docs , Source ). event ClaimExecutorsChanged ( address owner , address [] executors )","title":"ClaimExecutorsChanged"},{"location":"apis/smart-contracts/IIClaimSetupManager/#ev_delegationaccountcreated","text":"Defined in IClaimSetupManager ( Docs , Source ). event DelegationAccountCreated ( address owner , contract IDelegationAccount delegationAccount )","title":"DelegationAccountCreated"},{"location":"apis/smart-contracts/IIClaimSetupManager/#ev_delegationaccountupdated","text":"Defined in IClaimSetupManager ( Docs , Source ). event DelegationAccountUpdated ( address owner , contract IDelegationAccount delegationAccount , bool enabled )","title":"DelegationAccountUpdated"},{"location":"apis/smart-contracts/IIClaimSetupManager/#ev_executorregistered","text":"Defined in IClaimSetupManager ( Docs , Source ). event ExecutorRegistered ( address executor )","title":"ExecutorRegistered"},{"location":"apis/smart-contracts/IIClaimSetupManager/#ev_executorunregistered","text":"Defined in IClaimSetupManager ( Docs , Source ). event ExecutorUnregistered ( address executor , uint256 validFromRewardEpoch )","title":"ExecutorUnregistered"},{"location":"apis/smart-contracts/IIClaimSetupManager/#ev_maxfeeset","text":"Defined in IClaimSetupManager ( Docs , Source ). event MaxFeeSet ( uint256 maxFeeValueWei )","title":"MaxFeeSet"},{"location":"apis/smart-contracts/IIClaimSetupManager/#ev_minfeeset","text":"Defined in IClaimSetupManager ( Docs , Source ). event MinFeeSet ( uint256 minFeeValueWei )","title":"MinFeeSet"},{"location":"apis/smart-contracts/IIClaimSetupManager/#ev_registerexecutorfeeset","text":"Defined in IClaimSetupManager ( Docs , Source ). event RegisterExecutorFeeSet ( uint256 registerExecutorFeeValueWei )","title":"RegisterExecutorFeeSet"},{"location":"apis/smart-contracts/IIClaimSetupManager/#ev_setexecutorsexcessamountrefunded","text":"Defined in IClaimSetupManager ( Docs , Source ). event SetExecutorsExcessAmountRefunded ( address owner , uint256 excessAmount )","title":"SetExecutorsExcessAmountRefunded"},{"location":"apis/smart-contracts/IIClaimSetupManager/#ev_setlibraryaddress","text":"Defined in IIClaimSetupManager ( Docs , Source ). event SetLibraryAddress ( address libraryAddress ) Emitted when the libraryAddress has been set.","title":"SetLibraryAddress"},{"location":"apis/smart-contracts/IIClaimSetupManager/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_accounttodelegationaccount_69ea2387","text":"Defined in IClaimSetupManager ( Docs , Source ). function accountToDelegationAccount ( address _owner ) external view returns ( address ); Gets the PDA of an account. Parameters Type Description _owner address Account to query. Returns Type Description [0] address Address of its PDA or address(0) if it has not been created yet.","title":"accountToDelegationAccount"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_allowedclaimrecipients_dfd14c34","text":"Defined in IClaimSetupManager ( Docs , Source ). function allowedClaimRecipients ( address _rewardOwner ) external view returns ( address []); Gets the addresses of recipients allowed to receive rewards on behalf of an account. Beside these, the owner of the rewards is always authorized. See setAllowedClaimRecipients . Parameters Type Description _rewardOwner address The account to query. Returns Type Description [0] address[] Addresses of all set authorized recipients.","title":"allowedClaimRecipients"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_batchdelegate_dc4fcda7","text":"Defined in IClaimSetupManager ( Docs , Source ). function batchDelegate ( address [] _delegatees , uint256 [] _bips ) external ; Undelegates all percentage delegations from the caller's PDA and then delegate to a list of accounts. See delegate . Parameters Type Description _delegatees address[] The addresses of the new recipients. _bips uint256[] The percentage of voting power to be delegated to each delegatee, expressed in basis points (1/100 of one percent). Total of all _bips values must be lower than 10000.","title":"batchDelegate"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_checkexecutorandallowedrecipient_ce2caa57","text":"Defined in IIClaimSetupManager ( Docs , Source ). function checkExecutorAndAllowedRecipient ( address _executor , address _owner , address _recipient ) external view ; Checks if an executor can claim on behalf of a given account and send funds to a given recipient address. Reverts if claiming is not possible, does nothing otherwise. Parameters Type Description _executor address The executor to query. _owner address The reward owner to query. _recipient address The address where the reward would be sent.","title":"checkExecutorAndAllowedRecipient"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_claimexecutors_3f317fe1","text":"Defined in IClaimSetupManager ( Docs , Source ). function claimExecutors ( address _owner ) external view returns ( address []); Gets the addresses of executors authorized to claim for an account. See setClaimExecutors . Parameters Type Description _owner address The account to query. Returns Type Description [0] address[] Addresses of all set executors.","title":"claimExecutors"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_delegate_026e402b","text":"Defined in IClaimSetupManager ( Docs , Source ). function delegate ( address _to , uint256 _bips ) external ; Delegates a percentage of the caller's PDA 's voting power to another address. Parameters Type Description _to address The address of the recipient. _bips uint256 The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: Every call resets the delegation value. A value of 0 revokes delegation.","title":"delegate"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_delegategovernance_7a68a508","text":"Defined in IClaimSetupManager ( Docs , Source ). function delegateGovernance ( address _to ) external ; Delegates all the governance vote power of the caller's PDA to another account. Parameters Type Description _to address Address of the recipient of the delegation.","title":"delegateGovernance"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_disabledelegationaccount_2394deb1","text":"Defined in IClaimSetupManager ( Docs , Source ). function disableDelegationAccount ( ) external ; Disables the Personal Delegation Account (PDA). When using automatic claiming, all airdrops and FTSO rewards will be sent to the owner's account. Rewards accrued by the PDA will no longer be automatically claimed. Reverts if there is no PDA.","title":"disableDelegationAccount"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_enabledelegationaccount_f0977215","text":"Defined in IClaimSetupManager ( Docs , Source ). function enableDelegationAccount ( ) external returns ( contract IDelegationAccount ); Enables (or creates) a Personal Delegation Account (PDA). When using automatic claiming, all airdrops and FTSO rewards will be sent to the PDA, and any rewards accrued by the PDA will be claimed too. Returns Type Description [0] contract IDelegationAccount Address of the delegation account contract.","title":"enableDelegationAccount"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_getautoclaimaddressesandexecutorfee_e24883b2","text":"Defined in IIClaimSetupManager ( Docs , Source ). function getAutoClaimAddressesAndExecutorFee ( address _executor , address [] _owners ) external view returns ( address [] _recipients , uint256 _executorFeeValue ); Gets the Personal Delegation Account (PDA) for a list of accounts for which an executor is claiming. Returns owner address instead if the PDA is not created yet or not enabled. Parameters Type Description _executor address Executor to query. _owners address[] Array of reward owners which must have set _executor as their executor. Returns Type Description _recipients address[] Addresses which will receive the claimed rewards. Can be the reward owners or their PDAs. _executorFeeValue uint256 Executor's fee value, in wei.","title":"getAutoClaimAddressesAndExecutorFee"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_getdelegationaccountdata_17a1e3fc","text":"Defined in IClaimSetupManager ( Docs , Source ). function getDelegationAccountData ( address _owner ) external view returns ( contract IDelegationAccount _delegationAccount , bool _enabled ); Gets PDA data for an account. Parameters Type Description _owner address Account to query. Returns Type Description _delegationAccount contract IDelegationAccount Account's PDA address or address(0) if it has not been created yet. _enabled bool Whether the PDA is enabled.","title":"getDelegationAccountData"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_getexecutorcurrentfeevalue_e25547f8","text":"Defined in IClaimSetupManager ( Docs , Source ). function getExecutorCurrentFeeValue ( address _executor ) external view returns ( uint256 ); Returns the current fee of a registered executor. Reverts if the executor is not registered. Parameters Type Description _executor address The executor to query. Returns Type Description [0] uint256 Fee in wei.","title":"getExecutorCurrentFeeValue"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_getexecutorfeevalue_3f8f784c","text":"Defined in IClaimSetupManager ( Docs , Source ). function getExecutorFeeValue ( address _executor , uint256 _rewardEpoch ) external view returns ( uint256 ); Returns the fee of an executor at a given reward epoch. Parameters Type Description _executor address The executor to query. _rewardEpoch uint256 Reward Epoch ID to query. Returns Type Description [0] uint256 Fee in wei at that reward epoch.","title":"getExecutorFeeValue"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_getexecutorinfo_8e28b923","text":"Defined in IClaimSetupManager ( Docs , Source ). function getExecutorInfo ( address _executor ) external view returns ( bool _registered , uint256 _currentFeeValue ); Returns information about an executor. Parameters Type Description _executor address The executor to query. Returns Type Description _registered bool Whether the executor is registered. _currentFeeValue uint256 Executor's current fee value, if registered.","title":"getExecutorInfo"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_getexecutorscheduledfeevaluechanges_950b028c","text":"Defined in IClaimSetupManager ( Docs , Source ). function getExecutorScheduledFeeValueChanges ( address _executor ) external view returns ( uint256 [] _feeValue , uint256 [] _validFromEpoch , bool [] _fixed ); Returns the currently scheduled fee changes of an executor. Parameters Type Description _executor address Executor to query. Returns Type Description _feeValue uint256[] Array of scheduled fees. _validFromEpoch uint256[] Array of reward epochs ID where the scheduled fees will become effective. _fixed bool[] Array of booleans indicating if an scheduled fee change is fixed or it might still be changed.","title":"getExecutorScheduledFeeValueChanges"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_getregisteredexecutors_6e927e61","text":"Defined in IClaimSetupManager ( Docs , Source ). function getRegisteredExecutors ( uint256 _start , uint256 _end ) external view returns ( address [] _registeredExecutors , uint256 _totalLength ); Returns the list of executors registered through registerExecutor . Supports paging. Parameters Type Description _start uint256 First executor to return. _end uint256 Last executor to return. Returns Type Description _registeredExecutors address[] Addresses of the registered executors. _totalLength uint256 Total amount of executors.","title":"getRegisteredExecutors"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_isclaimexecutor_87962abe","text":"Defined in IClaimSetupManager ( Docs , Source ). function isClaimExecutor ( address _owner , address _executor ) external view returns ( bool ); Returns whether an executor is authorized to claim on behalf of a reward owner. See setClaimExecutors . Parameters Type Description _owner address The reward owner to query. _executor address The executor to query.","title":"isClaimExecutor"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_registerexecutor_ccce7e86","text":"Defined in IClaimSetupManager ( Docs , Source ). function registerExecutor ( uint256 _feeValue ) external payable returns ( uint256 ); Registers the caller as an executor and sets its initial fee value. If the executor was already registered, this method only updates the fee, which will take effect after feeValueUpdateOffset reward epochs have elapsed. Executor must pay a fee in order to register. See registerExecutorFeeValueWei . Parameters Type Description _feeValue uint256 Desired fee, in wei. Must be between minFeeValueWei and maxFeeValueWei . 0 means no fee. Returns Type Description [0] uint256 Reward epoch ID when the changes become effective.","title":"registerExecutor"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_revokedelegationat_bbd6fbf8","text":"Defined in IClaimSetupManager ( Docs , Source ). function revokeDelegationAt ( address _who , uint256 _blockNumber ) external ; Revokes all delegation from the caller's PDA to a given account at a given block. Only affects the reads via votePowerOfAtCached() in the specified block. This method should be used only to prevent rogue delegate voting in the current voting block. To stop delegating use delegate with percentage of 0 or undelegateAll . Parameters Type Description _who address The account to revoke. _blockNumber uint256 Block number where the revoking will take place. Must be in the past.","title":"revokeDelegationAt"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_setallowedclaimrecipients_d2a4ac61","text":"Defined in IClaimSetupManager ( Docs , Source ). function setAllowedClaimRecipients ( address [] _recipients ) external ; Set the addresses of allowed recipients. The reward owner is always an allowed recipient. Parameters Type Description _recipients address[] The new allowed recipients. All old recipients will be deleted and replaced by these.","title":"setAllowedClaimRecipients"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_setautoclaiming_e72dcdbb","text":"Defined in IClaimSetupManager ( Docs , Source ). function setAutoClaiming ( address [] _executors , bool _enableDelegationAccount ) external payable ; Sets the addresses of executors and optionally enables (creates) a Personal Delegation Account (PDA). If any of the executors is a registered executor, some fee needs to be paid. Parameters Type Description _executors address[] The new executors. All old executors will be deleted and replaced by these. _enableDelegationAccount bool Whether the PDA should be enabled.","title":"setAutoClaiming"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_setclaimexecutors_9119c494","text":"Defined in IClaimSetupManager ( Docs , Source ). function setClaimExecutors ( address [] _executors ) external payable ; Sets the addresses of executors. If any of the executors is a registered executor, some fee needs to be paid. Parameters Type Description _executors address[] The new executors. All old executors will be deleted and replaced by these.","title":"setClaimExecutors"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_setlibraryaddress_4863ba17","text":"Defined in IIClaimSetupManager ( Docs , Source ). function setLibraryAddress ( address _libraryAddress ) external ; Sets new library address.","title":"setLibraryAddress"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_setmaxfeevaluewei_2e9b6afa","text":"Defined in IIClaimSetupManager ( Docs , Source ). function setMaxFeeValueWei ( uint256 _maxFeeValueWei ) external ; Sets maximum fee allowed for executors, in wei.","title":"setMaxFeeValueWei"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_setminfeevaluewei_d8343550","text":"Defined in IIClaimSetupManager ( Docs , Source ). function setMinFeeValueWei ( uint256 _minFeeValueWei ) external ; Sets minimum fee allowed for executors, in wei.","title":"setMinFeeValueWei"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_setregisterexecutorfeevaluewei_869d90a5","text":"Defined in IIClaimSetupManager ( Docs , Source ). function setRegisterExecutorFeeValueWei ( uint256 _registerExecutorFeeValueWei ) external ; Sets the fee required to register an executor, which must be higher than 0.","title":"setRegisterExecutorFeeValueWei"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_transferexternaltoken_489a8a47","text":"Defined in IClaimSetupManager ( Docs , Source ). function transferExternalToken ( contract IERC20 _token , uint256 _amount ) external ; Allows the caller to transfer ERC-20 tokens from their PDA to the owner account. The main use case is to move ERC-20 tokes received by mistake (by an airdrop, for example) out of the PDA and into the main account, where they can be more easily managed. Reverts if the target token is the WNat contract: use method withdraw for that. Parameters Type Description _token contract IERC20 Target token contract address. _amount uint256 Amount of tokens to transfer.","title":"transferExternalToken"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_undelegateall_b302f393","text":"Defined in IClaimSetupManager ( Docs , Source ). function undelegateAll ( ) external ; Removes all delegations from the caller's PDA .","title":"undelegateAll"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_undelegategovernance_87a2a0dc","text":"Defined in IClaimSetupManager ( Docs , Source ). function undelegateGovernance ( ) external ; Undelegates all governance vote power currently delegated by the caller's PDA .","title":"undelegateGovernance"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_unregisterexecutor_868a660f","text":"Defined in IClaimSetupManager ( Docs , Source ). function unregisterExecutor ( ) external returns ( uint256 ); Unregisters the caller as an executor. Returns Type Description [0] uint256 Reward epoch ID when the change becomes effective.","title":"unregisterExecutor"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_updateexecutorfeevalue_831f16af","text":"Defined in IClaimSetupManager ( Docs , Source ). function updateExecutorFeeValue ( uint256 _feeValue ) external returns ( uint256 ); Sets the caller's executor fee. The caller must be an executor registered through registerExecutor . When called multiple times inside the same reward epoch, only the last value remains. Parameters Type Description _feeValue uint256 Desired fee, in wei. Must be between minFeeValueWei and maxFeeValueWei . 0 means no fee. Returns Type Description [0] uint256 Reward epoch ID when the changes become effective.","title":"updateExecutorFeeValue"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_wnat_9edbf007","text":"Defined in IIClaimSetupManager ( Docs , Source ). function wNat ( ) external view returns ( contract WNat ); Returns the WNat contract.","title":"wNat"},{"location":"apis/smart-contracts/IIClaimSetupManager/#fn_withdraw_2e1a7d4d","text":"Defined in IClaimSetupManager ( Docs , Source ). function withdraw ( uint256 _amount ) external ; Allows the caller to transfer WNat wrapped tokens from their PDA to the owner account. Parameters Type Description _amount uint256 Amount of tokens to transfer, in wei.","title":"withdraw"},{"location":"apis/smart-contracts/IICleanable/","text":"IICleanable # Source Internal interface for entities that can have their block history cleaned. Functions # cleanupBlockNumber # Defined in IICleanable ( Docs , Source ). function cleanupBlockNumber ( ) external view returns ( uint256 ); Get the current cleanup block number set with setCleanupBlockNumber . Returns Type Description [0] uint256 The currently set cleanup block number. setCleanerContract # Defined in IICleanable ( Docs , Source ). function setCleanerContract ( address _cleanerContract ) external ; Set the contract that is allowed to call history cleaning methods. Parameters Type Description _cleanerContract address Address of the cleanup contract. Usually this will be an instance of CleanupBlockNumberManager . setCleanupBlockNumber # Defined in IICleanable ( Docs , Source ). function setCleanupBlockNumber ( uint256 _blockNumber ) external ; Set the cleanup block number. Historic data for the blocks before cleanupBlockNumber can be erased. History before that block should never be used since it can be inconsistent. In particular, cleanup block number must be lower than the current vote power block. Parameters Type Description _blockNumber uint256 The new cleanup block number.","title":"IICleanable"},{"location":"apis/smart-contracts/IICleanable/#ct_iicleanable","text":"Source Internal interface for entities that can have their block history cleaned.","title":"IICleanable"},{"location":"apis/smart-contracts/IICleanable/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IICleanable/#fn_cleanupblocknumber_deea13e7","text":"Defined in IICleanable ( Docs , Source ). function cleanupBlockNumber ( ) external view returns ( uint256 ); Get the current cleanup block number set with setCleanupBlockNumber . Returns Type Description [0] uint256 The currently set cleanup block number.","title":"cleanupBlockNumber"},{"location":"apis/smart-contracts/IICleanable/#fn_setcleanercontract_f6a494af","text":"Defined in IICleanable ( Docs , Source ). function setCleanerContract ( address _cleanerContract ) external ; Set the contract that is allowed to call history cleaning methods. Parameters Type Description _cleanerContract address Address of the cleanup contract. Usually this will be an instance of CleanupBlockNumberManager .","title":"setCleanerContract"},{"location":"apis/smart-contracts/IICleanable/#fn_setcleanupblocknumber_13de97f5","text":"Defined in IICleanable ( Docs , Source ). function setCleanupBlockNumber ( uint256 _blockNumber ) external ; Set the cleanup block number. Historic data for the blocks before cleanupBlockNumber can be erased. History before that block should never be used since it can be inconsistent. In particular, cleanup block number must be lower than the current vote power block. Parameters Type Description _blockNumber uint256 The new cleanup block number.","title":"setCleanupBlockNumber"},{"location":"apis/smart-contracts/IIFtso/","text":"IIFtso # Source | Inherits from IFtso , IFtsoGenesis Internal interface for each of the FTSO contracts that handles an asset. Read the FTSO documentation page for general information about the FTSO system. Functions # activateFtso # Defined in IIFtso ( Docs , Source ). function activateFtso ( uint256 _firstEpochStartTs , uint256 _submitPeriodSeconds , uint256 _revealPeriodSeconds ) external ; Initializes FTSO immutable settings and activates the contract. Parameters Type Description _firstEpochStartTs uint256 Timestamp of the first epoch in seconds from UNIX epoch. _submitPeriodSeconds uint256 Duration of epoch submission window in seconds. _revealPeriodSeconds uint256 Duration of epoch reveal window in seconds. active # Defined in IFtso ( Docs , Source ). function active ( ) external view returns ( bool ); Returns whether FTSO is active or not. configureEpochs # Defined in IIFtso ( Docs , Source ). function configureEpochs ( uint256 _maxVotePowerNatThresholdFraction , uint256 _maxVotePowerAssetThresholdFraction , uint256 _lowAssetUSDThreshold , uint256 _highAssetUSDThreshold , uint256 _highAssetTurnoutThresholdBIPS , uint256 _lowNatTurnoutThresholdBIPS , uint256 _elasticBandRewardBIPS , uint256 _elasticBandWidthPPM , address [] _trustedAddresses ) external ; Sets configurable settings related to epochs. Parameters Type Description _maxVotePowerNatThresholdFraction uint256 High threshold for native token vote power per voter. _maxVotePowerAssetThresholdFraction uint256 High threshold for asset vote power per voter. _lowAssetUSDThreshold uint256 Threshold for low asset vote power (in scaled USD). _highAssetUSDThreshold uint256 Threshold for high asset vote power (in scaled USD). _highAssetTurnoutThresholdBIPS uint256 Threshold for high asset turnout (in BIPS). _lowNatTurnoutThresholdBIPS uint256 Threshold for low nat turnout (in BIPS). _elasticBandRewardBIPS uint256 Percentage of the rewards (in BIPS) that go to the secondary reward band . The rest go to the primary reward band. _elasticBandWidthPPM uint256 Width of the secondary reward band, in parts-per-milion of the median. _trustedAddresses address[] Trusted voters that will be used if low voter turnout is detected. deactivateFtso # Defined in IIFtso ( Docs , Source ). function deactivateFtso ( ) external ; Deactivates the contract. epochsConfiguration # Defined in IIFtso ( Docs , Source ). function epochsConfiguration ( ) external view returns ( uint256 _maxVotePowerNatThresholdFraction , uint256 _maxVotePowerAssetThresholdFraction , uint256 _lowAssetUSDThreshold , uint256 _highAssetUSDThreshold , uint256 _highAssetTurnoutThresholdBIPS , uint256 _lowNatTurnoutThresholdBIPS , uint256 _elasticBandRewardBIPS , uint256 _elasticBandWidthPPM , address [] _trustedAddresses ); Returns current configuration of epoch state. Returns Type Description _maxVotePowerNatThresholdFraction uint256 High threshold for native token vote power per voter. _maxVotePowerAssetThresholdFraction uint256 High threshold for asset vote power per voter. _lowAssetUSDThreshold uint256 Threshold for low asset vote power (in scaled USD). _highAssetUSDThreshold uint256 Threshold for high asset vote power (in scaled USD). _highAssetTurnoutThresholdBIPS uint256 Threshold for high asset turnout (in BIPS). _lowNatTurnoutThresholdBIPS uint256 Threshold for low nat turnout (in BIPS). _elasticBandRewardBIPS uint256 Percentage of the rewards (in BIPS) that go to the secondary reward band . The rest go to the primary reward band. _elasticBandWidthPPM uint256 Width of the secondary reward band, in parts-per-milion of the median. _trustedAddresses address[] Trusted voters that will be used if low voter turnout is detected. fallbackFinalizePriceEpoch # Defined in IIFtso ( Docs , Source ). function fallbackFinalizePriceEpoch ( uint256 _epochId ) external ; Forces finalization of a price epoch, calculating the median price from trusted addresses only. Used as a fallback method, for example, due to an unexpected error during normal epoch finalization or because the ftsoManager enabled the fallback mode. Parameters Type Description _epochId uint256 ID of the epoch to finalize. finalizePriceEpoch # Defined in IIFtso ( Docs , Source ). function finalizePriceEpoch ( uint256 _epochId , bool _returnRewardData ) external returns ( address [] _eligibleAddresses , uint256 [] _natWeights , uint256 _totalNatWeight ); Computes epoch price based on gathered votes. If the price reveal window for the epoch has ended, finalize the epoch. Iterate list of price submissions. Find weighted median. Find adjacent 50% of price submissions. Allocate rewards for price submissions. Parameters Type Description _epochId uint256 ID of the epoch to finalize. _returnRewardData bool Parameter that determines if the reward data is returned. Returns Type Description _eligibleAddresses address[] List of addresses eligible for reward. _natWeights uint256[] List of native token weights corresponding to the eligible addresses. _totalNatWeight uint256 Sum of weights in _natWeights . forceFinalizePriceEpoch # Defined in IIFtso ( Docs , Source ). function forceFinalizePriceEpoch ( uint256 _epochId ) external ; Forces finalization of a price epoch by copying the price from the previous epoch. Used as a fallback method if fallbackFinalizePriceEpoch fails due to an exception. Parameters Type Description _epochId uint256 ID of the epoch to finalize. ftsoManager # Defined in IIFtso ( Docs , Source ). function ftsoManager ( ) external view returns ( address ); Returns the FTSO manager's address. Returns Type Description [0] address Address of the FTSO manager contract. getAsset # Defined in IIFtso ( Docs , Source ). function getAsset ( ) external view returns ( contract IIVPToken ); Returns the FTSO asset. Returns Type Description [0] contract IIVPToken Address of the IIVPToken tracked by this FTSO. null in case of multi-asset FTSO. getAssetFtsos # Defined in IIFtso ( Docs , Source ). function getAssetFtsos ( ) external view returns ( contract IIFtso []); Returns the asset FTSOs. Returns Type Description [0] contract IIFtso[] Array of IIFtso contract addresses. null in case of single-asset FTSO. getCurrentEpochId # Defined in IFtso ( Docs , Source ). function getCurrentEpochId ( ) external view returns ( uint256 ); Returns the current epoch ID. Returns Type Description [0] uint256 Currently running epoch ID. IDs are consecutive numbers starting from zero. getCurrentPrice # Defined in IFtso ( Docs , Source ). function getCurrentPrice ( ) external view returns ( uint256 _price , uint256 _timestamp ); Returns the current asset price. Returns Type Description _price uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Time when price was updated for the last time, in seconds from UNIX epoch. getCurrentPriceDetails # Defined in IFtso ( Docs , Source ). function getCurrentPriceDetails ( ) external view returns ( uint256 _price , uint256 _priceTimestamp , enum IFtso . PriceFinalizationType _priceFinalizationType , uint256 _lastPriceEpochFinalizationTimestamp , enum IFtso . PriceFinalizationType _lastPriceEpochFinalizationType ); Returns asset's current price details. All timestamps are in seconds from UNIX epoch. Returns Type Description _price uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _priceTimestamp uint256 Time when price was updated for the last time. _priceFinalizationType enum IFtso.PriceFinalizationType Finalization type when price was updated for the last time. _lastPriceEpochFinalizationTimestamp uint256 Time when last price epoch was finalized. _lastPriceEpochFinalizationType enum IFtso.PriceFinalizationType Finalization type of last finalized price epoch. getCurrentPriceFromTrustedProviders # Defined in IFtso ( Docs , Source ). function getCurrentPriceFromTrustedProviders ( ) external view returns ( uint256 _price , uint256 _timestamp ); Returns current asset price calculated only using input from trusted providers. Returns Type Description _price uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Time when price was updated for the last time, in seconds from UNIX epoch. getCurrentPriceWithDecimals # Defined in IFtso ( Docs , Source ). function getCurrentPriceWithDecimals ( ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Returns current asset price and number of decimals. Returns Type Description _price uint256 Price in USD multiplied by 10^ _assetPriceUsdDecimals . _timestamp uint256 Time when price was updated for the last time, in seconds from UNIX epoch. _assetPriceUsdDecimals uint256 Number of decimals used to return the USD price. getCurrentPriceWithDecimalsFromTrustedProviders # Defined in IFtso ( Docs , Source ). function getCurrentPriceWithDecimalsFromTrustedProviders ( ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Returns current asset price calculated only using input from trusted providers and number of decimals. Returns Type Description _price uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Time when price was updated for the last time, in seconds from UNIX epoch. _assetPriceUsdDecimals uint256 Number of decimals used to return the USD price. getCurrentRandom # Defined in IFtso ( Docs , Source ). function getCurrentRandom ( ) external view returns ( uint256 ); Returns the random number for the previous price epoch, obtained from the random numbers provided by all data providers along with their data submissions. getEpochId # Defined in IFtso ( Docs , Source ). function getEpochId ( uint256 _timestamp ) external view returns ( uint256 ); Returns the ID of the epoch that was opened for price submission at the specified timestamp. Parameters Type Description _timestamp uint256 Queried timestamp in seconds from UNIX epoch. Returns Type Description [0] uint256 Epoch ID corresponding to that timestamp. IDs are consecutive numbers starting from zero. getEpochPrice # Defined in IFtso ( Docs , Source ). function getEpochPrice ( uint256 _epochId ) external view returns ( uint256 ); Returns agreed asset price in the specified epoch. Parameters Type Description _epochId uint256 ID of the epoch. Only the last 200 epochs can be queried. Out-of-bounds queries revert. Returns Type Description [0] uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . getEpochPriceForVoter # Defined in IFtso ( Docs , Source ). function getEpochPriceForVoter ( uint256 _epochId , address _voter ) external view returns ( uint256 ); Returns asset price submitted by a voter in the specified epoch. Parameters Type Description _epochId uint256 ID of the epoch being queried. Only the last 200 epochs can be queried. Out-of-bounds queries revert. _voter address Address of the voter being queried. Returns Type Description [0] uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . getPriceEpochConfiguration # Defined in IFtso ( Docs , Source ). function getPriceEpochConfiguration ( ) external view returns ( uint256 _firstEpochStartTs , uint256 _submitPeriodSeconds , uint256 _revealPeriodSeconds ); Returns current epoch's configuration. Returns Type Description _firstEpochStartTs uint256 First epoch start timestamp in seconds from UNIX epoch. _submitPeriodSeconds uint256 Submit period in seconds. _revealPeriodSeconds uint256 Reveal period in seconds. getPriceEpochData # Defined in IFtso ( Docs , Source ). function getPriceEpochData ( ) external view returns ( uint256 _epochId , uint256 _epochSubmitEndTime , uint256 _epochRevealEndTime , uint256 _votePowerBlock , bool _fallbackMode ); Returns current epoch data. Intervals are open on the right: End times are not included. Returns Type Description _epochId uint256 Current epoch ID. _epochSubmitEndTime uint256 End time of the price submission window in seconds from UNIX epoch. _epochRevealEndTime uint256 End time of the price reveal window in seconds from UNIX epoch. _votePowerBlock uint256 Vote power block for the current epoch. _fallbackMode bool Whether the current epoch is in fallback mode. Only votes from trusted addresses are used in this mode. getRandom # Defined in IFtso ( Docs , Source ). function getRandom ( uint256 _epochId ) external view returns ( uint256 ); Returns the random number used in a specific past epoch, obtained from the random numbers provided by all data providers along with their data submissions. Parameters Type Description _epochId uint256 ID of the queried epoch. Current epoch cannot be queried, and the previous epoch is constantly updated as data providers reveal their prices and random numbers. Only the last 50 epochs can be queried and there is no bounds checking for this parameter. Out-of-bounds queries return undefined values. Returns Type Description [0] uint256 The random number used in that epoch. getVoteWeightingParameters # Defined in IIFtso ( Docs , Source ). function getVoteWeightingParameters ( ) external view returns ( contract IIVPToken [] _assets , uint256 [] _assetMultipliers , uint256 _totalVotePowerNat , uint256 _totalVotePowerAsset , uint256 _assetWeightRatio , uint256 _votePowerBlock ); Returns parameters necessary for replicating vote weighting (used in VoterWhitelister ). Returns Type Description _assets contract IIVPToken[] The list of assets that are accounted in vote. _assetMultipliers uint256[] Weight multiplier of each asset in (multiasset) FTSO. _totalVotePowerNat uint256 Total native token vote power at block. _totalVotePowerAsset uint256 Total combined asset vote power at block. _assetWeightRatio uint256 Ratio of combined asset vote power vs. native token vp (in BIPS). _votePowerBlock uint256 Vote power block for the epoch. initializeCurrentEpochStateForReveal # Defined in IIFtso ( Docs , Source ). function initializeCurrentEpochStateForReveal ( uint256 _circulatingSupplyNat , bool _fallbackMode ) external ; Initializes current epoch instance for reveal. Parameters Type Description _circulatingSupplyNat uint256 Epoch native token circulating supply. _fallbackMode bool Whether the current epoch is in fallback mode. revealPriceSubmitter # Defined in IFtsoGenesis ( Docs , Source ). function revealPriceSubmitter ( address _voter , uint256 _epochId , uint256 _price , uint256 _voterWNatVP ) external ; Reveals the price submitted by a voter on a specific epoch. The hash of _price and _random must be equal to the submitted hash Parameters Type Description _voter address Voter address. _epochId uint256 ID of the epoch in which the price hash was submitted. _price uint256 Submitted price. _voterWNatVP uint256 Voter's vote power in WNat units. setAsset # Defined in IIFtso ( Docs , Source ). function setAsset ( contract IIVPToken _asset ) external ; Sets asset for FTSO to operate as single-asset oracle. Parameters Type Description _asset contract IIVPToken Address of the IIVPToken contract that will be the asset tracked by this FTSO. setAssetFtsos # Defined in IIFtso ( Docs , Source ). function setAssetFtsos ( contract IIFtso [] _assetFtsos ) external ; Sets an array of FTSOs for FTSO to operate as multi-asset oracle. FTSOs implicitly determine the FTSO assets. Parameters Type Description _assetFtsos contract IIFtso[] Array of FTSOs. setVotePowerBlock # Defined in IIFtso ( Docs , Source ). function setVotePowerBlock ( uint256 _blockNumber ) external ; Sets the current vote power block. Current vote power block will update per reward epoch. The FTSO doesn't have notion of reward epochs. Parameters Type Description _blockNumber uint256 Vote power block. symbol # Defined in IFtso ( Docs , Source ). function symbol ( ) external view returns ( string ); Returns the FTSO symbol . updateInitialPrice # Defined in IIFtso ( Docs , Source ). function updateInitialPrice ( uint256 _initialPriceUSD , uint256 _initialPriceTimestamp ) external ; Updates initial asset price when the contract is not active yet. wNat # Defined in IIFtso ( Docs , Source ). function wNat ( ) external view returns ( contract IIVPToken ); Address of the WNat contract. Returns Type Description [0] contract IIVPToken Address of the WNat contract. wNatVotePowerCached # Defined in IFtsoGenesis ( Docs , Source ). function wNatVotePowerCached ( address _voter , uint256 _epochId ) external returns ( uint256 ); Get and cache the vote power of a voter on a specific epoch, in WNat units. Parameters Type Description _voter address Voter address. _epochId uint256 ID of the epoch in which the price hash was submitted. Returns Type Description [0] uint256 Voter's vote power in WNat units.","title":"IIFtso"},{"location":"apis/smart-contracts/IIFtso/#ct_iiftso","text":"Source | Inherits from IFtso , IFtsoGenesis Internal interface for each of the FTSO contracts that handles an asset. Read the FTSO documentation page for general information about the FTSO system.","title":"IIFtso"},{"location":"apis/smart-contracts/IIFtso/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IIFtso/#fn_activateftso_2f0a6f3c","text":"Defined in IIFtso ( Docs , Source ). function activateFtso ( uint256 _firstEpochStartTs , uint256 _submitPeriodSeconds , uint256 _revealPeriodSeconds ) external ; Initializes FTSO immutable settings and activates the contract. Parameters Type Description _firstEpochStartTs uint256 Timestamp of the first epoch in seconds from UNIX epoch. _submitPeriodSeconds uint256 Duration of epoch submission window in seconds. _revealPeriodSeconds uint256 Duration of epoch reveal window in seconds.","title":"activateFtso"},{"location":"apis/smart-contracts/IIFtso/#fn_active_02fb0c5e","text":"Defined in IFtso ( Docs , Source ). function active ( ) external view returns ( bool ); Returns whether FTSO is active or not.","title":"active"},{"location":"apis/smart-contracts/IIFtso/#fn_configureepochs_5a3c9d8e","text":"Defined in IIFtso ( Docs , Source ). function configureEpochs ( uint256 _maxVotePowerNatThresholdFraction , uint256 _maxVotePowerAssetThresholdFraction , uint256 _lowAssetUSDThreshold , uint256 _highAssetUSDThreshold , uint256 _highAssetTurnoutThresholdBIPS , uint256 _lowNatTurnoutThresholdBIPS , uint256 _elasticBandRewardBIPS , uint256 _elasticBandWidthPPM , address [] _trustedAddresses ) external ; Sets configurable settings related to epochs. Parameters Type Description _maxVotePowerNatThresholdFraction uint256 High threshold for native token vote power per voter. _maxVotePowerAssetThresholdFraction uint256 High threshold for asset vote power per voter. _lowAssetUSDThreshold uint256 Threshold for low asset vote power (in scaled USD). _highAssetUSDThreshold uint256 Threshold for high asset vote power (in scaled USD). _highAssetTurnoutThresholdBIPS uint256 Threshold for high asset turnout (in BIPS). _lowNatTurnoutThresholdBIPS uint256 Threshold for low nat turnout (in BIPS). _elasticBandRewardBIPS uint256 Percentage of the rewards (in BIPS) that go to the secondary reward band . The rest go to the primary reward band. _elasticBandWidthPPM uint256 Width of the secondary reward band, in parts-per-milion of the median. _trustedAddresses address[] Trusted voters that will be used if low voter turnout is detected.","title":"configureEpochs"},{"location":"apis/smart-contracts/IIFtso/#fn_deactivateftso_555989da","text":"Defined in IIFtso ( Docs , Source ). function deactivateFtso ( ) external ; Deactivates the contract.","title":"deactivateFtso"},{"location":"apis/smart-contracts/IIFtso/#fn_epochsconfiguration_e3749e0c","text":"Defined in IIFtso ( Docs , Source ). function epochsConfiguration ( ) external view returns ( uint256 _maxVotePowerNatThresholdFraction , uint256 _maxVotePowerAssetThresholdFraction , uint256 _lowAssetUSDThreshold , uint256 _highAssetUSDThreshold , uint256 _highAssetTurnoutThresholdBIPS , uint256 _lowNatTurnoutThresholdBIPS , uint256 _elasticBandRewardBIPS , uint256 _elasticBandWidthPPM , address [] _trustedAddresses ); Returns current configuration of epoch state. Returns Type Description _maxVotePowerNatThresholdFraction uint256 High threshold for native token vote power per voter. _maxVotePowerAssetThresholdFraction uint256 High threshold for asset vote power per voter. _lowAssetUSDThreshold uint256 Threshold for low asset vote power (in scaled USD). _highAssetUSDThreshold uint256 Threshold for high asset vote power (in scaled USD). _highAssetTurnoutThresholdBIPS uint256 Threshold for high asset turnout (in BIPS). _lowNatTurnoutThresholdBIPS uint256 Threshold for low nat turnout (in BIPS). _elasticBandRewardBIPS uint256 Percentage of the rewards (in BIPS) that go to the secondary reward band . The rest go to the primary reward band. _elasticBandWidthPPM uint256 Width of the secondary reward band, in parts-per-milion of the median. _trustedAddresses address[] Trusted voters that will be used if low voter turnout is detected.","title":"epochsConfiguration"},{"location":"apis/smart-contracts/IIFtso/#fn_fallbackfinalizepriceepoch_4afd5102","text":"Defined in IIFtso ( Docs , Source ). function fallbackFinalizePriceEpoch ( uint256 _epochId ) external ; Forces finalization of a price epoch, calculating the median price from trusted addresses only. Used as a fallback method, for example, due to an unexpected error during normal epoch finalization or because the ftsoManager enabled the fallback mode. Parameters Type Description _epochId uint256 ID of the epoch to finalize.","title":"fallbackFinalizePriceEpoch"},{"location":"apis/smart-contracts/IIFtso/#fn_finalizepriceepoch_40462a2d","text":"Defined in IIFtso ( Docs , Source ). function finalizePriceEpoch ( uint256 _epochId , bool _returnRewardData ) external returns ( address [] _eligibleAddresses , uint256 [] _natWeights , uint256 _totalNatWeight ); Computes epoch price based on gathered votes. If the price reveal window for the epoch has ended, finalize the epoch. Iterate list of price submissions. Find weighted median. Find adjacent 50% of price submissions. Allocate rewards for price submissions. Parameters Type Description _epochId uint256 ID of the epoch to finalize. _returnRewardData bool Parameter that determines if the reward data is returned. Returns Type Description _eligibleAddresses address[] List of addresses eligible for reward. _natWeights uint256[] List of native token weights corresponding to the eligible addresses. _totalNatWeight uint256 Sum of weights in _natWeights .","title":"finalizePriceEpoch"},{"location":"apis/smart-contracts/IIFtso/#fn_forcefinalizepriceepoch_974d7a6b","text":"Defined in IIFtso ( Docs , Source ). function forceFinalizePriceEpoch ( uint256 _epochId ) external ; Forces finalization of a price epoch by copying the price from the previous epoch. Used as a fallback method if fallbackFinalizePriceEpoch fails due to an exception. Parameters Type Description _epochId uint256 ID of the epoch to finalize.","title":"forceFinalizePriceEpoch"},{"location":"apis/smart-contracts/IIFtso/#fn_ftsomanager_11a7aaaa","text":"Defined in IIFtso ( Docs , Source ). function ftsoManager ( ) external view returns ( address ); Returns the FTSO manager's address. Returns Type Description [0] address Address of the FTSO manager contract.","title":"ftsoManager"},{"location":"apis/smart-contracts/IIFtso/#fn_getasset_5c222bad","text":"Defined in IIFtso ( Docs , Source ). function getAsset ( ) external view returns ( contract IIVPToken ); Returns the FTSO asset. Returns Type Description [0] contract IIVPToken Address of the IIVPToken tracked by this FTSO. null in case of multi-asset FTSO.","title":"getAsset"},{"location":"apis/smart-contracts/IIFtso/#fn_getassetftsos_18931c35","text":"Defined in IIFtso ( Docs , Source ). function getAssetFtsos ( ) external view returns ( contract IIFtso []); Returns the asset FTSOs. Returns Type Description [0] contract IIFtso[] Array of IIFtso contract addresses. null in case of single-asset FTSO.","title":"getAssetFtsos"},{"location":"apis/smart-contracts/IIFtso/#fn_getcurrentepochid_a29a839f","text":"Defined in IFtso ( Docs , Source ). function getCurrentEpochId ( ) external view returns ( uint256 ); Returns the current epoch ID. Returns Type Description [0] uint256 Currently running epoch ID. IDs are consecutive numbers starting from zero.","title":"getCurrentEpochId"},{"location":"apis/smart-contracts/IIFtso/#fn_getcurrentprice_eb91d37e","text":"Defined in IFtso ( Docs , Source ). function getCurrentPrice ( ) external view returns ( uint256 _price , uint256 _timestamp ); Returns the current asset price. Returns Type Description _price uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Time when price was updated for the last time, in seconds from UNIX epoch.","title":"getCurrentPrice"},{"location":"apis/smart-contracts/IIFtso/#fn_getcurrentpricedetails_040d73b8","text":"Defined in IFtso ( Docs , Source ). function getCurrentPriceDetails ( ) external view returns ( uint256 _price , uint256 _priceTimestamp , enum IFtso . PriceFinalizationType _priceFinalizationType , uint256 _lastPriceEpochFinalizationTimestamp , enum IFtso . PriceFinalizationType _lastPriceEpochFinalizationType ); Returns asset's current price details. All timestamps are in seconds from UNIX epoch. Returns Type Description _price uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _priceTimestamp uint256 Time when price was updated for the last time. _priceFinalizationType enum IFtso.PriceFinalizationType Finalization type when price was updated for the last time. _lastPriceEpochFinalizationTimestamp uint256 Time when last price epoch was finalized. _lastPriceEpochFinalizationType enum IFtso.PriceFinalizationType Finalization type of last finalized price epoch.","title":"getCurrentPriceDetails"},{"location":"apis/smart-contracts/IIFtso/#fn_getcurrentpricefromtrustedproviders_af52df08","text":"Defined in IFtso ( Docs , Source ). function getCurrentPriceFromTrustedProviders ( ) external view returns ( uint256 _price , uint256 _timestamp ); Returns current asset price calculated only using input from trusted providers. Returns Type Description _price uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Time when price was updated for the last time, in seconds from UNIX epoch.","title":"getCurrentPriceFromTrustedProviders"},{"location":"apis/smart-contracts/IIFtso/#fn_getcurrentpricewithdecimals_65f5cd86","text":"Defined in IFtso ( Docs , Source ). function getCurrentPriceWithDecimals ( ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Returns current asset price and number of decimals. Returns Type Description _price uint256 Price in USD multiplied by 10^ _assetPriceUsdDecimals . _timestamp uint256 Time when price was updated for the last time, in seconds from UNIX epoch. _assetPriceUsdDecimals uint256 Number of decimals used to return the USD price.","title":"getCurrentPriceWithDecimals"},{"location":"apis/smart-contracts/IIFtso/#fn_getcurrentpricewithdecimalsfromtrustedproviders_3cacb3ae","text":"Defined in IFtso ( Docs , Source ). function getCurrentPriceWithDecimalsFromTrustedProviders ( ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Returns current asset price calculated only using input from trusted providers and number of decimals. Returns Type Description _price uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Time when price was updated for the last time, in seconds from UNIX epoch. _assetPriceUsdDecimals uint256 Number of decimals used to return the USD price.","title":"getCurrentPriceWithDecimalsFromTrustedProviders"},{"location":"apis/smart-contracts/IIFtso/#fn_getcurrentrandom_d89601fd","text":"Defined in IFtso ( Docs , Source ). function getCurrentRandom ( ) external view returns ( uint256 ); Returns the random number for the previous price epoch, obtained from the random numbers provided by all data providers along with their data submissions.","title":"getCurrentRandom"},{"location":"apis/smart-contracts/IIFtso/#fn_getepochid_5303548b","text":"Defined in IFtso ( Docs , Source ). function getEpochId ( uint256 _timestamp ) external view returns ( uint256 ); Returns the ID of the epoch that was opened for price submission at the specified timestamp. Parameters Type Description _timestamp uint256 Queried timestamp in seconds from UNIX epoch. Returns Type Description [0] uint256 Epoch ID corresponding to that timestamp. IDs are consecutive numbers starting from zero.","title":"getEpochId"},{"location":"apis/smart-contracts/IIFtso/#fn_getepochprice_7d1d6f12","text":"Defined in IFtso ( Docs , Source ). function getEpochPrice ( uint256 _epochId ) external view returns ( uint256 ); Returns agreed asset price in the specified epoch. Parameters Type Description _epochId uint256 ID of the epoch. Only the last 200 epochs can be queried. Out-of-bounds queries revert. Returns Type Description [0] uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS .","title":"getEpochPrice"},{"location":"apis/smart-contracts/IIFtso/#fn_getepochpriceforvoter_c5d8b9e7","text":"Defined in IFtso ( Docs , Source ). function getEpochPriceForVoter ( uint256 _epochId , address _voter ) external view returns ( uint256 ); Returns asset price submitted by a voter in the specified epoch. Parameters Type Description _epochId uint256 ID of the epoch being queried. Only the last 200 epochs can be queried. Out-of-bounds queries revert. _voter address Address of the voter being queried. Returns Type Description [0] uint256 Price in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS .","title":"getEpochPriceForVoter"},{"location":"apis/smart-contracts/IIFtso/#fn_getpriceepochconfiguration_144e1591","text":"Defined in IFtso ( Docs , Source ). function getPriceEpochConfiguration ( ) external view returns ( uint256 _firstEpochStartTs , uint256 _submitPeriodSeconds , uint256 _revealPeriodSeconds ); Returns current epoch's configuration. Returns Type Description _firstEpochStartTs uint256 First epoch start timestamp in seconds from UNIX epoch. _submitPeriodSeconds uint256 Submit period in seconds. _revealPeriodSeconds uint256 Reveal period in seconds.","title":"getPriceEpochConfiguration"},{"location":"apis/smart-contracts/IIFtso/#fn_getpriceepochdata_e3b3a3b3","text":"Defined in IFtso ( Docs , Source ). function getPriceEpochData ( ) external view returns ( uint256 _epochId , uint256 _epochSubmitEndTime , uint256 _epochRevealEndTime , uint256 _votePowerBlock , bool _fallbackMode ); Returns current epoch data. Intervals are open on the right: End times are not included. Returns Type Description _epochId uint256 Current epoch ID. _epochSubmitEndTime uint256 End time of the price submission window in seconds from UNIX epoch. _epochRevealEndTime uint256 End time of the price reveal window in seconds from UNIX epoch. _votePowerBlock uint256 Vote power block for the current epoch. _fallbackMode bool Whether the current epoch is in fallback mode. Only votes from trusted addresses are used in this mode.","title":"getPriceEpochData"},{"location":"apis/smart-contracts/IIFtso/#fn_getrandom_cd4b6914","text":"Defined in IFtso ( Docs , Source ). function getRandom ( uint256 _epochId ) external view returns ( uint256 ); Returns the random number used in a specific past epoch, obtained from the random numbers provided by all data providers along with their data submissions. Parameters Type Description _epochId uint256 ID of the queried epoch. Current epoch cannot be queried, and the previous epoch is constantly updated as data providers reveal their prices and random numbers. Only the last 50 epochs can be queried and there is no bounds checking for this parameter. Out-of-bounds queries return undefined values. Returns Type Description [0] uint256 The random number used in that epoch.","title":"getRandom"},{"location":"apis/smart-contracts/IIFtso/#fn_getvoteweightingparameters_8357d08c","text":"Defined in IIFtso ( Docs , Source ). function getVoteWeightingParameters ( ) external view returns ( contract IIVPToken [] _assets , uint256 [] _assetMultipliers , uint256 _totalVotePowerNat , uint256 _totalVotePowerAsset , uint256 _assetWeightRatio , uint256 _votePowerBlock ); Returns parameters necessary for replicating vote weighting (used in VoterWhitelister ). Returns Type Description _assets contract IIVPToken[] The list of assets that are accounted in vote. _assetMultipliers uint256[] Weight multiplier of each asset in (multiasset) FTSO. _totalVotePowerNat uint256 Total native token vote power at block. _totalVotePowerAsset uint256 Total combined asset vote power at block. _assetWeightRatio uint256 Ratio of combined asset vote power vs. native token vp (in BIPS). _votePowerBlock uint256 Vote power block for the epoch.","title":"getVoteWeightingParameters"},{"location":"apis/smart-contracts/IIFtso/#fn_initializecurrentepochstateforreveal_f670ebe3","text":"Defined in IIFtso ( Docs , Source ). function initializeCurrentEpochStateForReveal ( uint256 _circulatingSupplyNat , bool _fallbackMode ) external ; Initializes current epoch instance for reveal. Parameters Type Description _circulatingSupplyNat uint256 Epoch native token circulating supply. _fallbackMode bool Whether the current epoch is in fallback mode.","title":"initializeCurrentEpochStateForReveal"},{"location":"apis/smart-contracts/IIFtso/#fn_revealpricesubmitter_c1f6c36e","text":"Defined in IFtsoGenesis ( Docs , Source ). function revealPriceSubmitter ( address _voter , uint256 _epochId , uint256 _price , uint256 _voterWNatVP ) external ; Reveals the price submitted by a voter on a specific epoch. The hash of _price and _random must be equal to the submitted hash Parameters Type Description _voter address Voter address. _epochId uint256 ID of the epoch in which the price hash was submitted. _price uint256 Submitted price. _voterWNatVP uint256 Voter's vote power in WNat units.","title":"revealPriceSubmitter"},{"location":"apis/smart-contracts/IIFtso/#fn_setasset_d0d552dd","text":"Defined in IIFtso ( Docs , Source ). function setAsset ( contract IIVPToken _asset ) external ; Sets asset for FTSO to operate as single-asset oracle. Parameters Type Description _asset contract IIVPToken Address of the IIVPToken contract that will be the asset tracked by this FTSO.","title":"setAsset"},{"location":"apis/smart-contracts/IIFtso/#fn_setassetftsos_131fdee2","text":"Defined in IIFtso ( Docs , Source ). function setAssetFtsos ( contract IIFtso [] _assetFtsos ) external ; Sets an array of FTSOs for FTSO to operate as multi-asset oracle. FTSOs implicitly determine the FTSO assets. Parameters Type Description _assetFtsos contract IIFtso[] Array of FTSOs.","title":"setAssetFtsos"},{"location":"apis/smart-contracts/IIFtso/#fn_setvotepowerblock_e536f396","text":"Defined in IIFtso ( Docs , Source ). function setVotePowerBlock ( uint256 _blockNumber ) external ; Sets the current vote power block. Current vote power block will update per reward epoch. The FTSO doesn't have notion of reward epochs. Parameters Type Description _blockNumber uint256 Vote power block.","title":"setVotePowerBlock"},{"location":"apis/smart-contracts/IIFtso/#fn_symbol_95d89b41","text":"Defined in IFtso ( Docs , Source ). function symbol ( ) external view returns ( string ); Returns the FTSO symbol .","title":"symbol"},{"location":"apis/smart-contracts/IIFtso/#fn_updateinitialprice_306ba253","text":"Defined in IIFtso ( Docs , Source ). function updateInitialPrice ( uint256 _initialPriceUSD , uint256 _initialPriceTimestamp ) external ; Updates initial asset price when the contract is not active yet.","title":"updateInitialPrice"},{"location":"apis/smart-contracts/IIFtso/#fn_wnat_9edbf007","text":"Defined in IIFtso ( Docs , Source ). function wNat ( ) external view returns ( contract IIVPToken ); Address of the WNat contract. Returns Type Description [0] contract IIVPToken Address of the WNat contract.","title":"wNat"},{"location":"apis/smart-contracts/IIFtso/#fn_wnatvotepowercached_f72cab28","text":"Defined in IFtsoGenesis ( Docs , Source ). function wNatVotePowerCached ( address _voter , uint256 _epochId ) external returns ( uint256 ); Get and cache the vote power of a voter on a specific epoch, in WNat units. Parameters Type Description _voter address Voter address. _epochId uint256 ID of the epoch in which the price hash was submitted. Returns Type Description [0] uint256 Voter's vote power in WNat units.","title":"wNatVotePowerCached"},{"location":"apis/smart-contracts/IIFtsoManager/","text":"IIFtsoManager # Source | Inherits from IFtsoManager , IFlareDaemonize Internal interface for the FtsoManager contract. Events # AccruingUnearnedRewardsFailed # Defined in IFtsoManager ( Docs , Source ). event AccruingUnearnedRewardsFailed ( uint256 epochId ) Unexpected failure while accruing unearned rewards. This should be a rare occurrence. Parameters Type Description epochId uint256 Epoch ID of the failure. ChillingNonrevealingDataProvidersFailed # Defined in IIFtsoManager ( Docs , Source ). event ChillingNonrevealingDataProvidersFailed ( ) Unexpected failure. This should be a rare occurrence. CleanupBlockNumberManagerFailedForBlock # Defined in IIFtsoManager ( Docs , Source ). event CleanupBlockNumberManagerFailedForBlock ( uint256 blockNumber ) Unexpected failure. This should be a rare occurrence. ClosingExpiredRewardEpochFailed # Defined in IIFtsoManager ( Docs , Source ). event ClosingExpiredRewardEpochFailed ( uint256 rewardEpoch ) Unexpected failure. This should be a rare occurrence. DistributingRewardsFailed # Defined in IFtsoManager ( Docs , Source ). event DistributingRewardsFailed ( address ftso , uint256 epochId ) Unexpected failure while distributing rewards. This should be a rare occurrence. Parameters Type Description ftso address Contract address of the FTSO where the failure happened. epochId uint256 Epoch ID of the failure. FallbackMode # Defined in IFtsoManager ( Docs , Source ). event FallbackMode ( bool fallbackMode ) Emitted when the fallback mode of the FTSO manager changes its state. Fallback mode is a recovery mode, where only data from a trusted subset of FTSO data providers is used to calculate the final price. The FTSO Manager enters the fallback mode when ALL FTSOs are in fallback mode. Parameters Type Description fallbackMode bool New state of the FTSO Manager fallback mode. FinalizingPriceEpochFailed # Defined in IFtsoManager ( Docs , Source ). event FinalizingPriceEpochFailed ( contract IIFtso ftso , uint256 epochId , enum IFtso . PriceFinalizationType failingType ) Unexpected failure while finalizing a price epoch. This should be a rare occurrence. Parameters Type Description ftso contract IIFtso Contract address of the FTSO where the failure happened. epochId uint256 Epoch ID of the failure. failingType enum IFtso.PriceFinalizationType How was the epoch finalized. FtsoAdded # Defined in IFtsoManager ( Docs , Source ). event FtsoAdded ( contract IIFtso ftso , bool add ) Emitted when a new FTSO has been added or an existing one has been removed. Parameters Type Description ftso contract IIFtso Contract address of the FTSO. add bool True if added, removed otherwise. FtsoDeactivationFailed # Defined in IIFtsoManager ( Docs , Source ). event FtsoDeactivationFailed ( contract IIFtso ftso ) Unexpected failure. This should be a rare occurrence. FtsoFallbackMode # Defined in IFtsoManager ( Docs , Source ). event FtsoFallbackMode ( contract IIFtso ftso , bool fallbackMode ) Emitted when the fallback mode of an FTSO changes its state. Parameters Type Description ftso contract IIFtso Contract address of the FTSO. fallbackMode bool New state of its fallback mode. InitializingCurrentEpochStateForRevealFailed # Defined in IFtsoManager ( Docs , Source ). event InitializingCurrentEpochStateForRevealFailed ( contract IIFtso ftso , uint256 epochId ) Unexpected failure while initializing a price epoch. This should be a rare occurrence. Parameters Type Description ftso contract IIFtso Contract address of the FTSO where the failure happened. epochId uint256 Epoch ID that failed initialization. PriceEpochFinalized # Defined in IFtsoManager ( Docs , Source ). event PriceEpochFinalized ( address chosenFtso , uint256 rewardEpochId ) Emitted when a price epoch ends, this is, after the reveal phase, when final prices are calculated. Parameters Type Description chosenFtso address Contract address of the FTSO asset that was randomly chosen to be the basis for reward calculation. On this price epoch, rewards will be calculated based on how close each data provider was to the median of all submitted prices FOR THIS FTSO. rewardEpochId uint256 Reward epoch ID this price epoch belongs to. RewardEpochFinalized # Defined in IFtsoManager ( Docs , Source ). event RewardEpochFinalized ( uint256 votepowerBlock , uint256 startBlock ) Emitted when a reward epoch ends and rewards are available. Parameters Type Description votepowerBlock uint256 The vote power block of the epoch. startBlock uint256 The first block of the epoch. UpdatingActiveValidatorsTriggerFailed # Defined in IIFtsoManager ( Docs , Source ). event UpdatingActiveValidatorsTriggerFailed ( uint256 rewardEpoch ) Unexpected failure. This should be a rare occurrence. UseGoodRandomSet # Defined in IFtsoManager ( Docs , Source ). event UseGoodRandomSet ( bool useGoodRandom , uint256 maxWaitForGoodRandomSeconds ) Emitted when the requirement to provide good random numbers has changed. As part of the FTSO protocol , data providers must submit a random number along with their price reveals. When good random numbers are enforced, all providers that submit a hash must then submit a reveal with a random number or they will be punished. This is a measure against random number manipulation. Parameters Type Description useGoodRandom bool Whether good random numbers are now enforced or not. maxWaitForGoodRandomSeconds uint256 Max number of seconds to wait for a good random number to be submitted. Functions # activate # Defined in IIFtsoManager ( Docs , Source ). function activate ( ) external ; Activates FTSO manager ( daemonize will run jobs). active # Defined in IFtsoManager ( Docs , Source ). function active ( ) external view returns ( bool ); Returns whether the FTSO Manager is active or not. Returns Type Description [0] bool bool Active status. addFtso # Defined in IIFtsoManager ( Docs , Source ). function addFtso ( contract IIFtso _ftso ) external ; Adds FTSO to the list of managed FTSOs, to support a new price pair. All FTSOs in a multi-asset FTSO must be managed by the same FTSO manager. Parameters Type Description _ftso contract IIFtso FTSO contract address to add. addFtsosBulk # Defined in IIFtsoManager ( Docs , Source ). function addFtsosBulk ( contract IIFtso [] _ftsos ) external ; Adds a list of FTSOs to the list of managed FTSOs, to support new price pairs. All FTSOs in a multi-asset FTSO must be managed by the same FTSO manager. Parameters Type Description _ftsos contract IIFtso[] Array of FTSO contract addresses to add. currentRewardEpochEnds # Defined in IIFtsoManager ( Docs , Source ). function currentRewardEpochEnds ( ) external view returns ( uint256 ); Returns when the current reward epoch finishes. Returns Type Description [0] uint256 uint256 Time in seconds since the UNIX epoch when the current reward epoch will finish. daemonize # Defined in IFlareDaemonize ( Docs , Source ). function daemonize ( ) external returns ( bool ); Implement this function to receive a trigger from the FlareDaemon . The trigger method is called by the validator right at the end of block state transition. Returns Type Description [0] bool bool Whether the contract is still active after the call. Currently unused. getContractName # Defined in IFlareDaemonize ( Docs , Source ). function getContractName ( ) external view returns ( string ); Implement this function to allow updating daemonized contracts through the AddressUpdater . Returns Type Description [0] string string Contract name. getCurrentPriceEpochData # Defined in IFtsoManager ( Docs , Source ). function getCurrentPriceEpochData ( ) external view returns ( uint256 _priceEpochId , uint256 _priceEpochStartTimestamp , uint256 _priceEpochEndTimestamp , uint256 _priceEpochRevealEndTimestamp , uint256 _currentTimestamp ); Returns timing information for the current price epoch. All intervals are half-closed: end time is not included. All timestamps are in seconds since UNIX epoch. See the FTSO page for information about the different submission phases. Returns Type Description _priceEpochId uint256 Price epoch ID. _priceEpochStartTimestamp uint256 Beginning of the commit phase. _priceEpochEndTimestamp uint256 End of the commit phase. _priceEpochRevealEndTimestamp uint256 End of the reveal phase. _currentTimestamp uint256 Current time. getCurrentPriceEpochId # Defined in IFtsoManagerGenesis ( Docs , Source ). function getCurrentPriceEpochId ( ) external view returns ( uint256 _priceEpochId ); Returns current price epoch ID. Returns Type Description _priceEpochId uint256 Currently running epoch ID. IDs are consecutive numbers starting from zero. getCurrentRewardEpoch # Defined in IFtsoManager ( Docs , Source ). function getCurrentRewardEpoch ( ) external view returns ( uint256 ); Returns current reward epoch ID (the one currently running). Returns Type Description [0] uint256 Reward epoch ID. A monotonically increasing integer. getElasticBandWidthPPMFtso # Defined in IIFtsoManager ( Docs , Source ). function getElasticBandWidthPPMFtso ( contract IIFtso _ftso ) external view returns ( uint256 ); Returns the secondary band's width in PPM (parts-per-million) of the median value, for a given FTSO. Parameters Type Description _ftso contract IIFtso The queried FTSO contract address. Returns Type Description [0] uint256 uint256 Secondary band width in PPM. To obtain the actual band width, divide this number by 10^6 and multiply by the price median value. getFallbackMode # Defined in IFtsoManager ( Docs , Source ). function getFallbackMode ( ) external view returns ( bool _fallbackMode , contract IIFtso [] _ftsos , bool [] _ftsoInFallbackMode ); Returns whether the FTSO Manager is currently in fallback mode. In this mode only submissions from trusted providers are used. Returns Type Description _fallbackMode bool True if fallback mode is enabled for the manager. _ftsos contract IIFtso[] Array of all currently active FTSO assets. _ftsoInFallbackMode bool[] Boolean array indicating which FTSO assets are in fallback mode. If the FTSO Manager is in fallback mode then ALL FTSOs are in fallback mode. getFtsos # Defined in IFtsoManager ( Docs , Source ). function getFtsos ( ) external view returns ( contract IIFtso [] _ftsos ); Returns the list of currently active FTSOs. Returns Type Description _ftsos contract IIFtso[] Array of contract addresses for the FTSOs. getLastUnprocessedPriceEpochData # Defined in IIFtsoManager ( Docs , Source ). function getLastUnprocessedPriceEpochData ( ) external view returns ( uint256 _lastUnprocessedPriceEpoch , uint256 _lastUnprocessedPriceEpochRevealEnds , bool _lastUnprocessedPriceEpochInitialized ); Returns information regarding the currently unprocessed price epoch. This epoch is not necessarily the last one, in case the network halts for some time due to validator node problems, for example. Returns Type Description _lastUnprocessedPriceEpoch uint256 ID of the price epoch that is currently waiting finalization. _lastUnprocessedPriceEpochRevealEnds uint256 When that price epoch can be finalized, in seconds since UNIX epoch. _lastUnprocessedPriceEpochInitialized bool Whether this price epoch has been already initialized and therefore it must be finalized before the corresponding reward epoch can be finalized. getPriceEpochConfiguration # Defined in IFtsoManager ( Docs , Source ). function getPriceEpochConfiguration ( ) external view returns ( uint256 _firstPriceEpochStartTs , uint256 _priceEpochDurationSeconds , uint256 _revealEpochDurationSeconds ); Returns the current values for price epoch timing configuration. See the FTSO page for information about the different submission phases. Returns Type Description _firstPriceEpochStartTs uint256 Timestamp, in seconds since UNIX epoch, of the first price epoch. _priceEpochDurationSeconds uint256 Duration in seconds of the commit phase. _revealEpochDurationSeconds uint256 Duration in seconds of the reveal phase. getRewardEpochConfiguration # Defined in IFtsoManager ( Docs , Source ). function getRewardEpochConfiguration ( ) external view returns ( uint256 _firstRewardEpochStartTs , uint256 _rewardEpochDurationSeconds ); Returns the current values for reward epoch timing configuration. See the Reward epochs box. Returns Type Description _firstRewardEpochStartTs uint256 Timestamp, in seconds since UNIX epoch, of the first reward epoch. _rewardEpochDurationSeconds uint256 Duration in seconds of the reward epochs. getRewardEpochData # Defined in IIFtsoManager ( Docs , Source ). function getRewardEpochData ( uint256 _rewardEpochId ) external view returns ( struct IIFtsoManager . RewardEpochData ); Returns data regarding a specific reward epoch ID. Parameters Type Description _rewardEpochId uint256 Epoch ID. Returns Type Description [0] struct IIFtsoManager.RewardEpochData RewardEpochData Its associated data. getRewardEpochToExpireNext # Defined in IFtsoManager ( Docs , Source ). function getRewardEpochToExpireNext ( ) external view returns ( uint256 ); Return reward epoch that will expire next, when a new reward epoch is initialized. Reward epochs older than 90 days expire, and any unclaimed rewards in them become inaccessible. Returns Type Description [0] uint256 uint256 Reward epoch ID. getRewardEpochVotePowerBlock # Defined in IFtsoManager ( Docs , Source ). function getRewardEpochVotePowerBlock ( uint256 _rewardEpoch ) external view returns ( uint256 ); Returns the vote power block that was used for a past reward epoch. Parameters Type Description _rewardEpoch uint256 The queried reward epoch ID. Returns Type Description [0] uint256 uint256 The block number of that reward epoch's vote power block. getRewardExpiryOffsetSeconds # Defined in IIFtsoManager ( Docs , Source ). function getRewardExpiryOffsetSeconds ( ) external view returns ( uint256 ); Returns the currently configured reward expiration time. Returns Type Description [0] uint256 uint256 Unclaimed rewards accrued in reward epochs more than this amount of seconds in the past expire and become inaccessible. notInitializedFtsos # Defined in IIFtsoManager ( Docs , Source ). function notInitializedFtsos ( contract IIFtso ) external view returns ( bool ); Returns whether an FTSO has been initialized. Returns Type Description [0] bool bool Initialization state. removeFtso # Defined in IIFtsoManager ( Docs , Source ). function removeFtso ( contract IIFtso _ftso ) external ; Removes an FTSO from the list of managed FTSOs. Reverts if FTSO is used in a multi-asset FTSO. Deactivates the _ftso . Parameters Type Description _ftso contract IIFtso FTSO contract address to remove. replaceFtso # Defined in IIFtsoManager ( Docs , Source ). function replaceFtso ( contract IIFtso _ftsoToAdd , bool copyCurrentPrice , bool copyAssetOrAssetFtsos ) external ; Replaces one FTSO with another with the same symbol. All FTSOs in a multi-asset FTSO must be managed by the same FTSO manager. Deactivates the old FTSO. Parameters Type Description _ftsoToAdd contract IIFtso FTSO contract address to add. An existing FTSO with the same symbol will be removed. copyCurrentPrice bool When true, initializes the new FTSO with the current price of the previous FTSO. copyAssetOrAssetFtsos bool When true, initializes the new FTSO with the current asset or asset FTSOs of the previous FTSO. replaceFtsosBulk # Defined in IIFtsoManager ( Docs , Source ). function replaceFtsosBulk ( contract IIFtso [] _ftsosToAdd , bool copyCurrentPrice , bool copyAssetOrAssetFtsos ) external ; Replaces a list of FTSOs with other FTSOs with the same symbol. All FTSOs in a multi-asset FTSO must be managed by the same FTSO manager. Deactivates the old FTSOs. Parameters Type Description _ftsosToAdd contract IIFtso[] Array of FTSO contract addresses to add. Every existing FTSO with the same symbols will be removed. copyCurrentPrice bool When true, initializes the new FTSOs with the current price of the previous FTSOs. copyAssetOrAssetFtsos bool When true, initializes the new FTSOs with the current asset or asset FTSOs of the previous FTSOs. rewardEpochDurationSeconds # Defined in IIFtsoManager ( Docs , Source ). function rewardEpochDurationSeconds ( ) external view returns ( uint256 ); Currently configured reward epoch duration. Returns Type Description [0] uint256 uint256 Reward epoch duration, in seconds. rewardEpochs # Defined in IIFtsoManager ( Docs , Source ). function rewardEpochs ( uint256 _rewardEpochId ) external view returns ( uint256 _votepowerBlock , uint256 _startBlock , uint256 _startTimestamp ); Returns information about a reward epoch. Parameters Type Description _rewardEpochId uint256 The epoch ID to query. Returns Type Description _votepowerBlock uint256 The vote power block of the epoch. _startBlock uint256 The first block of the epoch. _startTimestamp uint256 Timestamp of the epoch start, in seconds since UNIX epoch. rewardEpochsStartTs # Defined in IIFtsoManager ( Docs , Source ). function rewardEpochsStartTs ( ) external view returns ( uint256 ); Time when the current reward epoch started. Returns Type Description [0] uint256 uint256 Timestamp, in seconds since UNIX epoch. setFallbackMode # Defined in IIFtsoManager ( Docs , Source ). function setFallbackMode ( bool _fallbackMode ) external ; Sets whether the FTSO Manager is currently in fallback mode. In this mode only submissions from trusted providers are used. Parameters Type Description _fallbackMode bool True if fallback mode is enabled. setFtsoAsset # Defined in IIFtsoManager ( Docs , Source ). function setFtsoAsset ( contract IIFtso _ftso , contract IIVPToken _asset ) external ; Sets the asset tracked by an FTSO. Parameters Type Description _ftso contract IIFtso The FTSO contract address. _asset contract IIVPToken The VPToken contract address of the asset to track. setFtsoAssetFtsos # Defined in IIFtsoManager ( Docs , Source ). function setFtsoAssetFtsos ( contract IIFtso _ftso , contract IIFtso [] _assetFtsos ) external ; Sets an array of FTSOs to be tracked by a multi-asset FTSO. FTSOs implicitly determine the FTSO assets. Parameters Type Description _ftso contract IIFtso The multi-asset FTSO contract address. _assetFtsos contract IIFtso[] Array of FTSOs to be tracked. setFtsoFallbackMode # Defined in IIFtsoManager ( Docs , Source ). function setFtsoFallbackMode ( contract IIFtso _ftso , bool _fallbackMode ) external ; Sets whether an FTSO is currently in fallback mode. In this mode only submissions from trusted providers are used. Parameters Type Description _ftso contract IIFtso The FTSO contract address. _fallbackMode bool Fallback mode. setGovernanceParameters # Defined in IIFtsoManager ( Docs , Source ). function setGovernanceParameters ( uint256 _updateTs , uint256 _maxVotePowerNatThresholdFraction , uint256 _maxVotePowerAssetThresholdFraction , uint256 _lowAssetUSDThreshold , uint256 _highAssetUSDThreshold , uint256 _highAssetTurnoutThresholdBIPS , uint256 _lowNatTurnoutThresholdBIPS , uint256 _elasticBandRewardBIPS , uint256 _rewardExpiryOffsetSeconds , address [] _trustedAddresses ) external ; Sets governance parameters for FTSOs Parameters Type Description _updateTs uint256 Time, in seconds since UNIX epoch, when updated settings should be pushed to FTSOs. _maxVotePowerNatThresholdFraction uint256 High threshold for native token vote power per voter. _maxVotePowerAssetThresholdFraction uint256 High threshold for asset vote power per voter _lowAssetUSDThreshold uint256 Threshold for low asset vote power (in scaled USD). _highAssetUSDThreshold uint256 Threshold for high asset vote power (in scaled USD). _highAssetTurnoutThresholdBIPS uint256 Threshold for high asset turnout (in BIPS). _lowNatTurnoutThresholdBIPS uint256 Threshold for low nat turnout (in BIPS). _elasticBandRewardBIPS uint256 Secondary reward band, where _elasticBandRewardBIPS goes to the secondary band and 10000 - _elasticBandRewardBIPS to the primary (IQR) band. _rewardExpiryOffsetSeconds uint256 Reward epochs closed earlier than block.timestamp - _rewardExpiryOffsetSeconds expire. _trustedAddresses address[] Trusted addresses will be used as a fallback mechanism for setting the price. setInitialRewardData # Defined in IIFtsoManager ( Docs , Source ). function setInitialRewardData ( uint256 _nextRewardEpochToExpire , uint256 _rewardEpochsLength , uint256 _currentRewardEpochEnds ) external ; Set reward data to values from old ftso manager. Can only be called before activation. Parameters Type Description _nextRewardEpochToExpire uint256 See getRewardEpochToExpireNext . _rewardEpochsLength uint256 See getRewardEpochConfiguration . _currentRewardEpochEnds uint256 See getCurrentRewardEpoch . switchToFallbackMode # Defined in IFlareDaemonize ( Docs , Source ). function switchToFallbackMode ( ) external returns ( bool ); This function will be called after an error is caught in daemonize . It will switch the contract to a simpler fallback mode, which hopefully works when full mode doesn't. Not every contract needs to support fallback mode ( FtsoManager does), so this method may be empty. Switching back to normal mode is left to the contract (typically a governed method call). This function may be called due to low-gas error, so it shouldn't use more than ~30.000 gas. Returns Type Description [0] bool True if switched to fallback mode, false if already in fallback mode or if fallback mode is not supported. Structures # RewardEpochData # Defined in IIFtsoManager ( Docs , Source ). struct RewardEpochData { uint256 votepowerBlock ; uint256 startBlock ; uint256 startTimestamp ; }","title":"IIFtsoManager"},{"location":"apis/smart-contracts/IIFtsoManager/#ct_iiftsomanager","text":"Source | Inherits from IFtsoManager , IFlareDaemonize Internal interface for the FtsoManager contract.","title":"IIFtsoManager"},{"location":"apis/smart-contracts/IIFtsoManager/#events","text":"","title":"Events"},{"location":"apis/smart-contracts/IIFtsoManager/#ev_accruingunearnedrewardsfailed","text":"Defined in IFtsoManager ( Docs , Source ). event AccruingUnearnedRewardsFailed ( uint256 epochId ) Unexpected failure while accruing unearned rewards. This should be a rare occurrence. Parameters Type Description epochId uint256 Epoch ID of the failure.","title":"AccruingUnearnedRewardsFailed"},{"location":"apis/smart-contracts/IIFtsoManager/#ev_chillingnonrevealingdataprovidersfailed","text":"Defined in IIFtsoManager ( Docs , Source ). event ChillingNonrevealingDataProvidersFailed ( ) Unexpected failure. This should be a rare occurrence.","title":"ChillingNonrevealingDataProvidersFailed"},{"location":"apis/smart-contracts/IIFtsoManager/#ev_cleanupblocknumbermanagerfailedforblock","text":"Defined in IIFtsoManager ( Docs , Source ). event CleanupBlockNumberManagerFailedForBlock ( uint256 blockNumber ) Unexpected failure. This should be a rare occurrence.","title":"CleanupBlockNumberManagerFailedForBlock"},{"location":"apis/smart-contracts/IIFtsoManager/#ev_closingexpiredrewardepochfailed","text":"Defined in IIFtsoManager ( Docs , Source ). event ClosingExpiredRewardEpochFailed ( uint256 rewardEpoch ) Unexpected failure. This should be a rare occurrence.","title":"ClosingExpiredRewardEpochFailed"},{"location":"apis/smart-contracts/IIFtsoManager/#ev_distributingrewardsfailed","text":"Defined in IFtsoManager ( Docs , Source ). event DistributingRewardsFailed ( address ftso , uint256 epochId ) Unexpected failure while distributing rewards. This should be a rare occurrence. Parameters Type Description ftso address Contract address of the FTSO where the failure happened. epochId uint256 Epoch ID of the failure.","title":"DistributingRewardsFailed"},{"location":"apis/smart-contracts/IIFtsoManager/#ev_fallbackmode","text":"Defined in IFtsoManager ( Docs , Source ). event FallbackMode ( bool fallbackMode ) Emitted when the fallback mode of the FTSO manager changes its state. Fallback mode is a recovery mode, where only data from a trusted subset of FTSO data providers is used to calculate the final price. The FTSO Manager enters the fallback mode when ALL FTSOs are in fallback mode. Parameters Type Description fallbackMode bool New state of the FTSO Manager fallback mode.","title":"FallbackMode"},{"location":"apis/smart-contracts/IIFtsoManager/#ev_finalizingpriceepochfailed","text":"Defined in IFtsoManager ( Docs , Source ). event FinalizingPriceEpochFailed ( contract IIFtso ftso , uint256 epochId , enum IFtso . PriceFinalizationType failingType ) Unexpected failure while finalizing a price epoch. This should be a rare occurrence. Parameters Type Description ftso contract IIFtso Contract address of the FTSO where the failure happened. epochId uint256 Epoch ID of the failure. failingType enum IFtso.PriceFinalizationType How was the epoch finalized.","title":"FinalizingPriceEpochFailed"},{"location":"apis/smart-contracts/IIFtsoManager/#ev_ftsoadded","text":"Defined in IFtsoManager ( Docs , Source ). event FtsoAdded ( contract IIFtso ftso , bool add ) Emitted when a new FTSO has been added or an existing one has been removed. Parameters Type Description ftso contract IIFtso Contract address of the FTSO. add bool True if added, removed otherwise.","title":"FtsoAdded"},{"location":"apis/smart-contracts/IIFtsoManager/#ev_ftsodeactivationfailed","text":"Defined in IIFtsoManager ( Docs , Source ). event FtsoDeactivationFailed ( contract IIFtso ftso ) Unexpected failure. This should be a rare occurrence.","title":"FtsoDeactivationFailed"},{"location":"apis/smart-contracts/IIFtsoManager/#ev_ftsofallbackmode","text":"Defined in IFtsoManager ( Docs , Source ). event FtsoFallbackMode ( contract IIFtso ftso , bool fallbackMode ) Emitted when the fallback mode of an FTSO changes its state. Parameters Type Description ftso contract IIFtso Contract address of the FTSO. fallbackMode bool New state of its fallback mode.","title":"FtsoFallbackMode"},{"location":"apis/smart-contracts/IIFtsoManager/#ev_initializingcurrentepochstateforrevealfailed","text":"Defined in IFtsoManager ( Docs , Source ). event InitializingCurrentEpochStateForRevealFailed ( contract IIFtso ftso , uint256 epochId ) Unexpected failure while initializing a price epoch. This should be a rare occurrence. Parameters Type Description ftso contract IIFtso Contract address of the FTSO where the failure happened. epochId uint256 Epoch ID that failed initialization.","title":"InitializingCurrentEpochStateForRevealFailed"},{"location":"apis/smart-contracts/IIFtsoManager/#ev_priceepochfinalized","text":"Defined in IFtsoManager ( Docs , Source ). event PriceEpochFinalized ( address chosenFtso , uint256 rewardEpochId ) Emitted when a price epoch ends, this is, after the reveal phase, when final prices are calculated. Parameters Type Description chosenFtso address Contract address of the FTSO asset that was randomly chosen to be the basis for reward calculation. On this price epoch, rewards will be calculated based on how close each data provider was to the median of all submitted prices FOR THIS FTSO. rewardEpochId uint256 Reward epoch ID this price epoch belongs to.","title":"PriceEpochFinalized"},{"location":"apis/smart-contracts/IIFtsoManager/#ev_rewardepochfinalized","text":"Defined in IFtsoManager ( Docs , Source ). event RewardEpochFinalized ( uint256 votepowerBlock , uint256 startBlock ) Emitted when a reward epoch ends and rewards are available. Parameters Type Description votepowerBlock uint256 The vote power block of the epoch. startBlock uint256 The first block of the epoch.","title":"RewardEpochFinalized"},{"location":"apis/smart-contracts/IIFtsoManager/#ev_updatingactivevalidatorstriggerfailed","text":"Defined in IIFtsoManager ( Docs , Source ). event UpdatingActiveValidatorsTriggerFailed ( uint256 rewardEpoch ) Unexpected failure. This should be a rare occurrence.","title":"UpdatingActiveValidatorsTriggerFailed"},{"location":"apis/smart-contracts/IIFtsoManager/#ev_usegoodrandomset","text":"Defined in IFtsoManager ( Docs , Source ). event UseGoodRandomSet ( bool useGoodRandom , uint256 maxWaitForGoodRandomSeconds ) Emitted when the requirement to provide good random numbers has changed. As part of the FTSO protocol , data providers must submit a random number along with their price reveals. When good random numbers are enforced, all providers that submit a hash must then submit a reveal with a random number or they will be punished. This is a measure against random number manipulation. Parameters Type Description useGoodRandom bool Whether good random numbers are now enforced or not. maxWaitForGoodRandomSeconds uint256 Max number of seconds to wait for a good random number to be submitted.","title":"UseGoodRandomSet"},{"location":"apis/smart-contracts/IIFtsoManager/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_activate_0f15f4c0","text":"Defined in IIFtsoManager ( Docs , Source ). function activate ( ) external ; Activates FTSO manager ( daemonize will run jobs).","title":"activate"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_active_02fb0c5e","text":"Defined in IFtsoManager ( Docs , Source ). function active ( ) external view returns ( bool ); Returns whether the FTSO Manager is active or not. Returns Type Description [0] bool bool Active status.","title":"active"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_addftso_2663f1b4","text":"Defined in IIFtsoManager ( Docs , Source ). function addFtso ( contract IIFtso _ftso ) external ; Adds FTSO to the list of managed FTSOs, to support a new price pair. All FTSOs in a multi-asset FTSO must be managed by the same FTSO manager. Parameters Type Description _ftso contract IIFtso FTSO contract address to add.","title":"addFtso"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_addftsosbulk_d429cfe5","text":"Defined in IIFtsoManager ( Docs , Source ). function addFtsosBulk ( contract IIFtso [] _ftsos ) external ; Adds a list of FTSOs to the list of managed FTSOs, to support new price pairs. All FTSOs in a multi-asset FTSO must be managed by the same FTSO manager. Parameters Type Description _ftsos contract IIFtso[] Array of FTSO contract addresses to add.","title":"addFtsosBulk"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_currentrewardepochends_d89c39e6","text":"Defined in IIFtsoManager ( Docs , Source ). function currentRewardEpochEnds ( ) external view returns ( uint256 ); Returns when the current reward epoch finishes. Returns Type Description [0] uint256 uint256 Time in seconds since the UNIX epoch when the current reward epoch will finish.","title":"currentRewardEpochEnds"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_daemonize_6d0e8c34","text":"Defined in IFlareDaemonize ( Docs , Source ). function daemonize ( ) external returns ( bool ); Implement this function to receive a trigger from the FlareDaemon . The trigger method is called by the validator right at the end of block state transition. Returns Type Description [0] bool bool Whether the contract is still active after the call. Currently unused.","title":"daemonize"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_getcontractname_f5f5ba72","text":"Defined in IFlareDaemonize ( Docs , Source ). function getContractName ( ) external view returns ( string ); Implement this function to allow updating daemonized contracts through the AddressUpdater . Returns Type Description [0] string string Contract name.","title":"getContractName"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_getcurrentpriceepochdata_93a79025","text":"Defined in IFtsoManager ( Docs , Source ). function getCurrentPriceEpochData ( ) external view returns ( uint256 _priceEpochId , uint256 _priceEpochStartTimestamp , uint256 _priceEpochEndTimestamp , uint256 _priceEpochRevealEndTimestamp , uint256 _currentTimestamp ); Returns timing information for the current price epoch. All intervals are half-closed: end time is not included. All timestamps are in seconds since UNIX epoch. See the FTSO page for information about the different submission phases. Returns Type Description _priceEpochId uint256 Price epoch ID. _priceEpochStartTimestamp uint256 Beginning of the commit phase. _priceEpochEndTimestamp uint256 End of the commit phase. _priceEpochRevealEndTimestamp uint256 End of the reveal phase. _currentTimestamp uint256 Current time.","title":"getCurrentPriceEpochData"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_getcurrentpriceepochid_08a7f402","text":"Defined in IFtsoManagerGenesis ( Docs , Source ). function getCurrentPriceEpochId ( ) external view returns ( uint256 _priceEpochId ); Returns current price epoch ID. Returns Type Description _priceEpochId uint256 Currently running epoch ID. IDs are consecutive numbers starting from zero.","title":"getCurrentPriceEpochId"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_getcurrentrewardepoch_e7c830d4","text":"Defined in IFtsoManager ( Docs , Source ). function getCurrentRewardEpoch ( ) external view returns ( uint256 ); Returns current reward epoch ID (the one currently running). Returns Type Description [0] uint256 Reward epoch ID. A monotonically increasing integer.","title":"getCurrentRewardEpoch"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_getelasticbandwidthppmftso_5bb44e9a","text":"Defined in IIFtsoManager ( Docs , Source ). function getElasticBandWidthPPMFtso ( contract IIFtso _ftso ) external view returns ( uint256 ); Returns the secondary band's width in PPM (parts-per-million) of the median value, for a given FTSO. Parameters Type Description _ftso contract IIFtso The queried FTSO contract address. Returns Type Description [0] uint256 uint256 Secondary band width in PPM. To obtain the actual band width, divide this number by 10^6 and multiply by the price median value.","title":"getElasticBandWidthPPMFtso"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_getfallbackmode_4b48dd5e","text":"Defined in IFtsoManager ( Docs , Source ). function getFallbackMode ( ) external view returns ( bool _fallbackMode , contract IIFtso [] _ftsos , bool [] _ftsoInFallbackMode ); Returns whether the FTSO Manager is currently in fallback mode. In this mode only submissions from trusted providers are used. Returns Type Description _fallbackMode bool True if fallback mode is enabled for the manager. _ftsos contract IIFtso[] Array of all currently active FTSO assets. _ftsoInFallbackMode bool[] Boolean array indicating which FTSO assets are in fallback mode. If the FTSO Manager is in fallback mode then ALL FTSOs are in fallback mode.","title":"getFallbackMode"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_getftsos_ce69f833","text":"Defined in IFtsoManager ( Docs , Source ). function getFtsos ( ) external view returns ( contract IIFtso [] _ftsos ); Returns the list of currently active FTSOs. Returns Type Description _ftsos contract IIFtso[] Array of contract addresses for the FTSOs.","title":"getFtsos"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_getlastunprocessedpriceepochdata_6ca051e6","text":"Defined in IIFtsoManager ( Docs , Source ). function getLastUnprocessedPriceEpochData ( ) external view returns ( uint256 _lastUnprocessedPriceEpoch , uint256 _lastUnprocessedPriceEpochRevealEnds , bool _lastUnprocessedPriceEpochInitialized ); Returns information regarding the currently unprocessed price epoch. This epoch is not necessarily the last one, in case the network halts for some time due to validator node problems, for example. Returns Type Description _lastUnprocessedPriceEpoch uint256 ID of the price epoch that is currently waiting finalization. _lastUnprocessedPriceEpochRevealEnds uint256 When that price epoch can be finalized, in seconds since UNIX epoch. _lastUnprocessedPriceEpochInitialized bool Whether this price epoch has been already initialized and therefore it must be finalized before the corresponding reward epoch can be finalized.","title":"getLastUnprocessedPriceEpochData"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_getpriceepochconfiguration_144e1591","text":"Defined in IFtsoManager ( Docs , Source ). function getPriceEpochConfiguration ( ) external view returns ( uint256 _firstPriceEpochStartTs , uint256 _priceEpochDurationSeconds , uint256 _revealEpochDurationSeconds ); Returns the current values for price epoch timing configuration. See the FTSO page for information about the different submission phases. Returns Type Description _firstPriceEpochStartTs uint256 Timestamp, in seconds since UNIX epoch, of the first price epoch. _priceEpochDurationSeconds uint256 Duration in seconds of the commit phase. _revealEpochDurationSeconds uint256 Duration in seconds of the reveal phase.","title":"getPriceEpochConfiguration"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_getrewardepochconfiguration_1cb513f7","text":"Defined in IFtsoManager ( Docs , Source ). function getRewardEpochConfiguration ( ) external view returns ( uint256 _firstRewardEpochStartTs , uint256 _rewardEpochDurationSeconds ); Returns the current values for reward epoch timing configuration. See the Reward epochs box. Returns Type Description _firstRewardEpochStartTs uint256 Timestamp, in seconds since UNIX epoch, of the first reward epoch. _rewardEpochDurationSeconds uint256 Duration in seconds of the reward epochs.","title":"getRewardEpochConfiguration"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_getrewardepochdata_e5399da3","text":"Defined in IIFtsoManager ( Docs , Source ). function getRewardEpochData ( uint256 _rewardEpochId ) external view returns ( struct IIFtsoManager . RewardEpochData ); Returns data regarding a specific reward epoch ID. Parameters Type Description _rewardEpochId uint256 Epoch ID. Returns Type Description [0] struct IIFtsoManager.RewardEpochData RewardEpochData Its associated data.","title":"getRewardEpochData"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_getrewardepochtoexpirenext_3e7ff857","text":"Defined in IFtsoManager ( Docs , Source ). function getRewardEpochToExpireNext ( ) external view returns ( uint256 ); Return reward epoch that will expire next, when a new reward epoch is initialized. Reward epochs older than 90 days expire, and any unclaimed rewards in them become inaccessible. Returns Type Description [0] uint256 uint256 Reward epoch ID.","title":"getRewardEpochToExpireNext"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_getrewardepochvotepowerblock_f2edab5a","text":"Defined in IFtsoManager ( Docs , Source ). function getRewardEpochVotePowerBlock ( uint256 _rewardEpoch ) external view returns ( uint256 ); Returns the vote power block that was used for a past reward epoch. Parameters Type Description _rewardEpoch uint256 The queried reward epoch ID. Returns Type Description [0] uint256 uint256 The block number of that reward epoch's vote power block.","title":"getRewardEpochVotePowerBlock"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_getrewardexpiryoffsetseconds_ec31db0c","text":"Defined in IIFtsoManager ( Docs , Source ). function getRewardExpiryOffsetSeconds ( ) external view returns ( uint256 ); Returns the currently configured reward expiration time. Returns Type Description [0] uint256 uint256 Unclaimed rewards accrued in reward epochs more than this amount of seconds in the past expire and become inaccessible.","title":"getRewardExpiryOffsetSeconds"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_notinitializedftsos_823033a9","text":"Defined in IIFtsoManager ( Docs , Source ). function notInitializedFtsos ( contract IIFtso ) external view returns ( bool ); Returns whether an FTSO has been initialized. Returns Type Description [0] bool bool Initialization state.","title":"notInitializedFtsos"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_removeftso_a670ff87","text":"Defined in IIFtsoManager ( Docs , Source ). function removeFtso ( contract IIFtso _ftso ) external ; Removes an FTSO from the list of managed FTSOs. Reverts if FTSO is used in a multi-asset FTSO. Deactivates the _ftso . Parameters Type Description _ftso contract IIFtso FTSO contract address to remove.","title":"removeFtso"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_replaceftso_3758e679","text":"Defined in IIFtsoManager ( Docs , Source ). function replaceFtso ( contract IIFtso _ftsoToAdd , bool copyCurrentPrice , bool copyAssetOrAssetFtsos ) external ; Replaces one FTSO with another with the same symbol. All FTSOs in a multi-asset FTSO must be managed by the same FTSO manager. Deactivates the old FTSO. Parameters Type Description _ftsoToAdd contract IIFtso FTSO contract address to add. An existing FTSO with the same symbol will be removed. copyCurrentPrice bool When true, initializes the new FTSO with the current price of the previous FTSO. copyAssetOrAssetFtsos bool When true, initializes the new FTSO with the current asset or asset FTSOs of the previous FTSO.","title":"replaceFtso"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_replaceftsosbulk_758ff1da","text":"Defined in IIFtsoManager ( Docs , Source ). function replaceFtsosBulk ( contract IIFtso [] _ftsosToAdd , bool copyCurrentPrice , bool copyAssetOrAssetFtsos ) external ; Replaces a list of FTSOs with other FTSOs with the same symbol. All FTSOs in a multi-asset FTSO must be managed by the same FTSO manager. Deactivates the old FTSOs. Parameters Type Description _ftsosToAdd contract IIFtso[] Array of FTSO contract addresses to add. Every existing FTSO with the same symbols will be removed. copyCurrentPrice bool When true, initializes the new FTSOs with the current price of the previous FTSOs. copyAssetOrAssetFtsos bool When true, initializes the new FTSOs with the current asset or asset FTSOs of the previous FTSOs.","title":"replaceFtsosBulk"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_rewardepochdurationseconds_85f3c9c9","text":"Defined in IIFtsoManager ( Docs , Source ). function rewardEpochDurationSeconds ( ) external view returns ( uint256 ); Currently configured reward epoch duration. Returns Type Description [0] uint256 uint256 Reward epoch duration, in seconds.","title":"rewardEpochDurationSeconds"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_rewardepochs_a795f409","text":"Defined in IIFtsoManager ( Docs , Source ). function rewardEpochs ( uint256 _rewardEpochId ) external view returns ( uint256 _votepowerBlock , uint256 _startBlock , uint256 _startTimestamp ); Returns information about a reward epoch. Parameters Type Description _rewardEpochId uint256 The epoch ID to query. Returns Type Description _votepowerBlock uint256 The vote power block of the epoch. _startBlock uint256 The first block of the epoch. _startTimestamp uint256 Timestamp of the epoch start, in seconds since UNIX epoch.","title":"rewardEpochs"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_rewardepochsstartts_a578f55b","text":"Defined in IIFtsoManager ( Docs , Source ). function rewardEpochsStartTs ( ) external view returns ( uint256 ); Time when the current reward epoch started. Returns Type Description [0] uint256 uint256 Timestamp, in seconds since UNIX epoch.","title":"rewardEpochsStartTs"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_setfallbackmode_ff882fbb","text":"Defined in IIFtsoManager ( Docs , Source ). function setFallbackMode ( bool _fallbackMode ) external ; Sets whether the FTSO Manager is currently in fallback mode. In this mode only submissions from trusted providers are used. Parameters Type Description _fallbackMode bool True if fallback mode is enabled.","title":"setFallbackMode"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_setftsoasset_6b65cc34","text":"Defined in IIFtsoManager ( Docs , Source ). function setFtsoAsset ( contract IIFtso _ftso , contract IIVPToken _asset ) external ; Sets the asset tracked by an FTSO. Parameters Type Description _ftso contract IIFtso The FTSO contract address. _asset contract IIVPToken The VPToken contract address of the asset to track.","title":"setFtsoAsset"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_setftsoassetftsos_a93a6f42","text":"Defined in IIFtsoManager ( Docs , Source ). function setFtsoAssetFtsos ( contract IIFtso _ftso , contract IIFtso [] _assetFtsos ) external ; Sets an array of FTSOs to be tracked by a multi-asset FTSO. FTSOs implicitly determine the FTSO assets. Parameters Type Description _ftso contract IIFtso The multi-asset FTSO contract address. _assetFtsos contract IIFtso[] Array of FTSOs to be tracked.","title":"setFtsoAssetFtsos"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_setftsofallbackmode_af946af7","text":"Defined in IIFtsoManager ( Docs , Source ). function setFtsoFallbackMode ( contract IIFtso _ftso , bool _fallbackMode ) external ; Sets whether an FTSO is currently in fallback mode. In this mode only submissions from trusted providers are used. Parameters Type Description _ftso contract IIFtso The FTSO contract address. _fallbackMode bool Fallback mode.","title":"setFtsoFallbackMode"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_setgovernanceparameters_13226793","text":"Defined in IIFtsoManager ( Docs , Source ). function setGovernanceParameters ( uint256 _updateTs , uint256 _maxVotePowerNatThresholdFraction , uint256 _maxVotePowerAssetThresholdFraction , uint256 _lowAssetUSDThreshold , uint256 _highAssetUSDThreshold , uint256 _highAssetTurnoutThresholdBIPS , uint256 _lowNatTurnoutThresholdBIPS , uint256 _elasticBandRewardBIPS , uint256 _rewardExpiryOffsetSeconds , address [] _trustedAddresses ) external ; Sets governance parameters for FTSOs Parameters Type Description _updateTs uint256 Time, in seconds since UNIX epoch, when updated settings should be pushed to FTSOs. _maxVotePowerNatThresholdFraction uint256 High threshold for native token vote power per voter. _maxVotePowerAssetThresholdFraction uint256 High threshold for asset vote power per voter _lowAssetUSDThreshold uint256 Threshold for low asset vote power (in scaled USD). _highAssetUSDThreshold uint256 Threshold for high asset vote power (in scaled USD). _highAssetTurnoutThresholdBIPS uint256 Threshold for high asset turnout (in BIPS). _lowNatTurnoutThresholdBIPS uint256 Threshold for low nat turnout (in BIPS). _elasticBandRewardBIPS uint256 Secondary reward band, where _elasticBandRewardBIPS goes to the secondary band and 10000 - _elasticBandRewardBIPS to the primary (IQR) band. _rewardExpiryOffsetSeconds uint256 Reward epochs closed earlier than block.timestamp - _rewardExpiryOffsetSeconds expire. _trustedAddresses address[] Trusted addresses will be used as a fallback mechanism for setting the price.","title":"setGovernanceParameters"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_setinitialrewarddata_e080a970","text":"Defined in IIFtsoManager ( Docs , Source ). function setInitialRewardData ( uint256 _nextRewardEpochToExpire , uint256 _rewardEpochsLength , uint256 _currentRewardEpochEnds ) external ; Set reward data to values from old ftso manager. Can only be called before activation. Parameters Type Description _nextRewardEpochToExpire uint256 See getRewardEpochToExpireNext . _rewardEpochsLength uint256 See getRewardEpochConfiguration . _currentRewardEpochEnds uint256 See getCurrentRewardEpoch .","title":"setInitialRewardData"},{"location":"apis/smart-contracts/IIFtsoManager/#fn_switchtofallbackmode_e22fdece","text":"Defined in IFlareDaemonize ( Docs , Source ). function switchToFallbackMode ( ) external returns ( bool ); This function will be called after an error is caught in daemonize . It will switch the contract to a simpler fallback mode, which hopefully works when full mode doesn't. Not every contract needs to support fallback mode ( FtsoManager does), so this method may be empty. Switching back to normal mode is left to the contract (typically a governed method call). This function may be called due to low-gas error, so it shouldn't use more than ~30.000 gas. Returns Type Description [0] bool True if switched to fallback mode, false if already in fallback mode or if fallback mode is not supported.","title":"switchToFallbackMode"},{"location":"apis/smart-contracts/IIFtsoManager/#structures","text":"","title":"Structures"},{"location":"apis/smart-contracts/IIFtsoManager/#st_rewardepochdata","text":"Defined in IIFtsoManager ( Docs , Source ). struct RewardEpochData { uint256 votepowerBlock ; uint256 startBlock ; uint256 startTimestamp ; }","title":"RewardEpochData"},{"location":"apis/smart-contracts/IIFtsoRegistry/","text":"IIFtsoRegistry # Source | Inherits from IFtsoRegistry Internal interface for the FtsoRegistry contract. Functions # addFtso # Defined in IIFtsoRegistry ( Docs , Source ). function addFtso ( contract IIFtso _ftsoContract ) external returns ( uint256 ); Add a new FTSO contract to the registry. Parameters Type Description _ftsoContract contract IIFtso New target FTSO contract. Returns Type Description [0] uint256 The FTSO index assigned to the new asset. getAllCurrentPrices # Defined in IFtsoRegistry ( Docs , Source ). function getAllCurrentPrices ( ) external view returns ( struct IFtsoRegistry . PriceInfo []); Returns the current price of all supported assets. Returns Type Description [0] struct IFtsoRegistry.PriceInfo[] Array of PriceInfo structures. getCurrentPrice # Defined in IFtsoRegistry ( Docs , Source ). function getCurrentPrice ( uint256 _ftsoIndex ) external view returns ( uint256 _price , uint256 _timestamp ); Public view function to get the current price of a given active FTSO index. Reverts if the index is not supported. Parameters Type Description _ftsoIndex uint256 Index to query. Returns Type Description _price uint256 Current price of the asset in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Timestamp for when this price was updated, in seconds since UNIX epoch. getCurrentPrice # Defined in IFtsoRegistry ( Docs , Source ). function getCurrentPrice ( string _symbol ) external view returns ( uint256 _price , uint256 _timestamp ); Public view function to get the current price of a given active asset symbol. Reverts if the symbol is not supported. Parameters Type Description _symbol string Symbol to query. Returns Type Description _price uint256 Current price of the asset in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Timestamp for when this price was updated, in seconds since UNIX epoch. getCurrentPriceWithDecimals # Defined in IFtsoRegistry ( Docs , Source ). function getCurrentPriceWithDecimals ( uint256 _assetIndex ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Public view function to get the current price and decimals of a given active FTSO index. Reverts if the index is not supported. Parameters Type Description _assetIndex uint256 Index to query. Returns Type Description _price uint256 Current price of the asset in USD multiplied by 10^ _assetPriceUsdDecimals . _timestamp uint256 Timestamp for when this price was updated, in seconds since UNIX epoch. _assetPriceUsdDecimals uint256 Number of decimals used to return the _price . getCurrentPriceWithDecimals # Defined in IFtsoRegistry ( Docs , Source ). function getCurrentPriceWithDecimals ( string _symbol ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Public view function to get the current price and decimals of a given active asset symbol. Reverts if the symbol is not supported. Parameters Type Description _symbol string Symbol to query. Returns Type Description _price uint256 Current price of the asset in USD multiplied by 10^ _assetPriceUsdDecimals . _timestamp uint256 Timestamp for when this price was updated, in seconds since UNIX epoch. _assetPriceUsdDecimals uint256 Number of decimals used to return the _price . getCurrentPricesByIndices # Defined in IFtsoRegistry ( Docs , Source ). function getCurrentPricesByIndices ( uint256 [] _indices ) external view returns ( struct IFtsoRegistry . PriceInfo []); Returns the current price of a list of indices. Reverts if any of the indices is not supported. Parameters Type Description _indices uint256[] Array of indices to query. Returns Type Description [0] struct IFtsoRegistry.PriceInfo[] Array of PriceInfo structures. getCurrentPricesBySymbols # Defined in IFtsoRegistry ( Docs , Source ). function getCurrentPricesBySymbols ( string [] _symbols ) external view returns ( struct IFtsoRegistry . PriceInfo []); Returns the current price of a list of asset symbols. Reverts if any of the symbols is not supported. Parameters Type Description _symbols string[] Array of symbols to query. Returns Type Description [0] struct IFtsoRegistry.PriceInfo[] Array of PriceInfo structures. getFtso # Defined in IFtsoRegistry ( Docs , Source ). function getFtso ( uint256 _activeFtso ) external view returns ( contract IIFtso _activeFtsoAddress ); Returns the address of the FTSO contract for a given index. Reverts if unsupported index is passed. Parameters Type Description _activeFtso uint256 The queried index. Returns Type Description _activeFtsoAddress contract IIFtso FTSO contract address for the queried index. getFtsoBySymbol # Defined in IFtsoRegistry ( Docs , Source ). function getFtsoBySymbol ( string _symbol ) external view returns ( contract IIFtso _activeFtsoAddress ); Returns the address of the FTSO contract for a given symbol. Reverts if unsupported symbol is passed. Parameters Type Description _symbol string The queried symbol. Returns Type Description _activeFtsoAddress contract IIFtso FTSO contract address for the queried symbol. getFtsoIndex # Defined in IFtsoRegistry ( Docs , Source ). function getFtsoIndex ( string _symbol ) external view returns ( uint256 _assetIndex ); Returns the FTSO index corresponding to a given asset symbol. Reverts if the symbol is not supported. Parameters Type Description _symbol string Symbol to query. Returns Type Description _assetIndex uint256 The corresponding asset index. getFtsoSymbol # Defined in IFtsoRegistry ( Docs , Source ). function getFtsoSymbol ( uint256 _ftsoIndex ) external view returns ( string _symbol ); Returns the asset symbol corresponding to a given FTSO index. Reverts if the index is not supported. Parameters Type Description _ftsoIndex uint256 Index to query. Returns Type Description _symbol string The corresponding asset symbol. getFtsos # Defined in IFtsoRegistryGenesis ( Docs , Source ). function getFtsos ( uint256 [] _indices ) external view returns ( contract IFtsoGenesis [] _ftsos ); Get the addresses of the active FTSOs at the given indices. Reverts if any of the provided indices is non-existing or inactive. Parameters Type Description _indices uint256[] Array of FTSO indices to query. Returns Type Description _ftsos contract IFtsoGenesis[] The array of FTSO addresses. getSupportedFtsos # Defined in IFtsoRegistry ( Docs , Source ). function getSupportedFtsos ( ) external view returns ( contract IIFtso [] _ftsos ); Get array of all FTSO contracts for all supported asset indices. The index of FTSO in returned array does not necessarily correspond to the asset's index. Due to deletion, some indices might be unsupported. Use getSupportedIndicesAndFtsos to retrieve pairs of correct indices and FTSOs, where possible \"null\" holes are readily apparent. Returns Type Description _ftsos contract IIFtso[] Array of all supported FTSOs. getSupportedIndices # Defined in IFtsoRegistry ( Docs , Source ). function getSupportedIndices ( ) external view returns ( uint256 [] _supportedIndices ); Returns the indices of the currently supported FTSOs. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedIndices uint256[] Array of all active FTSO indices in increasing order. getSupportedIndicesAndFtsos # Defined in IFtsoRegistry ( Docs , Source ). function getSupportedIndicesAndFtsos ( ) external view returns ( uint256 [] _supportedIndices , contract IIFtso [] _ftsos ); Get all supported indices and corresponding FTSO addresses. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedIndices uint256[] Array of all supported indices. _ftsos contract IIFtso[] Array of all supported FTSO addresses. getSupportedIndicesAndSymbols # Defined in IFtsoRegistry ( Docs , Source ). function getSupportedIndicesAndSymbols ( ) external view returns ( uint256 [] _supportedIndices , string [] _supportedSymbols ); Get all supported indices and corresponding symbols. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedIndices uint256[] Array of all supported indices. _supportedSymbols string[] Array of all supported symbols. getSupportedIndicesSymbolsAndFtsos # Defined in IFtsoRegistry ( Docs , Source ). function getSupportedIndicesSymbolsAndFtsos ( ) external view returns ( uint256 [] _supportedIndices , string [] _supportedSymbols , contract IIFtso [] _ftsos ); Get all supported indices, symbols, and corresponding FTSO addresses. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedIndices uint256[] Array of all supported indices. _supportedSymbols string[] Array of all supported symbols. _ftsos contract IIFtso[] Array of all supported FTSO addresses. getSupportedSymbols # Defined in IFtsoRegistry ( Docs , Source ). function getSupportedSymbols ( ) external view returns ( string [] _supportedSymbols ); Returns the symbols of the currently supported FTSOs. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedSymbols string[] Array of all active FTSO symbols in increasing order. getSupportedSymbolsAndFtsos # Defined in IFtsoRegistry ( Docs , Source ). function getSupportedSymbolsAndFtsos ( ) external view returns ( string [] _supportedSymbols , contract IIFtso [] _ftsos ); Get all supported symbols and corresponding FTSO addresses. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedSymbols string[] Array of all supported symbols. _ftsos contract IIFtso[] Array of all supported FTSO addresses. removeFtso # Defined in IIFtsoRegistry ( Docs , Source ). function removeFtso ( contract IIFtso _ftso ) external ; Removes the FTSO and keeps part of the history. Reverts if the provided address is not supported. From now on, the index this asset was using is \"reserved\" and cannot be used again. It will not be returned in any list of currently supported assets. Parameters Type Description _ftso contract IIFtso Address of the FTSO contract to remove.","title":"IIFtsoRegistry"},{"location":"apis/smart-contracts/IIFtsoRegistry/#ct_iiftsoregistry","text":"Source | Inherits from IFtsoRegistry Internal interface for the FtsoRegistry contract.","title":"IIFtsoRegistry"},{"location":"apis/smart-contracts/IIFtsoRegistry/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IIFtsoRegistry/#fn_addftso_2663f1b4","text":"Defined in IIFtsoRegistry ( Docs , Source ). function addFtso ( contract IIFtso _ftsoContract ) external returns ( uint256 ); Add a new FTSO contract to the registry. Parameters Type Description _ftsoContract contract IIFtso New target FTSO contract. Returns Type Description [0] uint256 The FTSO index assigned to the new asset.","title":"addFtso"},{"location":"apis/smart-contracts/IIFtsoRegistry/#fn_getallcurrentprices_58f9296f","text":"Defined in IFtsoRegistry ( Docs , Source ). function getAllCurrentPrices ( ) external view returns ( struct IFtsoRegistry . PriceInfo []); Returns the current price of all supported assets. Returns Type Description [0] struct IFtsoRegistry.PriceInfo[] Array of PriceInfo structures.","title":"getAllCurrentPrices"},{"location":"apis/smart-contracts/IIFtsoRegistry/#fn_getcurrentprice_c55d0f56","text":"Defined in IFtsoRegistry ( Docs , Source ). function getCurrentPrice ( uint256 _ftsoIndex ) external view returns ( uint256 _price , uint256 _timestamp ); Public view function to get the current price of a given active FTSO index. Reverts if the index is not supported. Parameters Type Description _ftsoIndex uint256 Index to query. Returns Type Description _price uint256 Current price of the asset in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Timestamp for when this price was updated, in seconds since UNIX epoch.","title":"getCurrentPrice"},{"location":"apis/smart-contracts/IIFtsoRegistry/#fn_getcurrentprice_42a0f243","text":"Defined in IFtsoRegistry ( Docs , Source ). function getCurrentPrice ( string _symbol ) external view returns ( uint256 _price , uint256 _timestamp ); Public view function to get the current price of a given active asset symbol. Reverts if the symbol is not supported. Parameters Type Description _symbol string Symbol to query. Returns Type Description _price uint256 Current price of the asset in USD multiplied by 10^ ASSET_PRICE_USD_DECIMALS . _timestamp uint256 Timestamp for when this price was updated, in seconds since UNIX epoch.","title":"getCurrentPrice"},{"location":"apis/smart-contracts/IIFtsoRegistry/#fn_getcurrentpricewithdecimals_257cbd3a","text":"Defined in IFtsoRegistry ( Docs , Source ). function getCurrentPriceWithDecimals ( uint256 _assetIndex ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Public view function to get the current price and decimals of a given active FTSO index. Reverts if the index is not supported. Parameters Type Description _assetIndex uint256 Index to query. Returns Type Description _price uint256 Current price of the asset in USD multiplied by 10^ _assetPriceUsdDecimals . _timestamp uint256 Timestamp for when this price was updated, in seconds since UNIX epoch. _assetPriceUsdDecimals uint256 Number of decimals used to return the _price .","title":"getCurrentPriceWithDecimals"},{"location":"apis/smart-contracts/IIFtsoRegistry/#fn_getcurrentpricewithdecimals_a69afdc6","text":"Defined in IFtsoRegistry ( Docs , Source ). function getCurrentPriceWithDecimals ( string _symbol ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Public view function to get the current price and decimals of a given active asset symbol. Reverts if the symbol is not supported. Parameters Type Description _symbol string Symbol to query. Returns Type Description _price uint256 Current price of the asset in USD multiplied by 10^ _assetPriceUsdDecimals . _timestamp uint256 Timestamp for when this price was updated, in seconds since UNIX epoch. _assetPriceUsdDecimals uint256 Number of decimals used to return the _price .","title":"getCurrentPriceWithDecimals"},{"location":"apis/smart-contracts/IIFtsoRegistry/#fn_getcurrentpricesbyindices_6ba31fa1","text":"Defined in IFtsoRegistry ( Docs , Source ). function getCurrentPricesByIndices ( uint256 [] _indices ) external view returns ( struct IFtsoRegistry . PriceInfo []); Returns the current price of a list of indices. Reverts if any of the indices is not supported. Parameters Type Description _indices uint256[] Array of indices to query. Returns Type Description [0] struct IFtsoRegistry.PriceInfo[] Array of PriceInfo structures.","title":"getCurrentPricesByIndices"},{"location":"apis/smart-contracts/IIFtsoRegistry/#fn_getcurrentpricesbysymbols_79d5ea4b","text":"Defined in IFtsoRegistry ( Docs , Source ). function getCurrentPricesBySymbols ( string [] _symbols ) external view returns ( struct IFtsoRegistry . PriceInfo []); Returns the current price of a list of asset symbols. Reverts if any of the symbols is not supported. Parameters Type Description _symbols string[] Array of symbols to query. Returns Type Description [0] struct IFtsoRegistry.PriceInfo[] Array of PriceInfo structures.","title":"getCurrentPricesBySymbols"},{"location":"apis/smart-contracts/IIFtsoRegistry/#fn_getftso_d75f6d81","text":"Defined in IFtsoRegistry ( Docs , Source ). function getFtso ( uint256 _activeFtso ) external view returns ( contract IIFtso _activeFtsoAddress ); Returns the address of the FTSO contract for a given index. Reverts if unsupported index is passed. Parameters Type Description _activeFtso uint256 The queried index. Returns Type Description _activeFtsoAddress contract IIFtso FTSO contract address for the queried index.","title":"getFtso"},{"location":"apis/smart-contracts/IIFtsoRegistry/#fn_getftsobysymbol_97da6af4","text":"Defined in IFtsoRegistry ( Docs , Source ). function getFtsoBySymbol ( string _symbol ) external view returns ( contract IIFtso _activeFtsoAddress ); Returns the address of the FTSO contract for a given symbol. Reverts if unsupported symbol is passed. Parameters Type Description _symbol string The queried symbol. Returns Type Description _activeFtsoAddress contract IIFtso FTSO contract address for the queried symbol.","title":"getFtsoBySymbol"},{"location":"apis/smart-contracts/IIFtsoRegistry/#fn_getftsoindex_e848da30","text":"Defined in IFtsoRegistry ( Docs , Source ). function getFtsoIndex ( string _symbol ) external view returns ( uint256 _assetIndex ); Returns the FTSO index corresponding to a given asset symbol. Reverts if the symbol is not supported. Parameters Type Description _symbol string Symbol to query. Returns Type Description _assetIndex uint256 The corresponding asset index.","title":"getFtsoIndex"},{"location":"apis/smart-contracts/IIFtsoRegistry/#fn_getftsosymbol_136d3f64","text":"Defined in IFtsoRegistry ( Docs , Source ). function getFtsoSymbol ( uint256 _ftsoIndex ) external view returns ( string _symbol ); Returns the asset symbol corresponding to a given FTSO index. Reverts if the index is not supported. Parameters Type Description _ftsoIndex uint256 Index to query. Returns Type Description _symbol string The corresponding asset symbol.","title":"getFtsoSymbol"},{"location":"apis/smart-contracts/IIFtsoRegistry/#fn_getftsos_9cb47538","text":"Defined in IFtsoRegistryGenesis ( Docs , Source ). function getFtsos ( uint256 [] _indices ) external view returns ( contract IFtsoGenesis [] _ftsos ); Get the addresses of the active FTSOs at the given indices. Reverts if any of the provided indices is non-existing or inactive. Parameters Type Description _indices uint256[] Array of FTSO indices to query. Returns Type Description _ftsos contract IFtsoGenesis[] The array of FTSO addresses.","title":"getFtsos"},{"location":"apis/smart-contracts/IIFtsoRegistry/#fn_getsupportedftsos_a40060ba","text":"Defined in IFtsoRegistry ( Docs , Source ). function getSupportedFtsos ( ) external view returns ( contract IIFtso [] _ftsos ); Get array of all FTSO contracts for all supported asset indices. The index of FTSO in returned array does not necessarily correspond to the asset's index. Due to deletion, some indices might be unsupported. Use getSupportedIndicesAndFtsos to retrieve pairs of correct indices and FTSOs, where possible \"null\" holes are readily apparent. Returns Type Description _ftsos contract IIFtso[] Array of all supported FTSOs.","title":"getSupportedFtsos"},{"location":"apis/smart-contracts/IIFtsoRegistry/#fn_getsupportedindices_798aac5b","text":"Defined in IFtsoRegistry ( Docs , Source ). function getSupportedIndices ( ) external view returns ( uint256 [] _supportedIndices ); Returns the indices of the currently supported FTSOs. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedIndices uint256[] Array of all active FTSO indices in increasing order.","title":"getSupportedIndices"},{"location":"apis/smart-contracts/IIFtsoRegistry/#fn_getsupportedindicesandftsos_06a2ba29","text":"Defined in IFtsoRegistry ( Docs , Source ). function getSupportedIndicesAndFtsos ( ) external view returns ( uint256 [] _supportedIndices , contract IIFtso [] _ftsos ); Get all supported indices and corresponding FTSO addresses. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedIndices uint256[] Array of all supported indices. _ftsos contract IIFtso[] Array of all supported FTSO addresses.","title":"getSupportedIndicesAndFtsos"},{"location":"apis/smart-contracts/IIFtsoRegistry/#fn_getsupportedindicesandsymbols_e68f283b","text":"Defined in IFtsoRegistry ( Docs , Source ). function getSupportedIndicesAndSymbols ( ) external view returns ( uint256 [] _supportedIndices , string [] _supportedSymbols ); Get all supported indices and corresponding symbols. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedIndices uint256[] Array of all supported indices. _supportedSymbols string[] Array of all supported symbols.","title":"getSupportedIndicesAndSymbols"},{"location":"apis/smart-contracts/IIFtsoRegistry/#fn_getsupportedindicessymbolsandftsos_7687542c","text":"Defined in IFtsoRegistry ( Docs , Source ). function getSupportedIndicesSymbolsAndFtsos ( ) external view returns ( uint256 [] _supportedIndices , string [] _supportedSymbols , contract IIFtso [] _ftsos ); Get all supported indices, symbols, and corresponding FTSO addresses. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedIndices uint256[] Array of all supported indices. _supportedSymbols string[] Array of all supported symbols. _ftsos contract IIFtso[] Array of all supported FTSO addresses.","title":"getSupportedIndicesSymbolsAndFtsos"},{"location":"apis/smart-contracts/IIFtsoRegistry/#fn_getsupportedsymbols_ce1c0e4d","text":"Defined in IFtsoRegistry ( Docs , Source ). function getSupportedSymbols ( ) external view returns ( string [] _supportedSymbols ); Returns the symbols of the currently supported FTSOs. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedSymbols string[] Array of all active FTSO symbols in increasing order.","title":"getSupportedSymbols"},{"location":"apis/smart-contracts/IIFtsoRegistry/#fn_getsupportedsymbolsandftsos_0cf48497","text":"Defined in IFtsoRegistry ( Docs , Source ). function getSupportedSymbolsAndFtsos ( ) external view returns ( string [] _supportedSymbols , contract IIFtso [] _ftsos ); Get all supported symbols and corresponding FTSO addresses. Active FTSOs are ones that currently receive price feeds. Returns Type Description _supportedSymbols string[] Array of all supported symbols. _ftsos contract IIFtso[] Array of all supported FTSO addresses.","title":"getSupportedSymbolsAndFtsos"},{"location":"apis/smart-contracts/IIFtsoRegistry/#fn_removeftso_a670ff87","text":"Defined in IIFtsoRegistry ( Docs , Source ). function removeFtso ( contract IIFtso _ftso ) external ; Removes the FTSO and keeps part of the history. Reverts if the provided address is not supported. From now on, the index this asset was using is \"reserved\" and cannot be used again. It will not be returned in any list of currently supported assets. Parameters Type Description _ftso contract IIFtso Address of the FTSO contract to remove.","title":"removeFtso"},{"location":"apis/smart-contracts/IIFtsoRewardManager/","text":"IIFtsoRewardManager # Source | Inherits from IFtsoRewardManager , IIInflationReceiver , IITokenPool Internal interface for the FtsoRewardManager . Events # DailyAuthorizedInflationSet # Defined in IIFtsoRewardManager ( Docs , Source ). event DailyAuthorizedInflationSet ( uint256 authorizedAmountWei ) Emitted when the contract's daily authorized inflation has been set. Parameters Type Description authorizedAmountWei uint256 Authorized amount of native tokens, in wei. FeePercentageChanged # Defined in IFtsoRewardManager ( Docs , Source ). event FeePercentageChanged ( address dataProvider , uint256 value , uint256 validFromEpoch ) Emitted when a data provider changes its fee. Parameters Type Description dataProvider address Address of the data provider. value uint256 New fee, in BIPS. validFromEpoch uint256 Epoch ID where the new fee takes effect. FtsoRewardManagerActivated # Defined in IFtsoRewardManager ( Docs , Source ). event FtsoRewardManagerActivated ( address ftsoRewardManager ) Emitted when the reward manager contract is activated. Parameters Type Description ftsoRewardManager address The reward manager contract. FtsoRewardManagerDeactivated # Defined in IFtsoRewardManager ( Docs , Source ). event FtsoRewardManagerDeactivated ( address ftsoRewardManager ) Emitted when the reward manager contract is deactivated. Parameters Type Description ftsoRewardManager address The reward manager contract. InflationReceived # Defined in IIFtsoRewardManager ( Docs , Source ). event InflationReceived ( uint256 amountReceivedWei ) Emitted when the contract has received the daily inflation amount. Parameters Type Description amountReceivedWei uint256 Received amount of native tokens, in wei. RewardClaimed # Defined in IFtsoRewardManager ( Docs , Source ). event RewardClaimed ( address dataProvider , address whoClaimed , address sentTo , uint256 rewardEpoch , uint256 amount ) Emitted when a data provider claims its FTSO rewards. Parameters Type Description dataProvider address Address of the data provider that accrued the reward. whoClaimed address Address that actually performed the claim. sentTo address Address that received the reward. rewardEpoch uint256 ID of the reward epoch where the reward was accrued. amount uint256 Amount of rewarded native tokens (wei). RewardClaimsEnabled # Defined in IFtsoRewardManager ( Docs , Source ). event RewardClaimsEnabled ( uint256 rewardEpochId ) Emitted when reward claims have been enabled. Parameters Type Description rewardEpochId uint256 First claimable reward epoch. RewardClaimsExpired # Defined in IFtsoRewardManager ( Docs , Source ). event RewardClaimsExpired ( uint256 rewardEpochId ) Unclaimed rewards have expired and are now inaccessible. getUnclaimedReward() can be used to retrieve more information. Parameters Type Description rewardEpochId uint256 ID of the reward epoch that has just expired. RewardsBurned # Defined in IIFtsoRewardManager ( Docs , Source ). event RewardsBurned ( uint256 amountBurnedWei ) Emitted when unclaimed rewards are burned. Parameters Type Description amountBurnedWei uint256 Burned amount of native tokens, in wei. RewardsDistributed # Defined in IFtsoRewardManager ( Docs , Source ). event RewardsDistributed ( address ftso , uint256 epochId , address [] addresses , uint256 [] rewards ) Emitted every price epoch, when rewards have been distributed to each contributing data provider. Note that rewards are not claimable until the reward epoch finishes. Parameters Type Description ftso address Address of the FTSO that generated the rewards. epochId uint256 ID of the reward epoch where the rewards were accrued. addresses address[] Data provider addresses that have rewards to claim. rewards uint256[] Amounts available for claiming (wei). UnearnedRewardsAccrued # Defined in IFtsoRewardManager ( Docs , Source ). event UnearnedRewardsAccrued ( uint256 epochId , uint256 reward ) Emitted when rewards cannot be distributed during a reward epoch (for example, because the FTSO went into fallback mode) and they are accrued for later burning. Parameters Type Description epochId uint256 ID of the reward epoch where the reward was accrued. reward uint256 Total amount of accrued rewards (wei). Functions # accrueUnearnedRewards # Defined in IIFtsoRewardManager ( Docs , Source ). function accrueUnearnedRewards ( uint256 epochId , uint256 priceEpochDurationSeconds , uint256 priceEpochEndTime ) external ; Accrue unearned rewards for a given price epoch. Typically done when the FTSO is in fallback mode or because of insufficient vote power. Simply accrue them so they will not be distributed and will be burned later. The amount of rewards that will be burned is calculated in the same way as in distributeRewards . Parameters Type Description epochId uint256 Price epoch ID. priceEpochDurationSeconds uint256 Duration of price epochs (180s). priceEpochEndTime uint256 Timestamp of the price epoch end time (end of submit period), in seconds since UNIX epoch. activate # Defined in IIFtsoRewardManager ( Docs , Source ). function activate ( ) external ; Activates reward manager (allows claiming rewards). active # Defined in IFtsoRewardManager ( Docs , Source ). function active ( ) external view returns ( bool ); Whether rewards can be claimed from this reward manager. autoClaim # Defined in IFtsoRewardManager ( Docs , Source ). function autoClaim ( address [] _rewardOwners , uint256 _rewardEpoch ) external ; Allows claiming rewards simultaneously for a list of reward owners and all unclaimed epochs before the specified one. This is meant as a convenience all-in-one reward claiming method to be used both by reward owners and registered executors . It performs a series of operations, besides claiming rewards: If a reward owner has enabled its Personal Delegation Account , rewards are also claimed for the PDA and the total claimed amount is sent to that PDA. Otherwise, the claimed amount is sent to the reward owner's account. Claimed amount is automatically wrapped through the WNat contract. If the caller is a registered executor with a non-zero fee, the fee is paid to the executor for each claimed address. Parameters Type Description _rewardOwners address[] List of reward owners to claim for. _rewardEpoch uint256 Last reward epoch ID to claim for. All previous epochs with pending rewards will be claimed too. claim # Defined in IFtsoRewardManager ( Docs , Source ). function claim ( address _rewardOwner , address payable _recipient , uint256 _rewardEpoch , bool _wrap ) external returns ( uint256 _rewardAmount ); Allows the caller to claim rewards for a reward owner. The caller does not have to be the owner of the rewards, but must be approved by the owner to claim on his behalf by using setClaimExecutors on the claimSetupManager . This function is intended to be used to claim rewards in case of delegation by percentage. Reverts if msg.sender is delegating by amount. Anybody can call this method, but rewards can only be sent to the reward owner, therefore no funds can be stolen. However, by limiting the authorized callers, the owner can control the timing of the calls. When the reward owner is the caller, rewards can be sent to any recipient set by setAllowedClaimRecipients on the claimSetupManager . The reward owner's Personal Delegation Account is always an authorized recipient. Parameters Type Description _rewardOwner address Address of the reward owner. _recipient address payable Address to transfer claimed rewards to. _rewardEpoch uint256 Last reward epoch to claim for. All previous epochs with pending rewards will be claimed too. _wrap bool Whether claimed rewards should be wrapped through the WNat contract before transferring them to the _recipient . This parameter is offered as a convenience. Returns Type Description _rewardAmount uint256 Total amount of claimed rewards (wei). claimFromDataProviders # Defined in IFtsoRewardManager ( Docs , Source ). function claimFromDataProviders ( address _rewardOwner , address payable _recipient , uint256 [] _rewardEpochs , address [] _dataProviders , bool _wrap ) external returns ( uint256 _rewardAmount ); Allows the caller to claim rewards for a reward owner from specific data providers. The caller does not have to be the owner of the rewards, but must be approved by the owner to claim on his behalf by using setClaimExecutors on the claimSetupManager . This function is intended to be used to claim rewards in case of delegation by amount (explicit delegation). Reverts if msg.sender is delegating by percentage. Anybody can call this method, but rewards can only be sent to the reward owner, therefore no funds can be stolen. However, by limiting the authorized callers, the owner can control the timing of the calls. When the reward owner is the caller, rewards can be sent to any recipient set by setAllowedClaimRecipients on the claimSetupManager . The reward owner's Personal Delegation Account is always an authorized recipient. Parameters Type Description _rewardOwner address Address of the reward owner. _recipient address payable Address to transfer claimed rewards to. _rewardEpochs uint256[] Array of reward epoch IDs to claim for. _dataProviders address[] Array of addresses of the data providers to claim the reward from. _wrap bool Whether claimed rewards should be wrapped through the WNat contract before transferring them to the _recipient . This parameter is offered as a convenience. Returns Type Description _rewardAmount uint256 Total amount of claimed rewards (wei). claimReward # Defined in IFtsoRewardManager ( Docs , Source ). function claimReward ( address payable _recipient , uint256 [] _rewardEpochs ) external returns ( uint256 _rewardAmount ); Allows a percentage delegator to claim rewards. This function is intended to be used to claim rewards in case of delegation by percentage. This function is deprecated : use claim instead. Reverts if msg.sender is delegating by amount. Claims for all unclaimed reward epochs to the 'max(_rewardEpochs)'. Retained for backward compatibility. Parameters Type Description _recipient address payable Address to transfer funds to. _rewardEpochs uint256[] Array of reward epoch numbers to claim for. Returns Type Description _rewardAmount uint256 Amount of total claimed rewards (wei). claimRewardFromDataProviders # Defined in IFtsoRewardManager ( Docs , Source ). function claimRewardFromDataProviders ( address payable _recipient , uint256 [] _rewardEpochs , address [] _dataProviders ) external returns ( uint256 _rewardAmount ); Allows the caller to claim rewards from specific data providers. This function is intended to be used to claim rewards in case of delegation by amount. This function is deprecated : use claimFromDataProviders instead. Parameters Type Description _recipient address payable Address to transfer funds to. _rewardEpochs uint256[] Array of reward epoch numbers to claim for. _dataProviders address[] Array of addresses of the data providers to claim the reward from. Returns Type Description _rewardAmount uint256 Total amount of claimed rewards (wei). closeExpiredRewardEpoch # Defined in IIFtsoRewardManager ( Docs , Source ). function closeExpiredRewardEpoch ( uint256 _rewardEpochId ) external ; Collects funds from expired reward epoch and calculates totals. Triggered by ftsoManager on finalization of a reward epoch. Operation is irreversible: when some reward epoch is closed according to current settings, it cannot be reopened even if new parameters would allow it, because nextRewardEpochToExpire in ftsoManager never decreases. Parameters Type Description _rewardEpochId uint256 ID of the epoch to close. deactivate # Defined in IIFtsoRewardManager ( Docs , Source ). function deactivate ( ) external ; Deactivates reward manager (prevents claiming rewards). distributeRewards # Defined in IIFtsoRewardManager ( Docs , Source ). function distributeRewards ( address [] addresses , uint256 [] weights , uint256 totalWeight , uint256 epochId , address ftso , uint256 priceEpochDurationSeconds , uint256 currentRewardEpoch , uint256 priceEpochEndTime , uint256 votePowerBlock ) external ; Distributes price epoch rewards to data provider accounts, according to input parameters. Must be called with totalWeight > 0 and addresses.length > 0. The amount of rewards for a given price epoch ID are calculated in FtsoRewardManager from priceEpochDurationSeconds , priceEpochEndTime and inflation authorization data (see _getTotalPriceEpochRewardWei in FtsoRewardManager . Then each data provider address is given a portion of this amount according to corresponding weight and total sum of weights. Parameters epochId and ftso are only needed so they can be passed onto the emitted event. Parameters Type Description addresses address[] Data provider addresses to reward. weights uint256[] Weights corresponding to rewarded addresses. totalWeight uint256 Sum of all weights. epochId uint256 Price epoch ID. ftso address Randomly chosen FTSO contract used to calculate the weights. priceEpochDurationSeconds uint256 Duration of price epochs (180s). currentRewardEpoch uint256 ID of the current reward epoch. Rewards for the price epoch are added to this reward epoch. priceEpochEndTime uint256 Timestamp of the price epoch end time (end of submit period), in seconds since UNIX epoch. votePowerBlock uint256 Vote power block used in the given reward epoch. enableClaims # Defined in IIFtsoRewardManager ( Docs , Source ). function enableClaims ( ) external ; Enable claiming for current and all future reward epochs. firstClaimableRewardEpoch # Defined in IIFtsoRewardManager ( Docs , Source ). function firstClaimableRewardEpoch ( ) external view returns ( uint256 ); Epochs before the token distribution event at Flare launch were not be claimable. Use this method to know the first reward epoch that was claimable. Returns Type Description [0] uint256 uint256 The first reward epoch that can be claimed. getClaimedReward # Defined in IFtsoRewardManager ( Docs , Source ). function getClaimedReward ( uint256 _rewardEpoch , address _dataProvider , address _claimer ) external view returns ( bool _claimed , uint256 _amount ); Returns information on the rewards accrued by a reward owner from a specific data provider at a specific reward epoch. Parameters Type Description _rewardEpoch uint256 Reward epoch ID to query. _dataProvider address Address of the data provider to query. _claimer address Address of the reward owner to query. Returns Type Description _claimed bool Whether the reward has been claimed or not. _amount uint256 Accrued amount in wei. getContractName # Defined in IIInflationReceiver ( Docs , Source ). function getContractName ( ) external view returns ( string ); Implement this function to allow updating inflation receiver contracts through AddressUpdater . Returns Type Description [0] string Contract name. getCurrentRewardEpoch # Defined in IFtsoRewardManager ( Docs , Source ). function getCurrentRewardEpoch ( ) external view returns ( uint256 ); Returns the current reward epoch ID. getDataProviderCurrentFeePercentage # Defined in IFtsoRewardManager ( Docs , Source ). function getDataProviderCurrentFeePercentage ( address _dataProvider ) external view returns ( uint256 _feePercentageBIPS ); Returns the current fee percentage of a data provider. Parameters Type Description _dataProvider address Address of the queried data provider. Returns Type Description _feePercentageBIPS uint256 Fee percentage in BIPS. getDataProviderFeePercentage # Defined in IFtsoRewardManager ( Docs , Source ). function getDataProviderFeePercentage ( address _dataProvider , uint256 _rewardEpoch ) external view returns ( uint256 _feePercentageBIPS ); Returns the fee percentage of a data provider at a given reward epoch. Parameters Type Description _dataProvider address Address of the queried data provider. _rewardEpoch uint256 Reward epoch ID. Returns Type Description _feePercentageBIPS uint256 Fee percentage in BIPS. getDataProviderPerformanceInfo # Defined in IFtsoRewardManager ( Docs , Source ). function getDataProviderPerformanceInfo ( uint256 _rewardEpoch , address _dataProvider ) external view returns ( uint256 _rewardAmount , uint256 _votePowerIgnoringRevocation ); Returns information on rewards and vote power of a data provider at a given reward epoch. Parameters Type Description _rewardEpoch uint256 Reward epoch ID. _dataProvider address Address of the data provider to query. Returns Type Description _rewardAmount uint256 Amount of rewards (wei). _votePowerIgnoringRevocation uint256 Vote power, not including revocations. getDataProviderScheduledFeePercentageChanges # Defined in IFtsoRewardManager ( Docs , Source ). function getDataProviderScheduledFeePercentageChanges ( address _dataProvider ) external view returns ( uint256 [] _feePercentageBIPS , uint256 [] _validFromEpoch , bool [] _fixed ); Returns the scheduled fee percentage changes for a data provider. Parameters Type Description _dataProvider address Address of the queried data provider. Returns Type Description _feePercentageBIPS uint256[] Array of fee percentages in BIPS. _validFromEpoch uint256[] Array of block numbers from which the fee settings are effective. _fixed bool[] Array of boolean values indicating whether settings are subject to change or not. getEpochReward # Defined in IFtsoRewardManager ( Docs , Source ). function getEpochReward ( uint256 _rewardEpoch ) external view returns ( uint256 _totalReward , uint256 _claimedReward ); Returns information on an epoch's rewards. Parameters Type Description _rewardEpoch uint256 Reward epoch ID. Returns Type Description _totalReward uint256 Total amount of rewards accrued on that epoch, in wei. _claimedReward uint256 Total amount of rewards that have already been claimed, in wei. getEpochsWithClaimableRewards # Defined in IFtsoRewardManager ( Docs , Source ). function getEpochsWithClaimableRewards ( ) external view returns ( uint256 _startEpochId , uint256 _endEpochId ); Returns the reward epoch range for which rewards can be claimed. Rewards outside this range are unclaimable, either because they have expired or because the reward epoch is still ongoing. Returns Type Description _startEpochId uint256 The oldest epoch ID that allows reward claiming. _endEpochId uint256 The newest epoch ID that allows reward claiming. getEpochsWithUnclaimedRewards # Defined in IFtsoRewardManager ( Docs , Source ). function getEpochsWithUnclaimedRewards ( address _beneficiary ) external view returns ( uint256 [] _epochIds ); Returns the array of claimable epoch IDs for which the rewards of a reward owner have not yet been claimed. Parameters Type Description _beneficiary address Address of the reward owner to query. Reverts if it uses delegation by amount. Returns Type Description _epochIds uint256[] Array of epoch IDs. getExpectedBalance # Defined in IIInflationReceiver ( Docs , Source ). function getExpectedBalance ( ) external view returns ( uint256 ); Returns the contract's expected balance (actual balance may be higher due to self-destruct funds). Returns Type Description [0] uint256 Expected native token balance. getInflationAddress # Defined in IIInflationReceiver ( Docs , Source ). function getInflationAddress ( ) external returns ( address ); Returns the address of the Inflation contract. getInitialRewardEpoch # Defined in IFtsoRewardManager ( Docs , Source ). function getInitialRewardEpoch ( ) external view returns ( uint256 ); Returns the initial reward epoch ID for this reward manager contract. This corresponds to the oldest reward epoch with claimable rewards in the previous reward manager when this one took over. Set by governance through setInitialRewardData . getRewardEpochToExpireNext # Defined in IFtsoRewardManager ( Docs , Source ). function getRewardEpochToExpireNext ( ) external view returns ( uint256 ); Returns the reward epoch that will expire next once a new reward epoch starts. getRewardEpochVotePowerBlock # Defined in IFtsoRewardManager ( Docs , Source ). function getRewardEpochVotePowerBlock ( uint256 _rewardEpoch ) external view returns ( uint256 ); Returns the vote power block of a given reward epoch. Parameters Type Description _rewardEpoch uint256 Reward epoch ID. getStateOfRewards # Defined in IFtsoRewardManager ( Docs , Source ). function getStateOfRewards ( address _beneficiary , uint256 _rewardEpoch ) external view returns ( address [] _dataProviders , uint256 [] _rewardAmounts , bool [] _claimed , bool _claimable ); Returns the state of rewards for a given address at a specific reward epoch. Parameters Type Description _beneficiary address Address of the beneficiary to query. It can be a data provider or a delegator, for example. Reverts if the queried address is delegating by amount. _rewardEpoch uint256 Reward epoch ID to query. Returns Type Description _dataProviders address[] Array of addresses of data providers. _rewardAmounts uint256[] Array of reward amounts received from each provider, in wei. _claimed bool[] Array of boolean values indicating whether each reward has been claimed or not. _claimable bool Boolean value indicating whether rewards are claimable or not. getStateOfRewardsFromDataProviders # Defined in IFtsoRewardManager ( Docs , Source ). function getStateOfRewardsFromDataProviders ( address _beneficiary , uint256 _rewardEpoch , address [] _dataProviders ) external view returns ( uint256 [] _rewardAmounts , bool [] _claimed , bool _claimable ); Returns the state of rewards for a given address coming from a specific set of data providers, at a specific reward epoch. Parameters Type Description _beneficiary address Address of beneficiary to query. _rewardEpoch uint256 Reward epoch ID to query. _dataProviders address[] Array of addresses of the data providers to query. Returns Type Description _rewardAmounts uint256[] Array of reward amounts received from each provider, in wei. _claimed bool[] Array of boolean values indicating whether each reward has been claimed or not. _claimable bool Boolean value indicating whether rewards are claimable or not. getTokenPoolSupplyData # Defined in IITokenPool ( Docs , Source ). function getTokenPoolSupplyData ( ) external returns ( uint256 _lockedFundsWei , uint256 _totalInflationAuthorizedWei , uint256 _totalClaimedWei ); Returns token pool supply data. Returns Type Description _lockedFundsWei uint256 Total amount of funds ever locked in the token pool (wei). _lockedFundsWei - _totalClaimedWei is the amount currently locked and outside the circulating supply. _totalInflationAuthorizedWei uint256 Total inflation authorized amount (wei). _totalClaimedWei uint256 Total claimed amount (wei). getUnclaimedReward # Defined in IIFtsoRewardManager ( Docs , Source ). function getUnclaimedReward ( uint256 _rewardEpoch , address _dataProvider ) external view returns ( uint256 _amount , uint256 _weight ); Returns information on unclaimed rewards for a given data provider and epoch. Parameters Type Description _rewardEpoch uint256 Queried reward epoch ID. _dataProvider address Address of the queried data provider. Returns Type Description _amount uint256 Amount available to be claimed, in wei. _weight uint256 Portion of total vote power used in this reward epoch that has not yet claimed its reward, in BIPS. It decreases to 0 when all data providers have claimed their rewards. nextClaimableRewardEpoch # Defined in IFtsoRewardManager ( Docs , Source ). function nextClaimableRewardEpoch ( address _rewardOwner ) external view returns ( uint256 ); Returns the next claimable reward epoch for a reward owner. Parameters Type Description _rewardOwner address Address of the reward owner to query. receiveInflation # Defined in IIInflationReceiver ( Docs , Source ). function receiveInflation ( ) external payable ; Receive native tokens from inflation. setDailyAuthorizedInflation # Defined in IIInflationReceiver ( Docs , Source ). function setDailyAuthorizedInflation ( uint256 _toAuthorizeWei ) external ; Notify the receiver that it is entitled to receive a new inflation amount. Parameters Type Description _toAuthorizeWei uint256 The amount of inflation that can be awarded in the coming day, in wei. setDataProviderFeePercentage # Defined in IFtsoRewardManager ( Docs , Source ). function setDataProviderFeePercentage ( uint256 _feePercentageBIPS ) external returns ( uint256 _validFromEpoch ); Sets the fee a data provider keeps from all delegations. Takes effect after feeValueUpdateOffset reward epochs have elapsed. When called multiple times inside the same reward epoch, only the last value remains. Parameters Type Description _feePercentageBIPS uint256 Fee percentage in BIPS. Returns Type Description _validFromEpoch uint256 Reward epoch number when the new fee percentage will become effective.","title":"IIFtsoRewardManager"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#ct_iiftsorewardmanager","text":"Source | Inherits from IFtsoRewardManager , IIInflationReceiver , IITokenPool Internal interface for the FtsoRewardManager .","title":"IIFtsoRewardManager"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#events","text":"","title":"Events"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#ev_dailyauthorizedinflationset","text":"Defined in IIFtsoRewardManager ( Docs , Source ). event DailyAuthorizedInflationSet ( uint256 authorizedAmountWei ) Emitted when the contract's daily authorized inflation has been set. Parameters Type Description authorizedAmountWei uint256 Authorized amount of native tokens, in wei.","title":"DailyAuthorizedInflationSet"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#ev_feepercentagechanged","text":"Defined in IFtsoRewardManager ( Docs , Source ). event FeePercentageChanged ( address dataProvider , uint256 value , uint256 validFromEpoch ) Emitted when a data provider changes its fee. Parameters Type Description dataProvider address Address of the data provider. value uint256 New fee, in BIPS. validFromEpoch uint256 Epoch ID where the new fee takes effect.","title":"FeePercentageChanged"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#ev_ftsorewardmanageractivated","text":"Defined in IFtsoRewardManager ( Docs , Source ). event FtsoRewardManagerActivated ( address ftsoRewardManager ) Emitted when the reward manager contract is activated. Parameters Type Description ftsoRewardManager address The reward manager contract.","title":"FtsoRewardManagerActivated"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#ev_ftsorewardmanagerdeactivated","text":"Defined in IFtsoRewardManager ( Docs , Source ). event FtsoRewardManagerDeactivated ( address ftsoRewardManager ) Emitted when the reward manager contract is deactivated. Parameters Type Description ftsoRewardManager address The reward manager contract.","title":"FtsoRewardManagerDeactivated"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#ev_inflationreceived","text":"Defined in IIFtsoRewardManager ( Docs , Source ). event InflationReceived ( uint256 amountReceivedWei ) Emitted when the contract has received the daily inflation amount. Parameters Type Description amountReceivedWei uint256 Received amount of native tokens, in wei.","title":"InflationReceived"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#ev_rewardclaimed","text":"Defined in IFtsoRewardManager ( Docs , Source ). event RewardClaimed ( address dataProvider , address whoClaimed , address sentTo , uint256 rewardEpoch , uint256 amount ) Emitted when a data provider claims its FTSO rewards. Parameters Type Description dataProvider address Address of the data provider that accrued the reward. whoClaimed address Address that actually performed the claim. sentTo address Address that received the reward. rewardEpoch uint256 ID of the reward epoch where the reward was accrued. amount uint256 Amount of rewarded native tokens (wei).","title":"RewardClaimed"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#ev_rewardclaimsenabled","text":"Defined in IFtsoRewardManager ( Docs , Source ). event RewardClaimsEnabled ( uint256 rewardEpochId ) Emitted when reward claims have been enabled. Parameters Type Description rewardEpochId uint256 First claimable reward epoch.","title":"RewardClaimsEnabled"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#ev_rewardclaimsexpired","text":"Defined in IFtsoRewardManager ( Docs , Source ). event RewardClaimsExpired ( uint256 rewardEpochId ) Unclaimed rewards have expired and are now inaccessible. getUnclaimedReward() can be used to retrieve more information. Parameters Type Description rewardEpochId uint256 ID of the reward epoch that has just expired.","title":"RewardClaimsExpired"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#ev_rewardsburned","text":"Defined in IIFtsoRewardManager ( Docs , Source ). event RewardsBurned ( uint256 amountBurnedWei ) Emitted when unclaimed rewards are burned. Parameters Type Description amountBurnedWei uint256 Burned amount of native tokens, in wei.","title":"RewardsBurned"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#ev_rewardsdistributed","text":"Defined in IFtsoRewardManager ( Docs , Source ). event RewardsDistributed ( address ftso , uint256 epochId , address [] addresses , uint256 [] rewards ) Emitted every price epoch, when rewards have been distributed to each contributing data provider. Note that rewards are not claimable until the reward epoch finishes. Parameters Type Description ftso address Address of the FTSO that generated the rewards. epochId uint256 ID of the reward epoch where the rewards were accrued. addresses address[] Data provider addresses that have rewards to claim. rewards uint256[] Amounts available for claiming (wei).","title":"RewardsDistributed"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#ev_unearnedrewardsaccrued","text":"Defined in IFtsoRewardManager ( Docs , Source ). event UnearnedRewardsAccrued ( uint256 epochId , uint256 reward ) Emitted when rewards cannot be distributed during a reward epoch (for example, because the FTSO went into fallback mode) and they are accrued for later burning. Parameters Type Description epochId uint256 ID of the reward epoch where the reward was accrued. reward uint256 Total amount of accrued rewards (wei).","title":"UnearnedRewardsAccrued"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_accrueunearnedrewards_67dcac53","text":"Defined in IIFtsoRewardManager ( Docs , Source ). function accrueUnearnedRewards ( uint256 epochId , uint256 priceEpochDurationSeconds , uint256 priceEpochEndTime ) external ; Accrue unearned rewards for a given price epoch. Typically done when the FTSO is in fallback mode or because of insufficient vote power. Simply accrue them so they will not be distributed and will be burned later. The amount of rewards that will be burned is calculated in the same way as in distributeRewards . Parameters Type Description epochId uint256 Price epoch ID. priceEpochDurationSeconds uint256 Duration of price epochs (180s). priceEpochEndTime uint256 Timestamp of the price epoch end time (end of submit period), in seconds since UNIX epoch.","title":"accrueUnearnedRewards"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_activate_0f15f4c0","text":"Defined in IIFtsoRewardManager ( Docs , Source ). function activate ( ) external ; Activates reward manager (allows claiming rewards).","title":"activate"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_active_02fb0c5e","text":"Defined in IFtsoRewardManager ( Docs , Source ). function active ( ) external view returns ( bool ); Whether rewards can be claimed from this reward manager.","title":"active"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_autoclaim_8dc305fa","text":"Defined in IFtsoRewardManager ( Docs , Source ). function autoClaim ( address [] _rewardOwners , uint256 _rewardEpoch ) external ; Allows claiming rewards simultaneously for a list of reward owners and all unclaimed epochs before the specified one. This is meant as a convenience all-in-one reward claiming method to be used both by reward owners and registered executors . It performs a series of operations, besides claiming rewards: If a reward owner has enabled its Personal Delegation Account , rewards are also claimed for the PDA and the total claimed amount is sent to that PDA. Otherwise, the claimed amount is sent to the reward owner's account. Claimed amount is automatically wrapped through the WNat contract. If the caller is a registered executor with a non-zero fee, the fee is paid to the executor for each claimed address. Parameters Type Description _rewardOwners address[] List of reward owners to claim for. _rewardEpoch uint256 Last reward epoch ID to claim for. All previous epochs with pending rewards will be claimed too.","title":"autoClaim"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_claim_b2c12192","text":"Defined in IFtsoRewardManager ( Docs , Source ). function claim ( address _rewardOwner , address payable _recipient , uint256 _rewardEpoch , bool _wrap ) external returns ( uint256 _rewardAmount ); Allows the caller to claim rewards for a reward owner. The caller does not have to be the owner of the rewards, but must be approved by the owner to claim on his behalf by using setClaimExecutors on the claimSetupManager . This function is intended to be used to claim rewards in case of delegation by percentage. Reverts if msg.sender is delegating by amount. Anybody can call this method, but rewards can only be sent to the reward owner, therefore no funds can be stolen. However, by limiting the authorized callers, the owner can control the timing of the calls. When the reward owner is the caller, rewards can be sent to any recipient set by setAllowedClaimRecipients on the claimSetupManager . The reward owner's Personal Delegation Account is always an authorized recipient. Parameters Type Description _rewardOwner address Address of the reward owner. _recipient address payable Address to transfer claimed rewards to. _rewardEpoch uint256 Last reward epoch to claim for. All previous epochs with pending rewards will be claimed too. _wrap bool Whether claimed rewards should be wrapped through the WNat contract before transferring them to the _recipient . This parameter is offered as a convenience. Returns Type Description _rewardAmount uint256 Total amount of claimed rewards (wei).","title":"claim"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_claimfromdataproviders_21bb25af","text":"Defined in IFtsoRewardManager ( Docs , Source ). function claimFromDataProviders ( address _rewardOwner , address payable _recipient , uint256 [] _rewardEpochs , address [] _dataProviders , bool _wrap ) external returns ( uint256 _rewardAmount ); Allows the caller to claim rewards for a reward owner from specific data providers. The caller does not have to be the owner of the rewards, but must be approved by the owner to claim on his behalf by using setClaimExecutors on the claimSetupManager . This function is intended to be used to claim rewards in case of delegation by amount (explicit delegation). Reverts if msg.sender is delegating by percentage. Anybody can call this method, but rewards can only be sent to the reward owner, therefore no funds can be stolen. However, by limiting the authorized callers, the owner can control the timing of the calls. When the reward owner is the caller, rewards can be sent to any recipient set by setAllowedClaimRecipients on the claimSetupManager . The reward owner's Personal Delegation Account is always an authorized recipient. Parameters Type Description _rewardOwner address Address of the reward owner. _recipient address payable Address to transfer claimed rewards to. _rewardEpochs uint256[] Array of reward epoch IDs to claim for. _dataProviders address[] Array of addresses of the data providers to claim the reward from. _wrap bool Whether claimed rewards should be wrapped through the WNat contract before transferring them to the _recipient . This parameter is offered as a convenience. Returns Type Description _rewardAmount uint256 Total amount of claimed rewards (wei).","title":"claimFromDataProviders"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_claimreward_b2af870a","text":"Defined in IFtsoRewardManager ( Docs , Source ). function claimReward ( address payable _recipient , uint256 [] _rewardEpochs ) external returns ( uint256 _rewardAmount ); Allows a percentage delegator to claim rewards. This function is intended to be used to claim rewards in case of delegation by percentage. This function is deprecated : use claim instead. Reverts if msg.sender is delegating by amount. Claims for all unclaimed reward epochs to the 'max(_rewardEpochs)'. Retained for backward compatibility. Parameters Type Description _recipient address payable Address to transfer funds to. _rewardEpochs uint256[] Array of reward epoch numbers to claim for. Returns Type Description _rewardAmount uint256 Amount of total claimed rewards (wei).","title":"claimReward"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_claimrewardfromdataproviders_d20bb542","text":"Defined in IFtsoRewardManager ( Docs , Source ). function claimRewardFromDataProviders ( address payable _recipient , uint256 [] _rewardEpochs , address [] _dataProviders ) external returns ( uint256 _rewardAmount ); Allows the caller to claim rewards from specific data providers. This function is intended to be used to claim rewards in case of delegation by amount. This function is deprecated : use claimFromDataProviders instead. Parameters Type Description _recipient address payable Address to transfer funds to. _rewardEpochs uint256[] Array of reward epoch numbers to claim for. _dataProviders address[] Array of addresses of the data providers to claim the reward from. Returns Type Description _rewardAmount uint256 Total amount of claimed rewards (wei).","title":"claimRewardFromDataProviders"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_closeexpiredrewardepoch_d6c1dbee","text":"Defined in IIFtsoRewardManager ( Docs , Source ). function closeExpiredRewardEpoch ( uint256 _rewardEpochId ) external ; Collects funds from expired reward epoch and calculates totals. Triggered by ftsoManager on finalization of a reward epoch. Operation is irreversible: when some reward epoch is closed according to current settings, it cannot be reopened even if new parameters would allow it, because nextRewardEpochToExpire in ftsoManager never decreases. Parameters Type Description _rewardEpochId uint256 ID of the epoch to close.","title":"closeExpiredRewardEpoch"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_deactivate_51b42b00","text":"Defined in IIFtsoRewardManager ( Docs , Source ). function deactivate ( ) external ; Deactivates reward manager (prevents claiming rewards).","title":"deactivate"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_distributerewards_a9b79e17","text":"Defined in IIFtsoRewardManager ( Docs , Source ). function distributeRewards ( address [] addresses , uint256 [] weights , uint256 totalWeight , uint256 epochId , address ftso , uint256 priceEpochDurationSeconds , uint256 currentRewardEpoch , uint256 priceEpochEndTime , uint256 votePowerBlock ) external ; Distributes price epoch rewards to data provider accounts, according to input parameters. Must be called with totalWeight > 0 and addresses.length > 0. The amount of rewards for a given price epoch ID are calculated in FtsoRewardManager from priceEpochDurationSeconds , priceEpochEndTime and inflation authorization data (see _getTotalPriceEpochRewardWei in FtsoRewardManager . Then each data provider address is given a portion of this amount according to corresponding weight and total sum of weights. Parameters epochId and ftso are only needed so they can be passed onto the emitted event. Parameters Type Description addresses address[] Data provider addresses to reward. weights uint256[] Weights corresponding to rewarded addresses. totalWeight uint256 Sum of all weights. epochId uint256 Price epoch ID. ftso address Randomly chosen FTSO contract used to calculate the weights. priceEpochDurationSeconds uint256 Duration of price epochs (180s). currentRewardEpoch uint256 ID of the current reward epoch. Rewards for the price epoch are added to this reward epoch. priceEpochEndTime uint256 Timestamp of the price epoch end time (end of submit period), in seconds since UNIX epoch. votePowerBlock uint256 Vote power block used in the given reward epoch.","title":"distributeRewards"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_enableclaims_ea28edad","text":"Defined in IIFtsoRewardManager ( Docs , Source ). function enableClaims ( ) external ; Enable claiming for current and all future reward epochs.","title":"enableClaims"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_firstclaimablerewardepoch_7b6b2c0a","text":"Defined in IIFtsoRewardManager ( Docs , Source ). function firstClaimableRewardEpoch ( ) external view returns ( uint256 ); Epochs before the token distribution event at Flare launch were not be claimable. Use this method to know the first reward epoch that was claimable. Returns Type Description [0] uint256 uint256 The first reward epoch that can be claimed.","title":"firstClaimableRewardEpoch"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_getclaimedreward_85b4c538","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getClaimedReward ( uint256 _rewardEpoch , address _dataProvider , address _claimer ) external view returns ( bool _claimed , uint256 _amount ); Returns information on the rewards accrued by a reward owner from a specific data provider at a specific reward epoch. Parameters Type Description _rewardEpoch uint256 Reward epoch ID to query. _dataProvider address Address of the data provider to query. _claimer address Address of the reward owner to query. Returns Type Description _claimed bool Whether the reward has been claimed or not. _amount uint256 Accrued amount in wei.","title":"getClaimedReward"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_getcontractname_f5f5ba72","text":"Defined in IIInflationReceiver ( Docs , Source ). function getContractName ( ) external view returns ( string ); Implement this function to allow updating inflation receiver contracts through AddressUpdater . Returns Type Description [0] string Contract name.","title":"getContractName"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_getcurrentrewardepoch_e7c830d4","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getCurrentRewardEpoch ( ) external view returns ( uint256 ); Returns the current reward epoch ID.","title":"getCurrentRewardEpoch"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_getdataprovidercurrentfeepercentage_cfbcd25f","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getDataProviderCurrentFeePercentage ( address _dataProvider ) external view returns ( uint256 _feePercentageBIPS ); Returns the current fee percentage of a data provider. Parameters Type Description _dataProvider address Address of the queried data provider. Returns Type Description _feePercentageBIPS uint256 Fee percentage in BIPS.","title":"getDataProviderCurrentFeePercentage"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_getdataproviderfeepercentage_961c00ed","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getDataProviderFeePercentage ( address _dataProvider , uint256 _rewardEpoch ) external view returns ( uint256 _feePercentageBIPS ); Returns the fee percentage of a data provider at a given reward epoch. Parameters Type Description _dataProvider address Address of the queried data provider. _rewardEpoch uint256 Reward epoch ID. Returns Type Description _feePercentageBIPS uint256 Fee percentage in BIPS.","title":"getDataProviderFeePercentage"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_getdataproviderperformanceinfo_eb82dd7f","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getDataProviderPerformanceInfo ( uint256 _rewardEpoch , address _dataProvider ) external view returns ( uint256 _rewardAmount , uint256 _votePowerIgnoringRevocation ); Returns information on rewards and vote power of a data provider at a given reward epoch. Parameters Type Description _rewardEpoch uint256 Reward epoch ID. _dataProvider address Address of the data provider to query. Returns Type Description _rewardAmount uint256 Amount of rewards (wei). _votePowerIgnoringRevocation uint256 Vote power, not including revocations.","title":"getDataProviderPerformanceInfo"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_getdataproviderscheduledfeepercentagechanges_33b7971e","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getDataProviderScheduledFeePercentageChanges ( address _dataProvider ) external view returns ( uint256 [] _feePercentageBIPS , uint256 [] _validFromEpoch , bool [] _fixed ); Returns the scheduled fee percentage changes for a data provider. Parameters Type Description _dataProvider address Address of the queried data provider. Returns Type Description _feePercentageBIPS uint256[] Array of fee percentages in BIPS. _validFromEpoch uint256[] Array of block numbers from which the fee settings are effective. _fixed bool[] Array of boolean values indicating whether settings are subject to change or not.","title":"getDataProviderScheduledFeePercentageChanges"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_getepochreward_d418634a","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getEpochReward ( uint256 _rewardEpoch ) external view returns ( uint256 _totalReward , uint256 _claimedReward ); Returns information on an epoch's rewards. Parameters Type Description _rewardEpoch uint256 Reward epoch ID. Returns Type Description _totalReward uint256 Total amount of rewards accrued on that epoch, in wei. _claimedReward uint256 Total amount of rewards that have already been claimed, in wei.","title":"getEpochReward"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_getepochswithclaimablerewards_0441218e","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getEpochsWithClaimableRewards ( ) external view returns ( uint256 _startEpochId , uint256 _endEpochId ); Returns the reward epoch range for which rewards can be claimed. Rewards outside this range are unclaimable, either because they have expired or because the reward epoch is still ongoing. Returns Type Description _startEpochId uint256 The oldest epoch ID that allows reward claiming. _endEpochId uint256 The newest epoch ID that allows reward claiming.","title":"getEpochsWithClaimableRewards"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_getepochswithunclaimedrewards_b4a2043d","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getEpochsWithUnclaimedRewards ( address _beneficiary ) external view returns ( uint256 [] _epochIds ); Returns the array of claimable epoch IDs for which the rewards of a reward owner have not yet been claimed. Parameters Type Description _beneficiary address Address of the reward owner to query. Reverts if it uses delegation by amount. Returns Type Description _epochIds uint256[] Array of epoch IDs.","title":"getEpochsWithUnclaimedRewards"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_getexpectedbalance_af04cd3b","text":"Defined in IIInflationReceiver ( Docs , Source ). function getExpectedBalance ( ) external view returns ( uint256 ); Returns the contract's expected balance (actual balance may be higher due to self-destruct funds). Returns Type Description [0] uint256 Expected native token balance.","title":"getExpectedBalance"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_getinflationaddress_ed39d3f8","text":"Defined in IIInflationReceiver ( Docs , Source ). function getInflationAddress ( ) external returns ( address ); Returns the address of the Inflation contract.","title":"getInflationAddress"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_getinitialrewardepoch_3123b7d8","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getInitialRewardEpoch ( ) external view returns ( uint256 ); Returns the initial reward epoch ID for this reward manager contract. This corresponds to the oldest reward epoch with claimable rewards in the previous reward manager when this one took over. Set by governance through setInitialRewardData .","title":"getInitialRewardEpoch"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_getrewardepochtoexpirenext_3e7ff857","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getRewardEpochToExpireNext ( ) external view returns ( uint256 ); Returns the reward epoch that will expire next once a new reward epoch starts.","title":"getRewardEpochToExpireNext"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_getrewardepochvotepowerblock_f2edab5a","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getRewardEpochVotePowerBlock ( uint256 _rewardEpoch ) external view returns ( uint256 ); Returns the vote power block of a given reward epoch. Parameters Type Description _rewardEpoch uint256 Reward epoch ID.","title":"getRewardEpochVotePowerBlock"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_getstateofrewards_a4472c10","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getStateOfRewards ( address _beneficiary , uint256 _rewardEpoch ) external view returns ( address [] _dataProviders , uint256 [] _rewardAmounts , bool [] _claimed , bool _claimable ); Returns the state of rewards for a given address at a specific reward epoch. Parameters Type Description _beneficiary address Address of the beneficiary to query. It can be a data provider or a delegator, for example. Reverts if the queried address is delegating by amount. _rewardEpoch uint256 Reward epoch ID to query. Returns Type Description _dataProviders address[] Array of addresses of data providers. _rewardAmounts uint256[] Array of reward amounts received from each provider, in wei. _claimed bool[] Array of boolean values indicating whether each reward has been claimed or not. _claimable bool Boolean value indicating whether rewards are claimable or not.","title":"getStateOfRewards"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_getstateofrewardsfromdataproviders_e416b7e1","text":"Defined in IFtsoRewardManager ( Docs , Source ). function getStateOfRewardsFromDataProviders ( address _beneficiary , uint256 _rewardEpoch , address [] _dataProviders ) external view returns ( uint256 [] _rewardAmounts , bool [] _claimed , bool _claimable ); Returns the state of rewards for a given address coming from a specific set of data providers, at a specific reward epoch. Parameters Type Description _beneficiary address Address of beneficiary to query. _rewardEpoch uint256 Reward epoch ID to query. _dataProviders address[] Array of addresses of the data providers to query. Returns Type Description _rewardAmounts uint256[] Array of reward amounts received from each provider, in wei. _claimed bool[] Array of boolean values indicating whether each reward has been claimed or not. _claimable bool Boolean value indicating whether rewards are claimable or not.","title":"getStateOfRewardsFromDataProviders"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_gettokenpoolsupplydata_2dafdbbf","text":"Defined in IITokenPool ( Docs , Source ). function getTokenPoolSupplyData ( ) external returns ( uint256 _lockedFundsWei , uint256 _totalInflationAuthorizedWei , uint256 _totalClaimedWei ); Returns token pool supply data. Returns Type Description _lockedFundsWei uint256 Total amount of funds ever locked in the token pool (wei). _lockedFundsWei - _totalClaimedWei is the amount currently locked and outside the circulating supply. _totalInflationAuthorizedWei uint256 Total inflation authorized amount (wei). _totalClaimedWei uint256 Total claimed amount (wei).","title":"getTokenPoolSupplyData"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_getunclaimedreward_657d9695","text":"Defined in IIFtsoRewardManager ( Docs , Source ). function getUnclaimedReward ( uint256 _rewardEpoch , address _dataProvider ) external view returns ( uint256 _amount , uint256 _weight ); Returns information on unclaimed rewards for a given data provider and epoch. Parameters Type Description _rewardEpoch uint256 Queried reward epoch ID. _dataProvider address Address of the queried data provider. Returns Type Description _amount uint256 Amount available to be claimed, in wei. _weight uint256 Portion of total vote power used in this reward epoch that has not yet claimed its reward, in BIPS. It decreases to 0 when all data providers have claimed their rewards.","title":"getUnclaimedReward"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_nextclaimablerewardepoch_69b91b59","text":"Defined in IFtsoRewardManager ( Docs , Source ). function nextClaimableRewardEpoch ( address _rewardOwner ) external view returns ( uint256 ); Returns the next claimable reward epoch for a reward owner. Parameters Type Description _rewardOwner address Address of the reward owner to query.","title":"nextClaimableRewardEpoch"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_receiveinflation_06201f1d","text":"Defined in IIInflationReceiver ( Docs , Source ). function receiveInflation ( ) external payable ; Receive native tokens from inflation.","title":"receiveInflation"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_setdailyauthorizedinflation_e2739563","text":"Defined in IIInflationReceiver ( Docs , Source ). function setDailyAuthorizedInflation ( uint256 _toAuthorizeWei ) external ; Notify the receiver that it is entitled to receive a new inflation amount. Parameters Type Description _toAuthorizeWei uint256 The amount of inflation that can be awarded in the coming day, in wei.","title":"setDailyAuthorizedInflation"},{"location":"apis/smart-contracts/IIFtsoRewardManager/#fn_setdataproviderfeepercentage_16e69328","text":"Defined in IFtsoRewardManager ( Docs , Source ). function setDataProviderFeePercentage ( uint256 _feePercentageBIPS ) external returns ( uint256 _validFromEpoch ); Sets the fee a data provider keeps from all delegations. Takes effect after feeValueUpdateOffset reward epochs have elapsed. When called multiple times inside the same reward epoch, only the last value remains. Parameters Type Description _feePercentageBIPS uint256 Fee percentage in BIPS. Returns Type Description _validFromEpoch uint256 Reward epoch number when the new fee percentage will become effective.","title":"setDataProviderFeePercentage"},{"location":"apis/smart-contracts/IIGovernanceVotePower/","text":"IIGovernanceVotePower # Source | Inherits from IGovernanceVotePower Internal interface for contracts delegating their governance vote power. Events # DelegateChanged # Defined in IIGovernanceVotePower ( Docs , Source ). event DelegateChanged ( address delegator , address fromDelegate , address toDelegate ) Emitted when an account starts delegating vote power or switches its delegation to another address. The event is always emitted from a GovernanceVotePower contract. Parameters Type Description delegator address Account delegating its vote power. fromDelegate address Account receiving the delegation before the change. Can be address(0) if there was no previous delegation. toDelegate address Account receiving the delegation after the change. Can be address(0) if delegator just undelegated all its vote power. DelegateVotesChanged # Defined in IIGovernanceVotePower ( Docs , Source ). event DelegateVotesChanged ( address delegate , uint256 previousBalance , uint256 newBalance ) Emitted when a delegate 's vote power changes, as a result of a new delegation or a token transfer, for example. The event is always emitted from a GovernanceVotePower contract. Parameters Type Description delegate address The account receiving the changing delegated vote power. previousBalance uint256 Delegated vote power before the change. newBalance uint256 Delegated vote power after the change. Functions # delegate # Defined in IGovernanceVotePower ( Docs , Source ). function delegate ( address _to ) external ; Delegates all governance vote power of msg.sender to address _to . Parameters Type Description _to address The address of the recipient. getCleanupBlockNumber # Defined in IIGovernanceVotePower ( Docs , Source ). function getCleanupBlockNumber ( ) external view returns ( uint256 ); Get the current cleanup block number set with setCleanupBlockNumber . Returns Type Description [0] uint256 The currently set cleanup block number. getDelegateOfAt # Defined in IGovernanceVotePower ( Docs , Source ). function getDelegateOfAt ( address _who , uint256 _blockNumber ) external view returns ( address ); Gets the address an account is delegating its governance vote power to, at a given block number. Parameters Type Description _who address The address being queried. _blockNumber uint256 The block number at which to fetch the address. Returns Type Description [0] address Address where _who was delegating its governance vote power at block _blockNumber . getDelegateOfAtNow # Defined in IGovernanceVotePower ( Docs , Source ). function getDelegateOfAtNow ( address _who ) external view returns ( address ); Gets the address an account is delegating its governance vote power to, at the latest block number. Parameters Type Description _who address The address being queried. Returns Type Description [0] address Address where _who is currently delegating its governance vote power. getVotes # Defined in IGovernanceVotePower ( Docs , Source ). function getVotes ( address _who ) external view returns ( uint256 ); Gets the governance vote power of an address at the latest block, including all delegations made to it. Parameters Type Description _who address The address being queried. Returns Type Description [0] uint256 Governance vote power of account at the lastest block. ownerToken # Defined in IIGovernanceVotePower ( Docs , Source ). function ownerToken ( ) external view returns ( contract IVPToken ); Get the token that this governance vote power contract belongs to. Returns Type Description [0] contract IVPToken The IVPToken interface owning this contract. setCleanerContract # Defined in IIGovernanceVotePower ( Docs , Source ). function setCleanerContract ( address _cleanerContract ) external ; Set the contract that is allowed to call history cleaning methods. Parameters Type Description _cleanerContract address Address of the cleanup contract. Usually this will be an instance of CleanupBlockNumberManager . setCleanupBlockNumber # Defined in IIGovernanceVotePower ( Docs , Source ). function setCleanupBlockNumber ( uint256 _blockNumber ) external ; Set the cleanup block number. Historic data for the blocks before cleanupBlockNumber can be erased. History before that block should never be used since it can be inconsistent. In particular, cleanup block number must be lower than the current vote power block. Parameters Type Description _blockNumber uint256 The new cleanup block number. undelegate # Defined in IGovernanceVotePower ( Docs , Source ). function undelegate ( ) external ; Undelegates all governance vote power of msg.sender . updateAtTokenTransfer # Defined in IIGovernanceVotePower ( Docs , Source ). function updateAtTokenTransfer ( address _from , address _to , uint256 _fromBalance , uint256 _toBalance , uint256 _amount ) external ; Update governance vote power of all involved delegates after tokens are transferred. This function MUST be called after each governance token transfer for the delegates to reflect the correct balance. Parameters Type Description _from address Source address of the transfer. _to address Destination address of the transfer. _fromBalance uint256 Ignored. _toBalance uint256 Ignored. _amount uint256 Amount being transferred. votePowerOfAt # Defined in IGovernanceVotePower ( Docs , Source ). function votePowerOfAt ( address _who , uint256 _blockNumber ) external view returns ( uint256 ); Gets the governance vote power of an address at a given block number, including all delegations made to it. Parameters Type Description _who address The address being queried. _blockNumber uint256 The block number at which to fetch the vote power. Returns Type Description [0] uint256 Governance vote power of _who at _blockNumber .","title":"IIGovernanceVotePower"},{"location":"apis/smart-contracts/IIGovernanceVotePower/#ct_iigovernancevotepower","text":"Source | Inherits from IGovernanceVotePower Internal interface for contracts delegating their governance vote power.","title":"IIGovernanceVotePower"},{"location":"apis/smart-contracts/IIGovernanceVotePower/#events","text":"","title":"Events"},{"location":"apis/smart-contracts/IIGovernanceVotePower/#ev_delegatechanged","text":"Defined in IIGovernanceVotePower ( Docs , Source ). event DelegateChanged ( address delegator , address fromDelegate , address toDelegate ) Emitted when an account starts delegating vote power or switches its delegation to another address. The event is always emitted from a GovernanceVotePower contract. Parameters Type Description delegator address Account delegating its vote power. fromDelegate address Account receiving the delegation before the change. Can be address(0) if there was no previous delegation. toDelegate address Account receiving the delegation after the change. Can be address(0) if delegator just undelegated all its vote power.","title":"DelegateChanged"},{"location":"apis/smart-contracts/IIGovernanceVotePower/#ev_delegatevoteschanged","text":"Defined in IIGovernanceVotePower ( Docs , Source ). event DelegateVotesChanged ( address delegate , uint256 previousBalance , uint256 newBalance ) Emitted when a delegate 's vote power changes, as a result of a new delegation or a token transfer, for example. The event is always emitted from a GovernanceVotePower contract. Parameters Type Description delegate address The account receiving the changing delegated vote power. previousBalance uint256 Delegated vote power before the change. newBalance uint256 Delegated vote power after the change.","title":"DelegateVotesChanged"},{"location":"apis/smart-contracts/IIGovernanceVotePower/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IIGovernanceVotePower/#fn_delegate_5c19a95c","text":"Defined in IGovernanceVotePower ( Docs , Source ). function delegate ( address _to ) external ; Delegates all governance vote power of msg.sender to address _to . Parameters Type Description _to address The address of the recipient.","title":"delegate"},{"location":"apis/smart-contracts/IIGovernanceVotePower/#fn_getcleanupblocknumber_a72ec4b6","text":"Defined in IIGovernanceVotePower ( Docs , Source ). function getCleanupBlockNumber ( ) external view returns ( uint256 ); Get the current cleanup block number set with setCleanupBlockNumber . Returns Type Description [0] uint256 The currently set cleanup block number.","title":"getCleanupBlockNumber"},{"location":"apis/smart-contracts/IIGovernanceVotePower/#fn_getdelegateofat_3c028e9d","text":"Defined in IGovernanceVotePower ( Docs , Source ). function getDelegateOfAt ( address _who , uint256 _blockNumber ) external view returns ( address ); Gets the address an account is delegating its governance vote power to, at a given block number. Parameters Type Description _who address The address being queried. _blockNumber uint256 The block number at which to fetch the address. Returns Type Description [0] address Address where _who was delegating its governance vote power at block _blockNumber .","title":"getDelegateOfAt"},{"location":"apis/smart-contracts/IIGovernanceVotePower/#fn_getdelegateofatnow_b3e871ee","text":"Defined in IGovernanceVotePower ( Docs , Source ). function getDelegateOfAtNow ( address _who ) external view returns ( address ); Gets the address an account is delegating its governance vote power to, at the latest block number. Parameters Type Description _who address The address being queried. Returns Type Description [0] address Address where _who is currently delegating its governance vote power.","title":"getDelegateOfAtNow"},{"location":"apis/smart-contracts/IIGovernanceVotePower/#fn_getvotes_9ab24eb0","text":"Defined in IGovernanceVotePower ( Docs , Source ). function getVotes ( address _who ) external view returns ( uint256 ); Gets the governance vote power of an address at the latest block, including all delegations made to it. Parameters Type Description _who address The address being queried. Returns Type Description [0] uint256 Governance vote power of account at the lastest block.","title":"getVotes"},{"location":"apis/smart-contracts/IIGovernanceVotePower/#fn_ownertoken_65371883","text":"Defined in IIGovernanceVotePower ( Docs , Source ). function ownerToken ( ) external view returns ( contract IVPToken ); Get the token that this governance vote power contract belongs to. Returns Type Description [0] contract IVPToken The IVPToken interface owning this contract.","title":"ownerToken"},{"location":"apis/smart-contracts/IIGovernanceVotePower/#fn_setcleanercontract_f6a494af","text":"Defined in IIGovernanceVotePower ( Docs , Source ). function setCleanerContract ( address _cleanerContract ) external ; Set the contract that is allowed to call history cleaning methods. Parameters Type Description _cleanerContract address Address of the cleanup contract. Usually this will be an instance of CleanupBlockNumberManager .","title":"setCleanerContract"},{"location":"apis/smart-contracts/IIGovernanceVotePower/#fn_setcleanupblocknumber_13de97f5","text":"Defined in IIGovernanceVotePower ( Docs , Source ). function setCleanupBlockNumber ( uint256 _blockNumber ) external ; Set the cleanup block number. Historic data for the blocks before cleanupBlockNumber can be erased. History before that block should never be used since it can be inconsistent. In particular, cleanup block number must be lower than the current vote power block. Parameters Type Description _blockNumber uint256 The new cleanup block number.","title":"setCleanupBlockNumber"},{"location":"apis/smart-contracts/IIGovernanceVotePower/#fn_undelegate_92ab89bb","text":"Defined in IGovernanceVotePower ( Docs , Source ). function undelegate ( ) external ; Undelegates all governance vote power of msg.sender .","title":"undelegate"},{"location":"apis/smart-contracts/IIGovernanceVotePower/#fn_updateattokentransfer_eadb4362","text":"Defined in IIGovernanceVotePower ( Docs , Source ). function updateAtTokenTransfer ( address _from , address _to , uint256 _fromBalance , uint256 _toBalance , uint256 _amount ) external ; Update governance vote power of all involved delegates after tokens are transferred. This function MUST be called after each governance token transfer for the delegates to reflect the correct balance. Parameters Type Description _from address Source address of the transfer. _to address Destination address of the transfer. _fromBalance uint256 Ignored. _toBalance uint256 Ignored. _amount uint256 Amount being transferred.","title":"updateAtTokenTransfer"},{"location":"apis/smart-contracts/IIGovernanceVotePower/#fn_votepowerofat_92bfe6d8","text":"Defined in IGovernanceVotePower ( Docs , Source ). function votePowerOfAt ( address _who , uint256 _blockNumber ) external view returns ( uint256 ); Gets the governance vote power of an address at a given block number, including all delegations made to it. Parameters Type Description _who address The address being queried. _blockNumber uint256 The block number at which to fetch the vote power. Returns Type Description [0] uint256 Governance vote power of _who at _blockNumber .","title":"votePowerOfAt"},{"location":"apis/smart-contracts/IIInflationReceiver/","text":"IIInflationReceiver # Source Internal interface for contracts that can receive inflation. Functions # getContractName # Defined in IIInflationReceiver ( Docs , Source ). function getContractName ( ) external view returns ( string ); Implement this function to allow updating inflation receiver contracts through AddressUpdater . Returns Type Description [0] string Contract name. getExpectedBalance # Defined in IIInflationReceiver ( Docs , Source ). function getExpectedBalance ( ) external view returns ( uint256 ); Returns the contract's expected balance (actual balance may be higher due to self-destruct funds). Returns Type Description [0] uint256 Expected native token balance. getInflationAddress # Defined in IIInflationReceiver ( Docs , Source ). function getInflationAddress ( ) external returns ( address ); Returns the address of the Inflation contract. receiveInflation # Defined in IIInflationReceiver ( Docs , Source ). function receiveInflation ( ) external payable ; Receive native tokens from inflation. setDailyAuthorizedInflation # Defined in IIInflationReceiver ( Docs , Source ). function setDailyAuthorizedInflation ( uint256 _toAuthorizeWei ) external ; Notify the receiver that it is entitled to receive a new inflation amount. Parameters Type Description _toAuthorizeWei uint256 The amount of inflation that can be awarded in the coming day, in wei.","title":"IIInflationReceiver"},{"location":"apis/smart-contracts/IIInflationReceiver/#ct_iiinflationreceiver","text":"Source Internal interface for contracts that can receive inflation.","title":"IIInflationReceiver"},{"location":"apis/smart-contracts/IIInflationReceiver/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IIInflationReceiver/#fn_getcontractname_f5f5ba72","text":"Defined in IIInflationReceiver ( Docs , Source ). function getContractName ( ) external view returns ( string ); Implement this function to allow updating inflation receiver contracts through AddressUpdater . Returns Type Description [0] string Contract name.","title":"getContractName"},{"location":"apis/smart-contracts/IIInflationReceiver/#fn_getexpectedbalance_af04cd3b","text":"Defined in IIInflationReceiver ( Docs , Source ). function getExpectedBalance ( ) external view returns ( uint256 ); Returns the contract's expected balance (actual balance may be higher due to self-destruct funds). Returns Type Description [0] uint256 Expected native token balance.","title":"getExpectedBalance"},{"location":"apis/smart-contracts/IIInflationReceiver/#fn_getinflationaddress_ed39d3f8","text":"Defined in IIInflationReceiver ( Docs , Source ). function getInflationAddress ( ) external returns ( address ); Returns the address of the Inflation contract.","title":"getInflationAddress"},{"location":"apis/smart-contracts/IIInflationReceiver/#fn_receiveinflation_06201f1d","text":"Defined in IIInflationReceiver ( Docs , Source ). function receiveInflation ( ) external payable ; Receive native tokens from inflation.","title":"receiveInflation"},{"location":"apis/smart-contracts/IIInflationReceiver/#fn_setdailyauthorizedinflation_e2739563","text":"Defined in IIInflationReceiver ( Docs , Source ). function setDailyAuthorizedInflation ( uint256 _toAuthorizeWei ) external ; Notify the receiver that it is entitled to receive a new inflation amount. Parameters Type Description _toAuthorizeWei uint256 The amount of inflation that can be awarded in the coming day, in wei.","title":"setDailyAuthorizedInflation"},{"location":"apis/smart-contracts/IIPriceSubmitter/","text":"IIPriceSubmitter # Source | Inherits from IPriceSubmitter Internal interface for the PriceSubmitter contract. Functions # getCurrentRandom # Defined in IPriceSubmitter ( Docs , Source ). function getCurrentRandom ( ) external view returns ( uint256 ); Returns the random number for the previous epoch, obtained from the random numbers provided by all data providers along with their data submissions. Note that the random number for the previous epoch keeps updating as new submissions are revealed. Returns Type Description [0] uint256 Random number calculated from all data provider's submissions. getFtsoManager # Defined in IPriceSubmitter ( Docs , Source ). function getFtsoManager ( ) external view returns ( contract IFtsoManagerGenesis ); Returns the address of the FtsoManager contract. getFtsoRegistry # Defined in IPriceSubmitter ( Docs , Source ). function getFtsoRegistry ( ) external view returns ( contract IFtsoRegistryGenesis ); Returns the address of the FtsoRegistry contract. getRandom # Defined in IPriceSubmitter ( Docs , Source ). function getRandom ( uint256 _epochId ) external view returns ( uint256 ); Returns the random number used in a specific past epoch, obtained from the random numbers provided by all data providers along with their data submissions. Parameters Type Description _epochId uint256 ID of the queried epoch. Current epoch cannot be queried, and the previous epoch is constantly updated as data providers reveal their prices and random numbers. Note that only the last 50 epochs can be queried and there is no bounds checking for this parameter. Out-of-bounds queries return undefined values. Returns Type Description [0] uint256 The random number used in that epoch. getTrustedAddresses # Defined in IIPriceSubmitter ( Docs , Source ). function getTrustedAddresses ( ) external view returns ( address []); Returns the list of trusted addresses that are always allowed to submit and reveal. Returns Type Description [0] address[] address[] Array of trusted voter addresses. getVoterWhitelister # Defined in IPriceSubmitter ( Docs , Source ). function getVoterWhitelister ( ) external view returns ( address ); Returns the address of the VoterWhitelister contract managing the data provider whitelist. revealPrices # Defined in IPriceSubmitter ( Docs , Source ). function revealPrices ( uint256 _epochId , uint256 [] _ftsoIndices , uint256 [] _prices , uint256 _random ) external ; Reveals submitted prices during the epoch reveal period. The hash of FTSO indices, prices, random number, and voter address must be equal to the hash previously submitted with submitHash . Emits a PricesRevealed event. Parameters Type Description _epochId uint256 ID of the epoch to which the price hashes are submitted. _ftsoIndices uint256[] List of FTSO indices in ascending order. _prices uint256[] List of submitted prices in USD. _random uint256 Submitted random number. setTrustedAddresses # Defined in IIPriceSubmitter ( Docs , Source ). function setTrustedAddresses ( address [] _trustedAddresses ) external ; Set trusted addresses that are always allowed to submit and reveal. Only ftso manager can call this method. Parameters Type Description _trustedAddresses address[] Array of voter addresses. submitHash # Defined in IPriceSubmitter ( Docs , Source ). function submitHash ( uint256 _epochId , bytes32 _hash ) external ; Submits a hash for the current epoch. Can only be called by FTSO data providers whitelisted through the VoterWhitelisted contract. Emits the HashSubmitted event. Parameters Type Description _epochId uint256 ID of the target epoch to which the hash is submitted. _hash bytes32 A hash of the FTSO indices, prices, random number, and voter address. voterWhitelistBitmap # Defined in IPriceSubmitter ( Docs , Source ). function voterWhitelistBitmap ( address _voter ) external view returns ( uint256 ); Returns a bitmap of all FTSOs for which a data provider is allowed to submit prices or hashes. Parameters Type Description _voter address Address of the voter. Returns Type Description [0] uint256 If a data provider is allowed to vote for a given FTSO index, the corresponding bit in the result is 1. voterWhitelisted # Defined in IIPriceSubmitter ( Docs , Source ). function voterWhitelisted ( address _voter , uint256 _ftsoIndex ) external ; Called from the VoterWhitelister contract when a new voter has been whitelisted. Parameters Type Description _voter address Voter address that has been added to the whitelist. _ftsoIndex uint256 Index of the FTSO to which the voter has registered. Each FTSO has its own whitelist. votersRemovedFromWhitelist # Defined in IIPriceSubmitter ( Docs , Source ). function votersRemovedFromWhitelist ( address [] _voters , uint256 _ftsoIndex ) external ; Called from the VoterWhitelister contract when one or more voters have been removed. Parameters Type Description _voters address[] Array of voter addresses that have been removed. _ftsoIndex uint256 Index of the FTSO to which the voters were registered. Each FTSO has its own whitelist.","title":"IIPriceSubmitter"},{"location":"apis/smart-contracts/IIPriceSubmitter/#ct_iipricesubmitter","text":"Source | Inherits from IPriceSubmitter Internal interface for the PriceSubmitter contract.","title":"IIPriceSubmitter"},{"location":"apis/smart-contracts/IIPriceSubmitter/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IIPriceSubmitter/#fn_getcurrentrandom_d89601fd","text":"Defined in IPriceSubmitter ( Docs , Source ). function getCurrentRandom ( ) external view returns ( uint256 ); Returns the random number for the previous epoch, obtained from the random numbers provided by all data providers along with their data submissions. Note that the random number for the previous epoch keeps updating as new submissions are revealed. Returns Type Description [0] uint256 Random number calculated from all data provider's submissions.","title":"getCurrentRandom"},{"location":"apis/smart-contracts/IIPriceSubmitter/#fn_getftsomanager_b39c6858","text":"Defined in IPriceSubmitter ( Docs , Source ). function getFtsoManager ( ) external view returns ( contract IFtsoManagerGenesis ); Returns the address of the FtsoManager contract.","title":"getFtsoManager"},{"location":"apis/smart-contracts/IIPriceSubmitter/#fn_getftsoregistry_8c9d28b6","text":"Defined in IPriceSubmitter ( Docs , Source ). function getFtsoRegistry ( ) external view returns ( contract IFtsoRegistryGenesis ); Returns the address of the FtsoRegistry contract.","title":"getFtsoRegistry"},{"location":"apis/smart-contracts/IIPriceSubmitter/#fn_getrandom_cd4b6914","text":"Defined in IPriceSubmitter ( Docs , Source ). function getRandom ( uint256 _epochId ) external view returns ( uint256 ); Returns the random number used in a specific past epoch, obtained from the random numbers provided by all data providers along with their data submissions. Parameters Type Description _epochId uint256 ID of the queried epoch. Current epoch cannot be queried, and the previous epoch is constantly updated as data providers reveal their prices and random numbers. Note that only the last 50 epochs can be queried and there is no bounds checking for this parameter. Out-of-bounds queries return undefined values. Returns Type Description [0] uint256 The random number used in that epoch.","title":"getRandom"},{"location":"apis/smart-contracts/IIPriceSubmitter/#fn_gettrustedaddresses_ffacb84e","text":"Defined in IIPriceSubmitter ( Docs , Source ). function getTrustedAddresses ( ) external view returns ( address []); Returns the list of trusted addresses that are always allowed to submit and reveal. Returns Type Description [0] address[] address[] Array of trusted voter addresses.","title":"getTrustedAddresses"},{"location":"apis/smart-contracts/IIPriceSubmitter/#fn_getvoterwhitelister_71e1fad9","text":"Defined in IPriceSubmitter ( Docs , Source ). function getVoterWhitelister ( ) external view returns ( address ); Returns the address of the VoterWhitelister contract managing the data provider whitelist.","title":"getVoterWhitelister"},{"location":"apis/smart-contracts/IIPriceSubmitter/#fn_revealprices_e2db5a52","text":"Defined in IPriceSubmitter ( Docs , Source ). function revealPrices ( uint256 _epochId , uint256 [] _ftsoIndices , uint256 [] _prices , uint256 _random ) external ; Reveals submitted prices during the epoch reveal period. The hash of FTSO indices, prices, random number, and voter address must be equal to the hash previously submitted with submitHash . Emits a PricesRevealed event. Parameters Type Description _epochId uint256 ID of the epoch to which the price hashes are submitted. _ftsoIndices uint256[] List of FTSO indices in ascending order. _prices uint256[] List of submitted prices in USD. _random uint256 Submitted random number.","title":"revealPrices"},{"location":"apis/smart-contracts/IIPriceSubmitter/#fn_settrustedaddresses_9ec2b581","text":"Defined in IIPriceSubmitter ( Docs , Source ). function setTrustedAddresses ( address [] _trustedAddresses ) external ; Set trusted addresses that are always allowed to submit and reveal. Only ftso manager can call this method. Parameters Type Description _trustedAddresses address[] Array of voter addresses.","title":"setTrustedAddresses"},{"location":"apis/smart-contracts/IIPriceSubmitter/#fn_submithash_8fc6f667","text":"Defined in IPriceSubmitter ( Docs , Source ). function submitHash ( uint256 _epochId , bytes32 _hash ) external ; Submits a hash for the current epoch. Can only be called by FTSO data providers whitelisted through the VoterWhitelisted contract. Emits the HashSubmitted event. Parameters Type Description _epochId uint256 ID of the target epoch to which the hash is submitted. _hash bytes32 A hash of the FTSO indices, prices, random number, and voter address.","title":"submitHash"},{"location":"apis/smart-contracts/IIPriceSubmitter/#fn_voterwhitelistbitmap_7ac420ad","text":"Defined in IPriceSubmitter ( Docs , Source ). function voterWhitelistBitmap ( address _voter ) external view returns ( uint256 ); Returns a bitmap of all FTSOs for which a data provider is allowed to submit prices or hashes. Parameters Type Description _voter address Address of the voter. Returns Type Description [0] uint256 If a data provider is allowed to vote for a given FTSO index, the corresponding bit in the result is 1.","title":"voterWhitelistBitmap"},{"location":"apis/smart-contracts/IIPriceSubmitter/#fn_voterwhitelisted_9d986f91","text":"Defined in IIPriceSubmitter ( Docs , Source ). function voterWhitelisted ( address _voter , uint256 _ftsoIndex ) external ; Called from the VoterWhitelister contract when a new voter has been whitelisted. Parameters Type Description _voter address Voter address that has been added to the whitelist. _ftsoIndex uint256 Index of the FTSO to which the voter has registered. Each FTSO has its own whitelist.","title":"voterWhitelisted"},{"location":"apis/smart-contracts/IIPriceSubmitter/#fn_votersremovedfromwhitelist_76794efb","text":"Defined in IIPriceSubmitter ( Docs , Source ). function votersRemovedFromWhitelist ( address [] _voters , uint256 _ftsoIndex ) external ; Called from the VoterWhitelister contract when one or more voters have been removed. Parameters Type Description _voters address[] Array of voter addresses that have been removed. _ftsoIndex uint256 Index of the FTSO to which the voters were registered. Each FTSO has its own whitelist.","title":"votersRemovedFromWhitelist"},{"location":"apis/smart-contracts/IITokenPool/","text":"IITokenPool # Source Internal interface for token pools. Functions # getTokenPoolSupplyData # Defined in IITokenPool ( Docs , Source ). function getTokenPoolSupplyData ( ) external returns ( uint256 _lockedFundsWei , uint256 _totalInflationAuthorizedWei , uint256 _totalClaimedWei ); Returns token pool supply data. Returns Type Description _lockedFundsWei uint256 Total amount of funds ever locked in the token pool (wei). _lockedFundsWei - _totalClaimedWei is the amount currently locked and outside the circulating supply. _totalInflationAuthorizedWei uint256 Total inflation authorized amount (wei). _totalClaimedWei uint256 Total claimed amount (wei).","title":"IITokenPool"},{"location":"apis/smart-contracts/IITokenPool/#ct_iitokenpool","text":"Source Internal interface for token pools.","title":"IITokenPool"},{"location":"apis/smart-contracts/IITokenPool/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IITokenPool/#fn_gettokenpoolsupplydata_2dafdbbf","text":"Defined in IITokenPool ( Docs , Source ). function getTokenPoolSupplyData ( ) external returns ( uint256 _lockedFundsWei , uint256 _totalInflationAuthorizedWei , uint256 _totalClaimedWei ); Returns token pool supply data. Returns Type Description _lockedFundsWei uint256 Total amount of funds ever locked in the token pool (wei). _lockedFundsWei - _totalClaimedWei is the amount currently locked and outside the circulating supply. _totalInflationAuthorizedWei uint256 Total inflation authorized amount (wei). _totalClaimedWei uint256 Total claimed amount (wei).","title":"getTokenPoolSupplyData"},{"location":"apis/smart-contracts/IIVPContract/","text":"IIVPContract # Source | Inherits from IICleanable , IVPContractEvents Internal interface for helper contracts handling functionality for an associated VPToken . Functions # batchVotePowerOfAt # Defined in IIVPContract ( Docs , Source ). function batchVotePowerOfAt ( address [] _owners , uint256 _blockNumber ) external view returns ( uint256 []); Get the vote power of a set of addresses at a given block number. Parameters Type Description _owners address[] The list of addresses being queried. _blockNumber uint256 The block number being queried. Returns Type Description [0] uint256[] Vote power of each address at _blockNumber , including any delegation received. cleanupBlockNumber # Defined in IICleanable ( Docs , Source ). function cleanupBlockNumber ( ) external view returns ( uint256 ); Get the current cleanup block number set with setCleanupBlockNumber . Returns Type Description [0] uint256 The currently set cleanup block number. delegate # Defined in IIVPContract ( Docs , Source ). function delegate ( address _from , address _to , uint256 _balance , uint256 _bips ) external ; Delegate _bips percentage of voting power from a delegator address to a delegatee address. Parameters Type Description _from address The address of the delegator. _to address The address of the delegatee. _balance uint256 The delegator's current balance _bips uint256 The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: every call resets the delegation value (and a value of 0 revokes delegation). delegateExplicit # Defined in IIVPContract ( Docs , Source ). function delegateExplicit ( address _from , address _to , uint256 _balance , uint256 _amount ) external ; Explicitly delegate _amount tokens of voting power from a delegator address to a delegatee address. Parameters Type Description _from address The address of the delegator. _to address The address of the delegatee. _balance uint256 The delegator's current balance. _amount uint256 An explicit vote power amount to be delegated. Not cumulative: every call resets the delegation value (and a value of 0 undelegates _to ). delegatesOf # Defined in IIVPContract ( Docs , Source ). function delegatesOf ( address _owner ) external view returns ( address [] _delegateAddresses , uint256 [] _bips , uint256 _count , uint256 _delegationMode ); Get the percentages and addresses being delegated to by a vote power delegator. Parameters Type Description _owner address The address of the delegator being queried. Returns Type Description _delegateAddresses address[] Array of delegatee addresses. _bips uint256[] Array of delegation percents specified in basis points (1/100 or 1 percent), for each delegatee. _count uint256 The number of returned delegatees. _delegationMode uint256 The mode of the delegation (NOTSET=0, PERCENTAGE=1, AMOUNT=2). See Delegatable .DelegationMode. delegatesOfAt # Defined in IIVPContract ( Docs , Source ). function delegatesOfAt ( address _owner , uint256 _blockNumber ) external view returns ( address [] _delegateAddresses , uint256 [] _bips , uint256 _count , uint256 _delegationMode ); Get the percentages and addresses being delegated to by a vote power delegator, at a given block. Parameters Type Description _owner address The address of the delegator being queried. _blockNumber uint256 The block number being queried. Returns Type Description _delegateAddresses address[] Array of delegatee addresses. _bips uint256[] Array of delegation percents specified in basis points (1/100 or 1 percent), for each delegatee. _count uint256 The number of returned delegatees. _delegationMode uint256 The mode of the delegation (NOTSET=0, PERCENTAGE=1, AMOUNT=2). See Delegatable .DelegationMode. delegationModeOf # Defined in IIVPContract ( Docs , Source ). function delegationModeOf ( address _who ) external view returns ( uint256 ); Get the delegation mode of an address. This mode determines whether vote power is allocated by percentage or by explicit value and cannot be changed once set with delegate or delegateExplicit . Parameters Type Description _who address The address being queried. Returns Type Description [0] uint256 Delegation mode (NOTSET=0, PERCENTAGE=1, AMOUNT=2). See Delegatable .DelegationMode. isReplacement # Defined in IIVPContract ( Docs , Source ). function isReplacement ( ) external view returns ( bool ); Return true if this IIVPContract is configured to be used as a replacement for other contract. It means that vote powers are not necessarily correct at the initialization, therefore every method that reads vote power must check whether it is initialized for that address and block. ownerToken # Defined in IIVPContract ( Docs , Source ). function ownerToken ( ) external view returns ( contract IVPToken ); The VPToken (or some other contract) that owns this VPContract . All state changing methods may be called only from this address. This is because original msg.sender is typically sent in a parameter and we must make sure that it cannot be faked by directly calling IIVPContract methods. Owner token is also used in case of replacement to recover vote powers from balances. revokeDelegationAt # Defined in IIVPContract ( Docs , Source ). function revokeDelegationAt ( address _from , address _to , uint256 _balance , uint256 _blockNumber ) external ; Revoke all vote power delegation from a delegator address to a delegatee address at a given block. Only affects the reads via votePowerOfAtCached in the block _blockNumber . This method should be used only to prevent rogue delegate voting in the current voting block. To stop delegating use delegate or delegateExplicit with value of 0, or undelegateAll / undelegateAllExplicit . Parameters Type Description _from address The address of the delegator. _to address Address of the delegatee. _balance uint256 The delegator's current balance. _blockNumber uint256 The block number at which to revoke delegation. Must be in the past. setCleanerContract # Defined in IICleanable ( Docs , Source ). function setCleanerContract ( address _cleanerContract ) external ; Set the contract that is allowed to call history cleaning methods. Parameters Type Description _cleanerContract address Address of the cleanup contract. Usually this will be an instance of CleanupBlockNumberManager . setCleanupBlockNumber # Defined in IICleanable ( Docs , Source ). function setCleanupBlockNumber ( uint256 _blockNumber ) external ; Set the cleanup block number. Historic data for the blocks before cleanupBlockNumber can be erased. History before that block should never be used since it can be inconsistent. In particular, cleanup block number must be lower than the current vote power block. Parameters Type Description _blockNumber uint256 The new cleanup block number. undelegateAll # Defined in IIVPContract ( Docs , Source ). function undelegateAll ( address _from , uint256 _balance ) external ; Undelegate all voting power for a delegator address. Can only be used with percentage delegation. Does not reset delegation mode back to NOTSET . Parameters Type Description _from address The address of the delegator. _balance uint256 The delegator's current balance. undelegateAllExplicit # Defined in IIVPContract ( Docs , Source ). function undelegateAllExplicit ( address _from , address [] _delegateAddresses ) external returns ( uint256 ); Undelegate all explicit vote power by amount for a delegator address. Can only be used with explicit delegation. Does not reset delegation mode back to NOTSET . Parameters Type Description _from address The address of the delegator. _delegateAddresses address[] Explicit delegation does not store delegatees' addresses, so the caller must supply them. Returns Type Description [0] uint256 The amount still delegated (in case the list of delegates was incomplete). undelegatedVotePowerOf # Defined in IIVPContract ( Docs , Source ). function undelegatedVotePowerOf ( address _owner , uint256 _balance ) external view returns ( uint256 ); Compute the current undelegated vote power of an address. Parameters Type Description _owner address The address being queried. _balance uint256 Current balance of that address. Returns Type Description [0] uint256 The unallocated vote power of _owner , this is, the amount of vote power currently not being delegated to other addresses. undelegatedVotePowerOfAt # Defined in IIVPContract ( Docs , Source ). function undelegatedVotePowerOfAt ( address _owner , uint256 _balance , uint256 _blockNumber ) external view returns ( uint256 ); Compute the undelegated vote power of an address at a given block. Parameters Type Description _owner address The address being queried. _balance uint256 _blockNumber uint256 The block number being queried. Returns Type Description [0] uint256 The unallocated vote power of _owner , this is, the amount of vote power that was not being delegated to other addresses at that block number. updateAtTokenTransfer # Defined in IIVPContract ( Docs , Source ). function updateAtTokenTransfer ( address _from , address _to , uint256 _fromBalance , uint256 _toBalance , uint256 _amount ) external ; Update vote powers when tokens are transferred. Also update delegated vote powers for percentage delegation and check for enough funds for explicit delegations. Parameters Type Description _from address Source account of the transfer. _to address Destination account of the transfer. _fromBalance uint256 Balance of the source account before the transfer. _toBalance uint256 Balance of the destination account before the transfer. _amount uint256 Amount that has been transferred. votePowerFromTo # Defined in IIVPContract ( Docs , Source ). function votePowerFromTo ( address _from , address _to , uint256 _balance ) external view returns ( uint256 ); Get current delegated vote power from a delegator to a delegatee. Parameters Type Description _from address Address of the delegator. _to address Address of the delegatee. _balance uint256 The delegator's current balance. Returns Type Description [0] uint256 The delegated vote power. votePowerFromToAt # Defined in IIVPContract ( Docs , Source ). function votePowerFromToAt ( address _from , address _to , uint256 _balance , uint256 _blockNumber ) external view returns ( uint256 ); Get delegated the vote power from a delegator to a delegatee at a given block number. Parameters Type Description _from address Address of the delegator. _to address Address of the delegatee. _balance uint256 The delegator's current balance. _blockNumber uint256 The block number being queried. Returns Type Description [0] uint256 The delegated vote power. votePowerOf # Defined in IIVPContract ( Docs , Source ). function votePowerOf ( address _who ) external view returns ( uint256 ); Get the current vote power of an address. Parameters Type Description _who address The address being queried. Returns Type Description [0] uint256 Current vote power of _who , including any delegation received. votePowerOfAt # Defined in IIVPContract ( Docs , Source ). function votePowerOfAt ( address _who , uint256 _blockNumber ) external view returns ( uint256 ); Get the vote power of an address at a given block number Parameters Type Description _who address The address being queried. _blockNumber uint256 The block number being queried. Returns Type Description [0] uint256 Vote power of _who at _blockNumber , including any delegation received. votePowerOfAtCached # Defined in IIVPContract ( Docs , Source ). function votePowerOfAtCached ( address _who , uint256 _blockNumber ) external returns ( uint256 ); Get the vote power of an address at a given block number. Reads/updates cache and upholds revocations. Parameters Type Description _who address The address being queried. _blockNumber uint256 The block number being queried. Returns Type Description [0] uint256 Vote power of _who at _blockNumber , including any delegation received. votePowerOfAtIgnoringRevocation # Defined in IIVPContract ( Docs , Source ). function votePowerOfAtIgnoringRevocation ( address _who , uint256 _blockNumber ) external view returns ( uint256 ); Get the vote power of an address at a given block number, ignoring revocation information and cache. Parameters Type Description _who address The address being queried. _blockNumber uint256 The block number being queried. Returns Type Description [0] uint256 Vote power of _who at _blockNumber , including any delegation received. Result doesn't change if vote power is revoked.","title":"IIVPContract"},{"location":"apis/smart-contracts/IIVPContract/#ct_iivpcontract","text":"Source | Inherits from IICleanable , IVPContractEvents Internal interface for helper contracts handling functionality for an associated VPToken .","title":"IIVPContract"},{"location":"apis/smart-contracts/IIVPContract/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IIVPContract/#fn_batchvotepowerofat_49e3c7e5","text":"Defined in IIVPContract ( Docs , Source ). function batchVotePowerOfAt ( address [] _owners , uint256 _blockNumber ) external view returns ( uint256 []); Get the vote power of a set of addresses at a given block number. Parameters Type Description _owners address[] The list of addresses being queried. _blockNumber uint256 The block number being queried. Returns Type Description [0] uint256[] Vote power of each address at _blockNumber , including any delegation received.","title":"batchVotePowerOfAt"},{"location":"apis/smart-contracts/IIVPContract/#fn_cleanupblocknumber_deea13e7","text":"Defined in IICleanable ( Docs , Source ). function cleanupBlockNumber ( ) external view returns ( uint256 ); Get the current cleanup block number set with setCleanupBlockNumber . Returns Type Description [0] uint256 The currently set cleanup block number.","title":"cleanupBlockNumber"},{"location":"apis/smart-contracts/IIVPContract/#fn_delegate_6230001a","text":"Defined in IIVPContract ( Docs , Source ). function delegate ( address _from , address _to , uint256 _balance , uint256 _bips ) external ; Delegate _bips percentage of voting power from a delegator address to a delegatee address. Parameters Type Description _from address The address of the delegator. _to address The address of the delegatee. _balance uint256 The delegator's current balance _bips uint256 The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: every call resets the delegation value (and a value of 0 revokes delegation).","title":"delegate"},{"location":"apis/smart-contracts/IIVPContract/#fn_delegateexplicit_404d9e82","text":"Defined in IIVPContract ( Docs , Source ). function delegateExplicit ( address _from , address _to , uint256 _balance , uint256 _amount ) external ; Explicitly delegate _amount tokens of voting power from a delegator address to a delegatee address. Parameters Type Description _from address The address of the delegator. _to address The address of the delegatee. _balance uint256 The delegator's current balance. _amount uint256 An explicit vote power amount to be delegated. Not cumulative: every call resets the delegation value (and a value of 0 undelegates _to ).","title":"delegateExplicit"},{"location":"apis/smart-contracts/IIVPContract/#fn_delegatesof_7de5b8ed","text":"Defined in IIVPContract ( Docs , Source ). function delegatesOf ( address _owner ) external view returns ( address [] _delegateAddresses , uint256 [] _bips , uint256 _count , uint256 _delegationMode ); Get the percentages and addresses being delegated to by a vote power delegator. Parameters Type Description _owner address The address of the delegator being queried. Returns Type Description _delegateAddresses address[] Array of delegatee addresses. _bips uint256[] Array of delegation percents specified in basis points (1/100 or 1 percent), for each delegatee. _count uint256 The number of returned delegatees. _delegationMode uint256 The mode of the delegation (NOTSET=0, PERCENTAGE=1, AMOUNT=2). See Delegatable .DelegationMode.","title":"delegatesOf"},{"location":"apis/smart-contracts/IIVPContract/#fn_delegatesofat_ed475a79","text":"Defined in IIVPContract ( Docs , Source ). function delegatesOfAt ( address _owner , uint256 _blockNumber ) external view returns ( address [] _delegateAddresses , uint256 [] _bips , uint256 _count , uint256 _delegationMode ); Get the percentages and addresses being delegated to by a vote power delegator, at a given block. Parameters Type Description _owner address The address of the delegator being queried. _blockNumber uint256 The block number being queried. Returns Type Description _delegateAddresses address[] Array of delegatee addresses. _bips uint256[] Array of delegation percents specified in basis points (1/100 or 1 percent), for each delegatee. _count uint256 The number of returned delegatees. _delegationMode uint256 The mode of the delegation (NOTSET=0, PERCENTAGE=1, AMOUNT=2). See Delegatable .DelegationMode.","title":"delegatesOfAt"},{"location":"apis/smart-contracts/IIVPContract/#fn_delegationmodeof_f6837767","text":"Defined in IIVPContract ( Docs , Source ). function delegationModeOf ( address _who ) external view returns ( uint256 ); Get the delegation mode of an address. This mode determines whether vote power is allocated by percentage or by explicit value and cannot be changed once set with delegate or delegateExplicit . Parameters Type Description _who address The address being queried. Returns Type Description [0] uint256 Delegation mode (NOTSET=0, PERCENTAGE=1, AMOUNT=2). See Delegatable .DelegationMode.","title":"delegationModeOf"},{"location":"apis/smart-contracts/IIVPContract/#fn_isreplacement_aa94d3f2","text":"Defined in IIVPContract ( Docs , Source ). function isReplacement ( ) external view returns ( bool ); Return true if this IIVPContract is configured to be used as a replacement for other contract. It means that vote powers are not necessarily correct at the initialization, therefore every method that reads vote power must check whether it is initialized for that address and block.","title":"isReplacement"},{"location":"apis/smart-contracts/IIVPContract/#fn_ownertoken_65371883","text":"Defined in IIVPContract ( Docs , Source ). function ownerToken ( ) external view returns ( contract IVPToken ); The VPToken (or some other contract) that owns this VPContract . All state changing methods may be called only from this address. This is because original msg.sender is typically sent in a parameter and we must make sure that it cannot be faked by directly calling IIVPContract methods. Owner token is also used in case of replacement to recover vote powers from balances.","title":"ownerToken"},{"location":"apis/smart-contracts/IIVPContract/#fn_revokedelegationat_c7c62fab","text":"Defined in IIVPContract ( Docs , Source ). function revokeDelegationAt ( address _from , address _to , uint256 _balance , uint256 _blockNumber ) external ; Revoke all vote power delegation from a delegator address to a delegatee address at a given block. Only affects the reads via votePowerOfAtCached in the block _blockNumber . This method should be used only to prevent rogue delegate voting in the current voting block. To stop delegating use delegate or delegateExplicit with value of 0, or undelegateAll / undelegateAllExplicit . Parameters Type Description _from address The address of the delegator. _to address Address of the delegatee. _balance uint256 The delegator's current balance. _blockNumber uint256 The block number at which to revoke delegation. Must be in the past.","title":"revokeDelegationAt"},{"location":"apis/smart-contracts/IIVPContract/#fn_setcleanercontract_f6a494af","text":"Defined in IICleanable ( Docs , Source ). function setCleanerContract ( address _cleanerContract ) external ; Set the contract that is allowed to call history cleaning methods. Parameters Type Description _cleanerContract address Address of the cleanup contract. Usually this will be an instance of CleanupBlockNumberManager .","title":"setCleanerContract"},{"location":"apis/smart-contracts/IIVPContract/#fn_setcleanupblocknumber_13de97f5","text":"Defined in IICleanable ( Docs , Source ). function setCleanupBlockNumber ( uint256 _blockNumber ) external ; Set the cleanup block number. Historic data for the blocks before cleanupBlockNumber can be erased. History before that block should never be used since it can be inconsistent. In particular, cleanup block number must be lower than the current vote power block. Parameters Type Description _blockNumber uint256 The new cleanup block number.","title":"setCleanupBlockNumber"},{"location":"apis/smart-contracts/IIVPContract/#fn_undelegateall_05109ecf","text":"Defined in IIVPContract ( Docs , Source ). function undelegateAll ( address _from , uint256 _balance ) external ; Undelegate all voting power for a delegator address. Can only be used with percentage delegation. Does not reset delegation mode back to NOTSET . Parameters Type Description _from address The address of the delegator. _balance uint256 The delegator's current balance.","title":"undelegateAll"},{"location":"apis/smart-contracts/IIVPContract/#fn_undelegateallexplicit_0f8b8af7","text":"Defined in IIVPContract ( Docs , Source ). function undelegateAllExplicit ( address _from , address [] _delegateAddresses ) external returns ( uint256 ); Undelegate all explicit vote power by amount for a delegator address. Can only be used with explicit delegation. Does not reset delegation mode back to NOTSET . Parameters Type Description _from address The address of the delegator. _delegateAddresses address[] Explicit delegation does not store delegatees' addresses, so the caller must supply them. Returns Type Description [0] uint256 The amount still delegated (in case the list of delegates was incomplete).","title":"undelegateAllExplicit"},{"location":"apis/smart-contracts/IIVPContract/#fn_undelegatedvotepowerof_4a03d556","text":"Defined in IIVPContract ( Docs , Source ). function undelegatedVotePowerOf ( address _owner , uint256 _balance ) external view returns ( uint256 ); Compute the current undelegated vote power of an address. Parameters Type Description _owner address The address being queried. _balance uint256 Current balance of that address. Returns Type Description [0] uint256 The unallocated vote power of _owner , this is, the amount of vote power currently not being delegated to other addresses.","title":"undelegatedVotePowerOf"},{"location":"apis/smart-contracts/IIVPContract/#fn_undelegatedvotepowerofat_31503927","text":"Defined in IIVPContract ( Docs , Source ). function undelegatedVotePowerOfAt ( address _owner , uint256 _balance , uint256 _blockNumber ) external view returns ( uint256 ); Compute the undelegated vote power of an address at a given block. Parameters Type Description _owner address The address being queried. _balance uint256 _blockNumber uint256 The block number being queried. Returns Type Description [0] uint256 The unallocated vote power of _owner , this is, the amount of vote power that was not being delegated to other addresses at that block number.","title":"undelegatedVotePowerOfAt"},{"location":"apis/smart-contracts/IIVPContract/#fn_updateattokentransfer_eadb4362","text":"Defined in IIVPContract ( Docs , Source ). function updateAtTokenTransfer ( address _from , address _to , uint256 _fromBalance , uint256 _toBalance , uint256 _amount ) external ; Update vote powers when tokens are transferred. Also update delegated vote powers for percentage delegation and check for enough funds for explicit delegations. Parameters Type Description _from address Source account of the transfer. _to address Destination account of the transfer. _fromBalance uint256 Balance of the source account before the transfer. _toBalance uint256 Balance of the destination account before the transfer. _amount uint256 Amount that has been transferred.","title":"updateAtTokenTransfer"},{"location":"apis/smart-contracts/IIVPContract/#fn_votepowerfromto_9dc6b9f2","text":"Defined in IIVPContract ( Docs , Source ). function votePowerFromTo ( address _from , address _to , uint256 _balance ) external view returns ( uint256 ); Get current delegated vote power from a delegator to a delegatee. Parameters Type Description _from address Address of the delegator. _to address Address of the delegatee. _balance uint256 The delegator's current balance. Returns Type Description [0] uint256 The delegated vote power.","title":"votePowerFromTo"},{"location":"apis/smart-contracts/IIVPContract/#fn_votepowerfromtoat_833aca92","text":"Defined in IIVPContract ( Docs , Source ). function votePowerFromToAt ( address _from , address _to , uint256 _balance , uint256 _blockNumber ) external view returns ( uint256 ); Get delegated the vote power from a delegator to a delegatee at a given block number. Parameters Type Description _from address Address of the delegator. _to address Address of the delegatee. _balance uint256 The delegator's current balance. _blockNumber uint256 The block number being queried. Returns Type Description [0] uint256 The delegated vote power.","title":"votePowerFromToAt"},{"location":"apis/smart-contracts/IIVPContract/#fn_votepowerof_142d1018","text":"Defined in IIVPContract ( Docs , Source ). function votePowerOf ( address _who ) external view returns ( uint256 ); Get the current vote power of an address. Parameters Type Description _who address The address being queried. Returns Type Description [0] uint256 Current vote power of _who , including any delegation received.","title":"votePowerOf"},{"location":"apis/smart-contracts/IIVPContract/#fn_votepowerofat_92bfe6d8","text":"Defined in IIVPContract ( Docs , Source ). function votePowerOfAt ( address _who , uint256 _blockNumber ) external view returns ( uint256 ); Get the vote power of an address at a given block number Parameters Type Description _who address The address being queried. _blockNumber uint256 The block number being queried. Returns Type Description [0] uint256 Vote power of _who at _blockNumber , including any delegation received.","title":"votePowerOfAt"},{"location":"apis/smart-contracts/IIVPContract/#fn_votepowerofatcached_e587497e","text":"Defined in IIVPContract ( Docs , Source ). function votePowerOfAtCached ( address _who , uint256 _blockNumber ) external returns ( uint256 ); Get the vote power of an address at a given block number. Reads/updates cache and upholds revocations. Parameters Type Description _who address The address being queried. _blockNumber uint256 The block number being queried. Returns Type Description [0] uint256 Vote power of _who at _blockNumber , including any delegation received.","title":"votePowerOfAtCached"},{"location":"apis/smart-contracts/IIVPContract/#fn_votepowerofatignoringrevocation_04bb4e43","text":"Defined in IIVPContract ( Docs , Source ). function votePowerOfAtIgnoringRevocation ( address _who , uint256 _blockNumber ) external view returns ( uint256 ); Get the vote power of an address at a given block number, ignoring revocation information and cache. Parameters Type Description _who address The address being queried. _blockNumber uint256 The block number being queried. Returns Type Description [0] uint256 Vote power of _who at _blockNumber , including any delegation received. Result doesn't change if vote power is revoked.","title":"votePowerOfAtIgnoringRevocation"},{"location":"apis/smart-contracts/IIVPToken/","text":"IIVPToken # Source | Inherits from IVPToken , IICleanable Vote power token internal interface. Functions # allowance # Defined in IERC20 ( Source ). function allowance ( address owner , address spender ) external view returns ( uint256 ); Returns the remaining number of tokens that spender will be allowed to spend on behalf of owner through transferFrom . This is zero by default. This value changes when approve or transferFrom are called. approve # Defined in IERC20 ( Source ). function approve ( address spender , uint256 amount ) external returns ( bool ); Sets amount as the allowance of spender over the caller's tokens. Returns a boolean value indicating whether the operation succeeded. IMPORTANT: Beware that changing an allowance with this method brings the risk that someone may use both the old and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 Emits an Approval event. balanceOf # Defined in IERC20 ( Source ). function balanceOf ( address account ) external view returns ( uint256 ); Returns the amount of tokens owned by account . balanceOfAt # Defined in IVPToken ( Docs , Source ). function balanceOfAt ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Queries the token balance of _owner at a specific _blockNumber . Parameters Type Description _owner address The address from which the balance will be retrieved. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The balance at _blockNumber . batchDelegate # Defined in IVPToken ( Docs , Source ). function batchDelegate ( address [] _delegatees , uint256 [] _bips ) external ; Undelegate all percentage delegations from the sender and then delegate corresponding _bips percentage of voting power from the sender to each member of the _delegatees array. Parameters Type Description _delegatees address[] The addresses of the new recipients. _bips uint256[] The percentages of voting power to be delegated expressed in basis points (1/100 of one percent). The sum of all _bips values must be at most 10000 (100%). batchVotePowerOfAt # Defined in IIVPToken ( Docs , Source ). function batchVotePowerOfAt ( address [] _owners , uint256 _blockNumber ) external view returns ( uint256 []); Return the vote power for several addresses. Parameters Type Description _owners address[] The list of addresses to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256[] Array of vote power for each queried address. cleanupBlockNumber # Defined in IICleanable ( Docs , Source ). function cleanupBlockNumber ( ) external view returns ( uint256 ); Get the current cleanup block number set with setCleanupBlockNumber . Returns Type Description [0] uint256 The currently set cleanup block number. decimals # Defined in IVPToken ( Docs , Source ). function decimals ( ) external view returns ( uint8 ); Returns the number of decimals used to get its user representation. For example, if decimals equals 2, a balance of 505 tokens should be displayed to a user as 5.05 (505 / 10 2 ). Tokens usually opt for a value of 18, imitating the relationship between Ether and wei. This is the default value returned by this function, unless it's overridden. NOTE: This information is only used for display purposes: it in no way affects any of the arithmetic of the contract, including balanceOf and transfer . Should be compatible with ERC20 method. delegate # Defined in IVPToken ( Docs , Source ). function delegate ( address _to , uint256 _bips ) external ; Delegate voting power to account _to from msg.sender , by percentage. Parameters Type Description _to address The address of the recipient. _bips uint256 The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: every call resets the delegation value (and a value of 0 revokes all previous delegations). delegateExplicit # Defined in IVPToken ( Docs , Source ). function delegateExplicit ( address _to , uint256 _amount ) external ; Explicitly delegate _amount voting power to account _to from msg.sender . Compare with delegate which delegates by percentage. Parameters Type Description _to address The address of the recipient. _amount uint256 An explicit vote power amount to be delegated. Not cumulative: every call resets the delegation value (and a value of 0 revokes all previous delegations). delegatesOf # Defined in IVPToken ( Docs , Source ). function delegatesOf ( address _who ) external view returns ( address [] _delegateAddresses , uint256 [] _bips , uint256 _count , uint256 _delegationMode ); Get the list of addresses to which _who is delegating, and their percentages. Parameters Type Description _who address The address to query. Returns Type Description _delegateAddresses address[] Positional array of addresses being delegated to. _bips uint256[] Positional array of delegation percents specified in basis points (1/100 of 1 percent). Each one matches the address in the same position in the _delegateAddresses array. _count uint256 The number of delegates. _delegationMode uint256 Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit). delegatesOfAt # Defined in IVPToken ( Docs , Source ). function delegatesOfAt ( address _who , uint256 _blockNumber ) external view returns ( address [] _delegateAddresses , uint256 [] _bips , uint256 _count , uint256 _delegationMode ); Get the list of addresses to which _who is delegating, and their percentages, at the given block. Parameters Type Description _who address The address to query. _blockNumber uint256 The block number to query. Returns Type Description _delegateAddresses address[] Positional array of addresses being delegated to. _bips uint256[] Positional array of delegation percents specified in basis points (1/100 of 1 percent). Each one matches the address in the same position in the _delegateAddresses array. _count uint256 The number of delegates. _delegationMode uint256 Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit). delegationModeOf # Defined in IVPToken ( Docs , Source ). function delegationModeOf ( address _who ) external view returns ( uint256 ); Get the delegation mode for account '_who'. This mode determines whether vote power is allocated by percentage or by explicit amount. Once the delegation mode is set, it can never be changed, even if all delegations are removed. Parameters Type Description _who address The address to get delegation mode. Returns Type Description [0] uint256 Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit). governanceVotePower # Defined in IVPToken ( Docs , Source ). function governanceVotePower ( ) external view returns ( contract IGovernanceVotePower ); When set, allows token owners to participate in governance voting and delegating governance vote power. name # Defined in IVPToken ( Docs , Source ). function name ( ) external view returns ( string ); Returns the name of the token. Should be compatible with ERC20 method. readVotePowerContract # Defined in IVPToken ( Docs , Source ). function readVotePowerContract ( ) external view returns ( contract IVPContractEvents ); Returns VPContract event interface used for read-only operations (view methods). The only non-view method that might be called on it is revokeDelegationAt . readVotePowerContract is almost always equal to writeVotePowerContract except during an upgrade from one VPContract to a new version (which should happen rarely or never and will be announced beforehand). Do not call any methods on VPContract directly. State changing methods are forbidden from direct calls. All methods are exposed via VPToken . This is the reason that this method returns IVPContractEvents . Use it only for listening to events and revoking. revokeDelegationAt # Defined in IVPToken ( Docs , Source ). function revokeDelegationAt ( address _who , uint256 _blockNumber ) external ; Revoke all delegation from sender to _who at given block. Only affects the reads via votePowerOfAtCached() in the block _blockNumber . Block _blockNumber must be in the past. This method should be used only to prevent rogue delegate voting in the current voting block. To stop delegating use delegate / delegateExplicit with value of 0 or undelegateAll / undelegateAllExplicit . Parameters Type Description _who address Address of the delegatee. _blockNumber uint256 The block number at which to revoke delegation.. setCleanerContract # Defined in IICleanable ( Docs , Source ). function setCleanerContract ( address _cleanerContract ) external ; Set the contract that is allowed to call history cleaning methods. Parameters Type Description _cleanerContract address Address of the cleanup contract. Usually this will be an instance of CleanupBlockNumberManager . setCleanupBlockNumber # Defined in IICleanable ( Docs , Source ). function setCleanupBlockNumber ( uint256 _blockNumber ) external ; Set the cleanup block number. Historic data for the blocks before cleanupBlockNumber can be erased. History before that block should never be used since it can be inconsistent. In particular, cleanup block number must be lower than the current vote power block. Parameters Type Description _blockNumber uint256 The new cleanup block number. setCleanupBlockNumberManager # Defined in IIVPToken ( Docs , Source ). function setCleanupBlockNumberManager ( address _cleanupBlockNumberManager ) external ; Set the contract that is allowed to set cleanupBlockNumber . Usually this will be an instance of CleanupBlockNumberManager . setGovernanceVotePower # Defined in IIVPToken ( Docs , Source ). function setGovernanceVotePower ( contract IIGovernanceVotePower _governanceVotePower ) external ; Sets new governance vote power contract that allows token owners to participate in governance voting and delegate governance vote power. symbol # Defined in IVPToken ( Docs , Source ). function symbol ( ) external view returns ( string ); Returns the symbol of the token, usually a shorter version of the name . Should be compatible with ERC20 method. totalSupply # Defined in IERC20 ( Source ). function totalSupply ( ) external view returns ( uint256 ); Returns the amount of tokens in existence. totalSupplyAt # Defined in IVPToken ( Docs , Source ). function totalSupplyAt ( uint256 _blockNumber ) external view returns ( uint256 ); Total amount of tokens held by all accounts at a specific block number. Parameters Type Description _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The total amount of tokens at _blockNumber . totalVotePower # Defined in IVPToken ( Docs , Source ). function totalVotePower ( ) external view returns ( uint256 ); Get the current total vote power. Returns Type Description [0] uint256 The current total vote power (sum of all accounts' vote power). totalVotePowerAt # Defined in IVPToken ( Docs , Source ). function totalVotePowerAt ( uint256 _blockNumber ) external view returns ( uint256 ); Get the total vote power at block _blockNumber . Parameters Type Description _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The total vote power at the queried block (sum of all accounts' vote powers). totalVotePowerAtCached # Defined in IIVPToken ( Docs , Source ). function totalVotePowerAtCached ( uint256 _blockNumber ) external returns ( uint256 ); Get the total vote power at block _blockNumber using cache. It tries to read the cached value and if it is not found, reads the actual value and stores it in the cache. Can only be used if _blockNumber is in the past, otherwise reverts. Parameters Type Description _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The total vote power at the queried block (sum of all accounts' vote powers). transfer # Defined in IERC20 ( Source ). function transfer ( address recipient , uint256 amount ) external returns ( bool ); Moves amount tokens from the caller's account to recipient . Returns a boolean value indicating whether the operation succeeded. Emits a Transfer event. transferFrom # Defined in IERC20 ( Source ). function transferFrom ( address sender , address recipient , uint256 amount ) external returns ( bool ); Moves amount tokens from sender to recipient using the allowance mechanism. amount is then deducted from the caller's allowance . Returns a boolean value indicating whether the operation succeeded. Emits a Transfer event. undelegateAll # Defined in IVPToken ( Docs , Source ). function undelegateAll ( ) external ; Undelegate all voting power of msg.sender . This effectively revokes all previous delegations. Can only be used with percentage delegation. Does not reset delegation mode back to NOT SET. undelegateAllExplicit # Defined in IVPToken ( Docs , Source ). function undelegateAllExplicit ( address [] _delegateAddresses ) external returns ( uint256 ); Undelegate all explicit vote power by amount of msg.sender . Can only be used with explicit delegation. Does not reset delegation mode back to NOT SET. Parameters Type Description _delegateAddresses address[] Explicit delegation does not store delegatees' addresses, so the caller must supply them. Returns Type Description [0] uint256 The amount still delegated (in case the list of delegates was incomplete). undelegatedVotePowerOf # Defined in IVPToken ( Docs , Source ). function undelegatedVotePowerOf ( address _owner ) external view returns ( uint256 ); Compute the current undelegated vote power of the _owner account. Parameters Type Description _owner address The address to query. Returns Type Description [0] uint256 The unallocated vote power of _owner . undelegatedVotePowerOfAt # Defined in IVPToken ( Docs , Source ). function undelegatedVotePowerOfAt ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Get the undelegated vote power of the _owner account at a given block number. Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The unallocated vote power of _owner . votePowerFromTo # Defined in IVPToken ( Docs , Source ). function votePowerFromTo ( address _from , address _to ) external view returns ( uint256 ); Get current delegated vote power from delegator _from to delegatee _to . Parameters Type Description _from address Address of delegator. _to address Address of delegatee. Returns Type Description [0] uint256 votePower The delegated vote power. votePowerFromToAt # Defined in IVPToken ( Docs , Source ). function votePowerFromToAt ( address _from , address _to , uint256 _blockNumber ) external view returns ( uint256 ); Get delegated vote power from delegator _from to delegatee _to at _blockNumber . Parameters Type Description _from address Address of delegator. _to address Address of delegatee. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The delegated vote power. votePowerOf # Defined in IVPToken ( Docs , Source ). function votePowerOf ( address _owner ) external view returns ( uint256 ); Get the current vote power of _owner . Parameters Type Description _owner address The address to query. Returns Type Description [0] uint256 Current vote power of _owner . votePowerOfAt # Defined in IVPToken ( Docs , Source ). function votePowerOfAt ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Get the vote power of _owner at block _blockNumber Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 Vote power of _owner at block number _blockNumber . votePowerOfAtCached # Defined in IIVPToken ( Docs , Source ). function votePowerOfAtCached ( address _owner , uint256 _blockNumber ) external returns ( uint256 ); Get the vote power of _owner at block _blockNumber using cache. It tries to read the cached value and if it is not found, reads the actual value and stores it in the cache. Can only be used if _blockNumber is in the past, otherwise reverts. Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 Vote power of _owner at _blockNumber . votePowerOfAtIgnoringRevocation # Defined in IVPToken ( Docs , Source ). function votePowerOfAtIgnoringRevocation ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Get the vote power of _owner at block _blockNumber , ignoring revocation information (and cache). Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 Vote power of _owner at block number _blockNumber . Result doesn't change if vote power is revoked. writeVotePowerContract # Defined in IVPToken ( Docs , Source ). function writeVotePowerContract ( ) external view returns ( contract IVPContractEvents ); Returns VPContract event interface used for state-changing operations (non-view methods). The only non-view method that might be called on it is revokeDelegationAt . writeVotePowerContract is almost always equal to readVotePowerContract , except during upgrade from one VPContract to a new version (which should happen rarely or never and will be announced beforehand). In the case of an upgrade, writeVotePowerContract is replaced first to establish delegations. After some period (e.g., after a reward epoch ends), readVotePowerContract is set equal to it. Do not call any methods on VPContract directly. State changing methods are forbidden from direct calls. All are exposed via VPToken . This is the reason that this method returns IVPContractEvents Use it only for listening to events, delegating, and revoking.","title":"IIVPToken"},{"location":"apis/smart-contracts/IIVPToken/#ct_iivptoken","text":"Source | Inherits from IVPToken , IICleanable Vote power token internal interface.","title":"IIVPToken"},{"location":"apis/smart-contracts/IIVPToken/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IIVPToken/#fn_allowance_dd62ed3e","text":"Defined in IERC20 ( Source ). function allowance ( address owner , address spender ) external view returns ( uint256 ); Returns the remaining number of tokens that spender will be allowed to spend on behalf of owner through transferFrom . This is zero by default. This value changes when approve or transferFrom are called.","title":"allowance"},{"location":"apis/smart-contracts/IIVPToken/#fn_approve_095ea7b3","text":"Defined in IERC20 ( Source ). function approve ( address spender , uint256 amount ) external returns ( bool ); Sets amount as the allowance of spender over the caller's tokens. Returns a boolean value indicating whether the operation succeeded. IMPORTANT: Beware that changing an allowance with this method brings the risk that someone may use both the old and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 Emits an Approval event.","title":"approve"},{"location":"apis/smart-contracts/IIVPToken/#fn_balanceof_70a08231","text":"Defined in IERC20 ( Source ). function balanceOf ( address account ) external view returns ( uint256 ); Returns the amount of tokens owned by account .","title":"balanceOf"},{"location":"apis/smart-contracts/IIVPToken/#fn_balanceofat_4ee2cd7e","text":"Defined in IVPToken ( Docs , Source ). function balanceOfAt ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Queries the token balance of _owner at a specific _blockNumber . Parameters Type Description _owner address The address from which the balance will be retrieved. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The balance at _blockNumber .","title":"balanceOfAt"},{"location":"apis/smart-contracts/IIVPToken/#fn_batchdelegate_dc4fcda7","text":"Defined in IVPToken ( Docs , Source ). function batchDelegate ( address [] _delegatees , uint256 [] _bips ) external ; Undelegate all percentage delegations from the sender and then delegate corresponding _bips percentage of voting power from the sender to each member of the _delegatees array. Parameters Type Description _delegatees address[] The addresses of the new recipients. _bips uint256[] The percentages of voting power to be delegated expressed in basis points (1/100 of one percent). The sum of all _bips values must be at most 10000 (100%).","title":"batchDelegate"},{"location":"apis/smart-contracts/IIVPToken/#fn_batchvotepowerofat_49e3c7e5","text":"Defined in IIVPToken ( Docs , Source ). function batchVotePowerOfAt ( address [] _owners , uint256 _blockNumber ) external view returns ( uint256 []); Return the vote power for several addresses. Parameters Type Description _owners address[] The list of addresses to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256[] Array of vote power for each queried address.","title":"batchVotePowerOfAt"},{"location":"apis/smart-contracts/IIVPToken/#fn_cleanupblocknumber_deea13e7","text":"Defined in IICleanable ( Docs , Source ). function cleanupBlockNumber ( ) external view returns ( uint256 ); Get the current cleanup block number set with setCleanupBlockNumber . Returns Type Description [0] uint256 The currently set cleanup block number.","title":"cleanupBlockNumber"},{"location":"apis/smart-contracts/IIVPToken/#fn_decimals_313ce567","text":"Defined in IVPToken ( Docs , Source ). function decimals ( ) external view returns ( uint8 ); Returns the number of decimals used to get its user representation. For example, if decimals equals 2, a balance of 505 tokens should be displayed to a user as 5.05 (505 / 10 2 ). Tokens usually opt for a value of 18, imitating the relationship between Ether and wei. This is the default value returned by this function, unless it's overridden. NOTE: This information is only used for display purposes: it in no way affects any of the arithmetic of the contract, including balanceOf and transfer . Should be compatible with ERC20 method.","title":"decimals"},{"location":"apis/smart-contracts/IIVPToken/#fn_delegate_026e402b","text":"Defined in IVPToken ( Docs , Source ). function delegate ( address _to , uint256 _bips ) external ; Delegate voting power to account _to from msg.sender , by percentage. Parameters Type Description _to address The address of the recipient. _bips uint256 The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: every call resets the delegation value (and a value of 0 revokes all previous delegations).","title":"delegate"},{"location":"apis/smart-contracts/IIVPToken/#fn_delegateexplicit_d06dc3ad","text":"Defined in IVPToken ( Docs , Source ). function delegateExplicit ( address _to , uint256 _amount ) external ; Explicitly delegate _amount voting power to account _to from msg.sender . Compare with delegate which delegates by percentage. Parameters Type Description _to address The address of the recipient. _amount uint256 An explicit vote power amount to be delegated. Not cumulative: every call resets the delegation value (and a value of 0 revokes all previous delegations).","title":"delegateExplicit"},{"location":"apis/smart-contracts/IIVPToken/#fn_delegatesof_7de5b8ed","text":"Defined in IVPToken ( Docs , Source ). function delegatesOf ( address _who ) external view returns ( address [] _delegateAddresses , uint256 [] _bips , uint256 _count , uint256 _delegationMode ); Get the list of addresses to which _who is delegating, and their percentages. Parameters Type Description _who address The address to query. Returns Type Description _delegateAddresses address[] Positional array of addresses being delegated to. _bips uint256[] Positional array of delegation percents specified in basis points (1/100 of 1 percent). Each one matches the address in the same position in the _delegateAddresses array. _count uint256 The number of delegates. _delegationMode uint256 Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).","title":"delegatesOf"},{"location":"apis/smart-contracts/IIVPToken/#fn_delegatesofat_ed475a79","text":"Defined in IVPToken ( Docs , Source ). function delegatesOfAt ( address _who , uint256 _blockNumber ) external view returns ( address [] _delegateAddresses , uint256 [] _bips , uint256 _count , uint256 _delegationMode ); Get the list of addresses to which _who is delegating, and their percentages, at the given block. Parameters Type Description _who address The address to query. _blockNumber uint256 The block number to query. Returns Type Description _delegateAddresses address[] Positional array of addresses being delegated to. _bips uint256[] Positional array of delegation percents specified in basis points (1/100 of 1 percent). Each one matches the address in the same position in the _delegateAddresses array. _count uint256 The number of delegates. _delegationMode uint256 Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).","title":"delegatesOfAt"},{"location":"apis/smart-contracts/IIVPToken/#fn_delegationmodeof_f6837767","text":"Defined in IVPToken ( Docs , Source ). function delegationModeOf ( address _who ) external view returns ( uint256 ); Get the delegation mode for account '_who'. This mode determines whether vote power is allocated by percentage or by explicit amount. Once the delegation mode is set, it can never be changed, even if all delegations are removed. Parameters Type Description _who address The address to get delegation mode. Returns Type Description [0] uint256 Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).","title":"delegationModeOf"},{"location":"apis/smart-contracts/IIVPToken/#fn_governancevotepower_8c2b8ae1","text":"Defined in IVPToken ( Docs , Source ). function governanceVotePower ( ) external view returns ( contract IGovernanceVotePower ); When set, allows token owners to participate in governance voting and delegating governance vote power.","title":"governanceVotePower"},{"location":"apis/smart-contracts/IIVPToken/#fn_name_06fdde03","text":"Defined in IVPToken ( Docs , Source ). function name ( ) external view returns ( string ); Returns the name of the token. Should be compatible with ERC20 method.","title":"name"},{"location":"apis/smart-contracts/IIVPToken/#fn_readvotepowercontract_9b3baa0e","text":"Defined in IVPToken ( Docs , Source ). function readVotePowerContract ( ) external view returns ( contract IVPContractEvents ); Returns VPContract event interface used for read-only operations (view methods). The only non-view method that might be called on it is revokeDelegationAt . readVotePowerContract is almost always equal to writeVotePowerContract except during an upgrade from one VPContract to a new version (which should happen rarely or never and will be announced beforehand). Do not call any methods on VPContract directly. State changing methods are forbidden from direct calls. All methods are exposed via VPToken . This is the reason that this method returns IVPContractEvents . Use it only for listening to events and revoking.","title":"readVotePowerContract"},{"location":"apis/smart-contracts/IIVPToken/#fn_revokedelegationat_bbd6fbf8","text":"Defined in IVPToken ( Docs , Source ). function revokeDelegationAt ( address _who , uint256 _blockNumber ) external ; Revoke all delegation from sender to _who at given block. Only affects the reads via votePowerOfAtCached() in the block _blockNumber . Block _blockNumber must be in the past. This method should be used only to prevent rogue delegate voting in the current voting block. To stop delegating use delegate / delegateExplicit with value of 0 or undelegateAll / undelegateAllExplicit . Parameters Type Description _who address Address of the delegatee. _blockNumber uint256 The block number at which to revoke delegation..","title":"revokeDelegationAt"},{"location":"apis/smart-contracts/IIVPToken/#fn_setcleanercontract_f6a494af","text":"Defined in IICleanable ( Docs , Source ). function setCleanerContract ( address _cleanerContract ) external ; Set the contract that is allowed to call history cleaning methods. Parameters Type Description _cleanerContract address Address of the cleanup contract. Usually this will be an instance of CleanupBlockNumberManager .","title":"setCleanerContract"},{"location":"apis/smart-contracts/IIVPToken/#fn_setcleanupblocknumber_13de97f5","text":"Defined in IICleanable ( Docs , Source ). function setCleanupBlockNumber ( uint256 _blockNumber ) external ; Set the cleanup block number. Historic data for the blocks before cleanupBlockNumber can be erased. History before that block should never be used since it can be inconsistent. In particular, cleanup block number must be lower than the current vote power block. Parameters Type Description _blockNumber uint256 The new cleanup block number.","title":"setCleanupBlockNumber"},{"location":"apis/smart-contracts/IIVPToken/#fn_setcleanupblocknumbermanager_7f4fcaa9","text":"Defined in IIVPToken ( Docs , Source ). function setCleanupBlockNumberManager ( address _cleanupBlockNumberManager ) external ; Set the contract that is allowed to set cleanupBlockNumber . Usually this will be an instance of CleanupBlockNumberManager .","title":"setCleanupBlockNumberManager"},{"location":"apis/smart-contracts/IIVPToken/#fn_setgovernancevotepower_9ca2231a","text":"Defined in IIVPToken ( Docs , Source ). function setGovernanceVotePower ( contract IIGovernanceVotePower _governanceVotePower ) external ; Sets new governance vote power contract that allows token owners to participate in governance voting and delegate governance vote power.","title":"setGovernanceVotePower"},{"location":"apis/smart-contracts/IIVPToken/#fn_symbol_95d89b41","text":"Defined in IVPToken ( Docs , Source ). function symbol ( ) external view returns ( string ); Returns the symbol of the token, usually a shorter version of the name . Should be compatible with ERC20 method.","title":"symbol"},{"location":"apis/smart-contracts/IIVPToken/#fn_totalsupply_18160ddd","text":"Defined in IERC20 ( Source ). function totalSupply ( ) external view returns ( uint256 ); Returns the amount of tokens in existence.","title":"totalSupply"},{"location":"apis/smart-contracts/IIVPToken/#fn_totalsupplyat_981b24d0","text":"Defined in IVPToken ( Docs , Source ). function totalSupplyAt ( uint256 _blockNumber ) external view returns ( uint256 ); Total amount of tokens held by all accounts at a specific block number. Parameters Type Description _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The total amount of tokens at _blockNumber .","title":"totalSupplyAt"},{"location":"apis/smart-contracts/IIVPToken/#fn_totalvotepower_f5f3d4f7","text":"Defined in IVPToken ( Docs , Source ). function totalVotePower ( ) external view returns ( uint256 ); Get the current total vote power. Returns Type Description [0] uint256 The current total vote power (sum of all accounts' vote power).","title":"totalVotePower"},{"location":"apis/smart-contracts/IIVPToken/#fn_totalvotepowerat_3e5aa26a","text":"Defined in IVPToken ( Docs , Source ). function totalVotePowerAt ( uint256 _blockNumber ) external view returns ( uint256 ); Get the total vote power at block _blockNumber . Parameters Type Description _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The total vote power at the queried block (sum of all accounts' vote powers).","title":"totalVotePowerAt"},{"location":"apis/smart-contracts/IIVPToken/#fn_totalvotepoweratcached_caeb942b","text":"Defined in IIVPToken ( Docs , Source ). function totalVotePowerAtCached ( uint256 _blockNumber ) external returns ( uint256 ); Get the total vote power at block _blockNumber using cache. It tries to read the cached value and if it is not found, reads the actual value and stores it in the cache. Can only be used if _blockNumber is in the past, otherwise reverts. Parameters Type Description _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The total vote power at the queried block (sum of all accounts' vote powers).","title":"totalVotePowerAtCached"},{"location":"apis/smart-contracts/IIVPToken/#fn_transfer_a9059cbb","text":"Defined in IERC20 ( Source ). function transfer ( address recipient , uint256 amount ) external returns ( bool ); Moves amount tokens from the caller's account to recipient . Returns a boolean value indicating whether the operation succeeded. Emits a Transfer event.","title":"transfer"},{"location":"apis/smart-contracts/IIVPToken/#fn_transferfrom_23b872dd","text":"Defined in IERC20 ( Source ). function transferFrom ( address sender , address recipient , uint256 amount ) external returns ( bool ); Moves amount tokens from sender to recipient using the allowance mechanism. amount is then deducted from the caller's allowance . Returns a boolean value indicating whether the operation succeeded. Emits a Transfer event.","title":"transferFrom"},{"location":"apis/smart-contracts/IIVPToken/#fn_undelegateall_b302f393","text":"Defined in IVPToken ( Docs , Source ). function undelegateAll ( ) external ; Undelegate all voting power of msg.sender . This effectively revokes all previous delegations. Can only be used with percentage delegation. Does not reset delegation mode back to NOT SET.","title":"undelegateAll"},{"location":"apis/smart-contracts/IIVPToken/#fn_undelegateallexplicit_5d6d11eb","text":"Defined in IVPToken ( Docs , Source ). function undelegateAllExplicit ( address [] _delegateAddresses ) external returns ( uint256 ); Undelegate all explicit vote power by amount of msg.sender . Can only be used with explicit delegation. Does not reset delegation mode back to NOT SET. Parameters Type Description _delegateAddresses address[] Explicit delegation does not store delegatees' addresses, so the caller must supply them. Returns Type Description [0] uint256 The amount still delegated (in case the list of delegates was incomplete).","title":"undelegateAllExplicit"},{"location":"apis/smart-contracts/IIVPToken/#fn_undelegatedvotepowerof_d6aa0b77","text":"Defined in IVPToken ( Docs , Source ). function undelegatedVotePowerOf ( address _owner ) external view returns ( uint256 ); Compute the current undelegated vote power of the _owner account. Parameters Type Description _owner address The address to query. Returns Type Description [0] uint256 The unallocated vote power of _owner .","title":"undelegatedVotePowerOf"},{"location":"apis/smart-contracts/IIVPToken/#fn_undelegatedvotepowerofat_83035a82","text":"Defined in IVPToken ( Docs , Source ). function undelegatedVotePowerOfAt ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Get the undelegated vote power of the _owner account at a given block number. Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The unallocated vote power of _owner .","title":"undelegatedVotePowerOfAt"},{"location":"apis/smart-contracts/IIVPToken/#fn_votepowerfromto_be0ca747","text":"Defined in IVPToken ( Docs , Source ). function votePowerFromTo ( address _from , address _to ) external view returns ( uint256 ); Get current delegated vote power from delegator _from to delegatee _to . Parameters Type Description _from address Address of delegator. _to address Address of delegatee. Returns Type Description [0] uint256 votePower The delegated vote power.","title":"votePowerFromTo"},{"location":"apis/smart-contracts/IIVPToken/#fn_votepowerfromtoat_e64767aa","text":"Defined in IVPToken ( Docs , Source ). function votePowerFromToAt ( address _from , address _to , uint256 _blockNumber ) external view returns ( uint256 ); Get delegated vote power from delegator _from to delegatee _to at _blockNumber . Parameters Type Description _from address Address of delegator. _to address Address of delegatee. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The delegated vote power.","title":"votePowerFromToAt"},{"location":"apis/smart-contracts/IIVPToken/#fn_votepowerof_142d1018","text":"Defined in IVPToken ( Docs , Source ). function votePowerOf ( address _owner ) external view returns ( uint256 ); Get the current vote power of _owner . Parameters Type Description _owner address The address to query. Returns Type Description [0] uint256 Current vote power of _owner .","title":"votePowerOf"},{"location":"apis/smart-contracts/IIVPToken/#fn_votepowerofat_92bfe6d8","text":"Defined in IVPToken ( Docs , Source ). function votePowerOfAt ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Get the vote power of _owner at block _blockNumber Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 Vote power of _owner at block number _blockNumber .","title":"votePowerOfAt"},{"location":"apis/smart-contracts/IIVPToken/#fn_votepowerofatcached_e587497e","text":"Defined in IIVPToken ( Docs , Source ). function votePowerOfAtCached ( address _owner , uint256 _blockNumber ) external returns ( uint256 ); Get the vote power of _owner at block _blockNumber using cache. It tries to read the cached value and if it is not found, reads the actual value and stores it in the cache. Can only be used if _blockNumber is in the past, otherwise reverts. Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 Vote power of _owner at _blockNumber .","title":"votePowerOfAtCached"},{"location":"apis/smart-contracts/IIVPToken/#fn_votepowerofatignoringrevocation_04bb4e43","text":"Defined in IVPToken ( Docs , Source ). function votePowerOfAtIgnoringRevocation ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Get the vote power of _owner at block _blockNumber , ignoring revocation information (and cache). Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 Vote power of _owner at block number _blockNumber . Result doesn't change if vote power is revoked.","title":"votePowerOfAtIgnoringRevocation"},{"location":"apis/smart-contracts/IIVPToken/#fn_writevotepowercontract_1fec092a","text":"Defined in IVPToken ( Docs , Source ). function writeVotePowerContract ( ) external view returns ( contract IVPContractEvents ); Returns VPContract event interface used for state-changing operations (non-view methods). The only non-view method that might be called on it is revokeDelegationAt . writeVotePowerContract is almost always equal to readVotePowerContract , except during upgrade from one VPContract to a new version (which should happen rarely or never and will be announced beforehand). In the case of an upgrade, writeVotePowerContract is replaced first to establish delegations. After some period (e.g., after a reward epoch ends), readVotePowerContract is set equal to it. Do not call any methods on VPContract directly. State changing methods are forbidden from direct calls. All are exposed via VPToken . This is the reason that this method returns IVPContractEvents Use it only for listening to events, delegating, and revoking.","title":"writeVotePowerContract"},{"location":"apis/smart-contracts/IIVoterWhitelister/","text":"IIVoterWhitelister # Source | Inherits from IVoterWhitelister Internal interface for managers of the FTSO whitelist . Only addresses registered in this contract can submit data to the FTSO system. Functions # addFtso # Defined in IIVoterWhitelister ( Docs , Source ). function addFtso ( uint256 _ftsoIndex ) external ; Create an empty whitelist with default size for a new FTSO. Parameters Type Description _ftsoIndex uint256 Index of the new FTSO. chillVoter # Defined in IIVoterWhitelister ( Docs , Source ). function chillVoter ( address _voter , uint256 _noOfRewardEpochs , uint256 [] _ftsoIndices ) external returns ( bool [] _removed , uint256 _untilRewardEpoch ); Used to chill a data provider, this is, remove it from the whitelist for a specified number of reward epochs. Parameters Type Description _voter address Data provider being chilled. _noOfRewardEpochs uint256 Number of epochs to chill the provider for. _ftsoIndices uint256[] Array of indices of the FTSOs that will not allow this provider to submit data. chilledUntilRewardEpoch # Defined in IVoterWhitelister ( Docs , Source ). function chilledUntilRewardEpoch ( address _voter ) external view returns ( uint256 ); In case of providing bad prices (e.g. collusion), the voter can be chilled for a few reward epochs. A voter can whitelist again from a returned reward epoch onwards. Parameters Type Description _voter address Address of the queried data provider. Returns Type Description [0] uint256 uint256 ID of the epoch where the data provider can start submitting prices again. defaultMaxVotersForFtso # Defined in IVoterWhitelister ( Docs , Source ). function defaultMaxVotersForFtso ( ) external view returns ( uint256 ); Maximum number of voters in the whitelist for a new FTSO. Returns Type Description [0] uint256 uint256 Default maximum allowed voters. getFtsoWhitelistedPriceProviders # Defined in IVoterWhitelister ( Docs , Source ). function getFtsoWhitelistedPriceProviders ( uint256 _ftsoIndex ) external view returns ( address []); Gets whitelisted price providers for the FTSO at a given index. Parameters Type Description _ftsoIndex uint256 Queried index. Returns Type Description [0] address[] Array of addresses of the whitelisted data providers. getFtsoWhitelistedPriceProvidersBySymbol # Defined in IVoterWhitelister ( Docs , Source ). function getFtsoWhitelistedPriceProvidersBySymbol ( string _symbol ) external view returns ( address []); Gets whitelisted price providers for the FTSO with a specified symbol. Parameters Type Description _symbol string Queried symbol. Returns Type Description [0] address[] Array of addresses of the whitelisted data providers. maxVotersForFtso # Defined in IVoterWhitelister ( Docs , Source ). function maxVotersForFtso ( uint256 _ftsoIndex ) external view returns ( uint256 ); Maximum number of voters in the whitelist for a specific FTSO. Adjustable separately for each index. Parameters Type Description _ftsoIndex uint256 Index of the FTSO. Returns Type Description [0] uint256 uint256 Maximum allowed voters. removeFtso # Defined in IIVoterWhitelister ( Docs , Source ). function removeFtso ( uint256 _ftsoIndex ) external ; Clear whitelist for a removed FTSO. Parameters Type Description _ftsoIndex uint256 Index of the removed FTSO. removeTrustedAddressFromWhitelist # Defined in IIVoterWhitelister ( Docs , Source ). function removeTrustedAddressFromWhitelist ( address _trustedAddress , uint256 _ftsoIndex ) external ; Remove a trusted address from whitelist. Parameters Type Description _trustedAddress address Address to remove. _ftsoIndex uint256 Index of the FTSO being modified. requestFullVoterWhitelisting # Defined in IVoterWhitelister ( Docs , Source ). function requestFullVoterWhitelisting ( address _voter ) external returns ( uint256 [] _supportedIndices , bool [] _success ); Requests whitelisting an account to act as a data provider for all active FTSOs. May be called by any address, including the voter itself. Parameters Type Description _voter address Address of the voter to be whitelisted. Returns Type Description _supportedIndices uint256[] Array of currently supported FTSO indices. _success bool[] Array of success flags by FTSO index. requestWhitelistingVoter # Defined in IVoterWhitelister ( Docs , Source ). function requestWhitelistingVoter ( address _voter , uint256 _ftsoIndex ) external ; Requests whitelisting an account to act as a data provider for a specific FTSO. Reverts if the vote power of the account is too low. May be called by any address, including the voter itself. Parameters Type Description _voter address Address of the voter to be whitelisted. _ftsoIndex uint256 Index of the FTSO. setDefaultMaxVotersForFtso # Defined in IIVoterWhitelister ( Docs , Source ). function setDefaultMaxVotersForFtso ( uint256 _defaultMaxVotersForFtso ) external ; Set the maximum number of voters in the whitelist for a new FTSOs. Parameters Type Description _defaultMaxVotersForFtso uint256 New maximum default value. setMaxVotersForFtso # Defined in IIVoterWhitelister ( Docs , Source ). function setMaxVotersForFtso ( uint256 _ftsoIndex , uint256 _newMaxVoters ) external ; Set the maximum number of voters in the whitelist for a specific FTSO. Can remove voters with the least votepower from the whitelist. Parameters Type Description _ftsoIndex uint256 Index of the FTSO to modify. _newMaxVoters uint256 New size of the whitelist.","title":"IIVoterWhitelister"},{"location":"apis/smart-contracts/IIVoterWhitelister/#ct_iivoterwhitelister","text":"Source | Inherits from IVoterWhitelister Internal interface for managers of the FTSO whitelist . Only addresses registered in this contract can submit data to the FTSO system.","title":"IIVoterWhitelister"},{"location":"apis/smart-contracts/IIVoterWhitelister/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IIVoterWhitelister/#fn_addftso_345705a4","text":"Defined in IIVoterWhitelister ( Docs , Source ). function addFtso ( uint256 _ftsoIndex ) external ; Create an empty whitelist with default size for a new FTSO. Parameters Type Description _ftsoIndex uint256 Index of the new FTSO.","title":"addFtso"},{"location":"apis/smart-contracts/IIVoterWhitelister/#fn_chillvoter_2b4faebb","text":"Defined in IIVoterWhitelister ( Docs , Source ). function chillVoter ( address _voter , uint256 _noOfRewardEpochs , uint256 [] _ftsoIndices ) external returns ( bool [] _removed , uint256 _untilRewardEpoch ); Used to chill a data provider, this is, remove it from the whitelist for a specified number of reward epochs. Parameters Type Description _voter address Data provider being chilled. _noOfRewardEpochs uint256 Number of epochs to chill the provider for. _ftsoIndices uint256[] Array of indices of the FTSOs that will not allow this provider to submit data.","title":"chillVoter"},{"location":"apis/smart-contracts/IIVoterWhitelister/#fn_chilleduntilrewardepoch_46538074","text":"Defined in IVoterWhitelister ( Docs , Source ). function chilledUntilRewardEpoch ( address _voter ) external view returns ( uint256 ); In case of providing bad prices (e.g. collusion), the voter can be chilled for a few reward epochs. A voter can whitelist again from a returned reward epoch onwards. Parameters Type Description _voter address Address of the queried data provider. Returns Type Description [0] uint256 uint256 ID of the epoch where the data provider can start submitting prices again.","title":"chilledUntilRewardEpoch"},{"location":"apis/smart-contracts/IIVoterWhitelister/#fn_defaultmaxvotersforftso_47ed51b1","text":"Defined in IVoterWhitelister ( Docs , Source ). function defaultMaxVotersForFtso ( ) external view returns ( uint256 ); Maximum number of voters in the whitelist for a new FTSO. Returns Type Description [0] uint256 uint256 Default maximum allowed voters.","title":"defaultMaxVotersForFtso"},{"location":"apis/smart-contracts/IIVoterWhitelister/#fn_getftsowhitelistedpriceproviders_09fcb400","text":"Defined in IVoterWhitelister ( Docs , Source ). function getFtsoWhitelistedPriceProviders ( uint256 _ftsoIndex ) external view returns ( address []); Gets whitelisted price providers for the FTSO at a given index. Parameters Type Description _ftsoIndex uint256 Queried index. Returns Type Description [0] address[] Array of addresses of the whitelisted data providers.","title":"getFtsoWhitelistedPriceProviders"},{"location":"apis/smart-contracts/IIVoterWhitelister/#fn_getftsowhitelistedpriceprovidersbysymbol_aa89dfd4","text":"Defined in IVoterWhitelister ( Docs , Source ). function getFtsoWhitelistedPriceProvidersBySymbol ( string _symbol ) external view returns ( address []); Gets whitelisted price providers for the FTSO with a specified symbol. Parameters Type Description _symbol string Queried symbol. Returns Type Description [0] address[] Array of addresses of the whitelisted data providers.","title":"getFtsoWhitelistedPriceProvidersBySymbol"},{"location":"apis/smart-contracts/IIVoterWhitelister/#fn_maxvotersforftso_98dccfc2","text":"Defined in IVoterWhitelister ( Docs , Source ). function maxVotersForFtso ( uint256 _ftsoIndex ) external view returns ( uint256 ); Maximum number of voters in the whitelist for a specific FTSO. Adjustable separately for each index. Parameters Type Description _ftsoIndex uint256 Index of the FTSO. Returns Type Description [0] uint256 uint256 Maximum allowed voters.","title":"maxVotersForFtso"},{"location":"apis/smart-contracts/IIVoterWhitelister/#fn_removeftso_d8736171","text":"Defined in IIVoterWhitelister ( Docs , Source ). function removeFtso ( uint256 _ftsoIndex ) external ; Clear whitelist for a removed FTSO. Parameters Type Description _ftsoIndex uint256 Index of the removed FTSO.","title":"removeFtso"},{"location":"apis/smart-contracts/IIVoterWhitelister/#fn_removetrustedaddressfromwhitelist_9dc950ab","text":"Defined in IIVoterWhitelister ( Docs , Source ). function removeTrustedAddressFromWhitelist ( address _trustedAddress , uint256 _ftsoIndex ) external ; Remove a trusted address from whitelist. Parameters Type Description _trustedAddress address Address to remove. _ftsoIndex uint256 Index of the FTSO being modified.","title":"removeTrustedAddressFromWhitelist"},{"location":"apis/smart-contracts/IIVoterWhitelister/#fn_requestfullvoterwhitelisting_b06cbaf7","text":"Defined in IVoterWhitelister ( Docs , Source ). function requestFullVoterWhitelisting ( address _voter ) external returns ( uint256 [] _supportedIndices , bool [] _success ); Requests whitelisting an account to act as a data provider for all active FTSOs. May be called by any address, including the voter itself. Parameters Type Description _voter address Address of the voter to be whitelisted. Returns Type Description _supportedIndices uint256[] Array of currently supported FTSO indices. _success bool[] Array of success flags by FTSO index.","title":"requestFullVoterWhitelisting"},{"location":"apis/smart-contracts/IIVoterWhitelister/#fn_requestwhitelistingvoter_3de2cb1c","text":"Defined in IVoterWhitelister ( Docs , Source ). function requestWhitelistingVoter ( address _voter , uint256 _ftsoIndex ) external ; Requests whitelisting an account to act as a data provider for a specific FTSO. Reverts if the vote power of the account is too low. May be called by any address, including the voter itself. Parameters Type Description _voter address Address of the voter to be whitelisted. _ftsoIndex uint256 Index of the FTSO.","title":"requestWhitelistingVoter"},{"location":"apis/smart-contracts/IIVoterWhitelister/#fn_setdefaultmaxvotersforftso_2ee96140","text":"Defined in IIVoterWhitelister ( Docs , Source ). function setDefaultMaxVotersForFtso ( uint256 _defaultMaxVotersForFtso ) external ; Set the maximum number of voters in the whitelist for a new FTSOs. Parameters Type Description _defaultMaxVotersForFtso uint256 New maximum default value.","title":"setDefaultMaxVotersForFtso"},{"location":"apis/smart-contracts/IIVoterWhitelister/#fn_setmaxvotersforftso_7ecfcfa3","text":"Defined in IIVoterWhitelister ( Docs , Source ). function setMaxVotersForFtso ( uint256 _ftsoIndex , uint256 _newMaxVoters ) external ; Set the maximum number of voters in the whitelist for a specific FTSO. Can remove voters with the least votepower from the whitelist. Parameters Type Description _ftsoIndex uint256 Index of the FTSO to modify. _newMaxVoters uint256 New size of the whitelist.","title":"setMaxVotersForFtso"},{"location":"apis/smart-contracts/IInflationGenesis/","text":"IInflationGenesis # Source Portion of the Inflation contract that is available to contracts deployed at genesis. Functions # receiveMinting # Defined in IInflationGenesis ( Docs , Source ). function receiveMinting ( ) external payable ; Receive newly minted native tokens from the FlareDaemon . Assume that the received amount will be >= last topup requested across all services. If there is not enough balance sent to cover the topup request, expect the library method to revert. Also assume that any received balance greater than the calculated topup request came from self-destructor sending a balance to this contract.","title":"IInflationGenesis"},{"location":"apis/smart-contracts/IInflationGenesis/#ct_iinflationgenesis","text":"Source Portion of the Inflation contract that is available to contracts deployed at genesis.","title":"IInflationGenesis"},{"location":"apis/smart-contracts/IInflationGenesis/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IInflationGenesis/#fn_receiveminting_c611c2c5","text":"Defined in IInflationGenesis ( Docs , Source ). function receiveMinting ( ) external payable ; Receive newly minted native tokens from the FlareDaemon . Assume that the received amount will be >= last topup requested across all services. If there is not enough balance sent to cover the topup request, expect the library method to revert. Also assume that any received balance greater than the calculated topup request came from self-destructor sending a balance to this contract.","title":"receiveMinting"},{"location":"apis/smart-contracts/IPriceSubmitter/","text":"IPriceSubmitter # Source Interface for the PriceSubmitter contract. This is the contract used by all FTSO data providers to submit their data. Events # HashSubmitted # Defined in IPriceSubmitter ( Docs , Source ). event HashSubmitted ( address submitter , uint256 epochId , bytes32 hash , uint256 timestamp ) Emitted when a hash is submitted through submitHash . Parameters Type Description submitter address Address of the submitting data provider. epochId uint256 Current price epoch ID. hash bytes32 Submitted hash. timestamp uint256 Current block timestamp. PricesRevealed # Defined in IPriceSubmitter ( Docs , Source ). event PricesRevealed ( address voter , uint256 epochId , contract IFtsoGenesis [] ftsos , uint256 [] prices , uint256 random , uint256 timestamp ) Emitted when prices are revealed through revealPrice . Parameters Type Description voter address Address of the revealing data provider. epochId uint256 ID of the epoch in which the price hash is revealed. ftsos contract IFtsoGenesis[] Array of FTSOs that correspond to the indexes in the call. prices uint256[] List of revealed prices. random uint256 Revealed random number. timestamp uint256 Current block timestamp. Functions # getCurrentRandom # Defined in IPriceSubmitter ( Docs , Source ). function getCurrentRandom ( ) external view returns ( uint256 ); Returns the random number for the previous epoch, obtained from the random numbers provided by all data providers along with their data submissions. Note that the random number for the previous epoch keeps updating as new submissions are revealed. Returns Type Description [0] uint256 Random number calculated from all data provider's submissions. getFtsoManager # Defined in IPriceSubmitter ( Docs , Source ). function getFtsoManager ( ) external view returns ( contract IFtsoManagerGenesis ); Returns the address of the FtsoManager contract. getFtsoRegistry # Defined in IPriceSubmitter ( Docs , Source ). function getFtsoRegistry ( ) external view returns ( contract IFtsoRegistryGenesis ); Returns the address of the FtsoRegistry contract. getRandom # Defined in IPriceSubmitter ( Docs , Source ). function getRandom ( uint256 _epochId ) external view returns ( uint256 ); Returns the random number used in a specific past epoch, obtained from the random numbers provided by all data providers along with their data submissions. Parameters Type Description _epochId uint256 ID of the queried epoch. Current epoch cannot be queried, and the previous epoch is constantly updated as data providers reveal their prices and random numbers. Note that only the last 50 epochs can be queried and there is no bounds checking for this parameter. Out-of-bounds queries return undefined values. Returns Type Description [0] uint256 The random number used in that epoch. getVoterWhitelister # Defined in IPriceSubmitter ( Docs , Source ). function getVoterWhitelister ( ) external view returns ( address ); Returns the address of the VoterWhitelister contract managing the data provider whitelist. revealPrices # Defined in IPriceSubmitter ( Docs , Source ). function revealPrices ( uint256 _epochId , uint256 [] _ftsoIndices , uint256 [] _prices , uint256 _random ) external ; Reveals submitted prices during the epoch reveal period. The hash of FTSO indices, prices, random number, and voter address must be equal to the hash previously submitted with submitHash . Emits a PricesRevealed event. Parameters Type Description _epochId uint256 ID of the epoch to which the price hashes are submitted. _ftsoIndices uint256[] List of FTSO indices in ascending order. _prices uint256[] List of submitted prices in USD. _random uint256 Submitted random number. submitHash # Defined in IPriceSubmitter ( Docs , Source ). function submitHash ( uint256 _epochId , bytes32 _hash ) external ; Submits a hash for the current epoch. Can only be called by FTSO data providers whitelisted through the VoterWhitelisted contract. Emits the HashSubmitted event. Parameters Type Description _epochId uint256 ID of the target epoch to which the hash is submitted. _hash bytes32 A hash of the FTSO indices, prices, random number, and voter address. voterWhitelistBitmap # Defined in IPriceSubmitter ( Docs , Source ). function voterWhitelistBitmap ( address _voter ) external view returns ( uint256 ); Returns a bitmap of all FTSOs for which a data provider is allowed to submit prices or hashes. Parameters Type Description _voter address Address of the voter. Returns Type Description [0] uint256 If a data provider is allowed to vote for a given FTSO index, the corresponding bit in the result is 1.","title":"IPriceSubmitter"},{"location":"apis/smart-contracts/IPriceSubmitter/#ct_ipricesubmitter","text":"Source Interface for the PriceSubmitter contract. This is the contract used by all FTSO data providers to submit their data.","title":"IPriceSubmitter"},{"location":"apis/smart-contracts/IPriceSubmitter/#events","text":"","title":"Events"},{"location":"apis/smart-contracts/IPriceSubmitter/#ev_hashsubmitted","text":"Defined in IPriceSubmitter ( Docs , Source ). event HashSubmitted ( address submitter , uint256 epochId , bytes32 hash , uint256 timestamp ) Emitted when a hash is submitted through submitHash . Parameters Type Description submitter address Address of the submitting data provider. epochId uint256 Current price epoch ID. hash bytes32 Submitted hash. timestamp uint256 Current block timestamp.","title":"HashSubmitted"},{"location":"apis/smart-contracts/IPriceSubmitter/#ev_pricesrevealed","text":"Defined in IPriceSubmitter ( Docs , Source ). event PricesRevealed ( address voter , uint256 epochId , contract IFtsoGenesis [] ftsos , uint256 [] prices , uint256 random , uint256 timestamp ) Emitted when prices are revealed through revealPrice . Parameters Type Description voter address Address of the revealing data provider. epochId uint256 ID of the epoch in which the price hash is revealed. ftsos contract IFtsoGenesis[] Array of FTSOs that correspond to the indexes in the call. prices uint256[] List of revealed prices. random uint256 Revealed random number. timestamp uint256 Current block timestamp.","title":"PricesRevealed"},{"location":"apis/smart-contracts/IPriceSubmitter/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IPriceSubmitter/#fn_getcurrentrandom_d89601fd","text":"Defined in IPriceSubmitter ( Docs , Source ). function getCurrentRandom ( ) external view returns ( uint256 ); Returns the random number for the previous epoch, obtained from the random numbers provided by all data providers along with their data submissions. Note that the random number for the previous epoch keeps updating as new submissions are revealed. Returns Type Description [0] uint256 Random number calculated from all data provider's submissions.","title":"getCurrentRandom"},{"location":"apis/smart-contracts/IPriceSubmitter/#fn_getftsomanager_b39c6858","text":"Defined in IPriceSubmitter ( Docs , Source ). function getFtsoManager ( ) external view returns ( contract IFtsoManagerGenesis ); Returns the address of the FtsoManager contract.","title":"getFtsoManager"},{"location":"apis/smart-contracts/IPriceSubmitter/#fn_getftsoregistry_8c9d28b6","text":"Defined in IPriceSubmitter ( Docs , Source ). function getFtsoRegistry ( ) external view returns ( contract IFtsoRegistryGenesis ); Returns the address of the FtsoRegistry contract.","title":"getFtsoRegistry"},{"location":"apis/smart-contracts/IPriceSubmitter/#fn_getrandom_cd4b6914","text":"Defined in IPriceSubmitter ( Docs , Source ). function getRandom ( uint256 _epochId ) external view returns ( uint256 ); Returns the random number used in a specific past epoch, obtained from the random numbers provided by all data providers along with their data submissions. Parameters Type Description _epochId uint256 ID of the queried epoch. Current epoch cannot be queried, and the previous epoch is constantly updated as data providers reveal their prices and random numbers. Note that only the last 50 epochs can be queried and there is no bounds checking for this parameter. Out-of-bounds queries return undefined values. Returns Type Description [0] uint256 The random number used in that epoch.","title":"getRandom"},{"location":"apis/smart-contracts/IPriceSubmitter/#fn_getvoterwhitelister_71e1fad9","text":"Defined in IPriceSubmitter ( Docs , Source ). function getVoterWhitelister ( ) external view returns ( address ); Returns the address of the VoterWhitelister contract managing the data provider whitelist.","title":"getVoterWhitelister"},{"location":"apis/smart-contracts/IPriceSubmitter/#fn_revealprices_e2db5a52","text":"Defined in IPriceSubmitter ( Docs , Source ). function revealPrices ( uint256 _epochId , uint256 [] _ftsoIndices , uint256 [] _prices , uint256 _random ) external ; Reveals submitted prices during the epoch reveal period. The hash of FTSO indices, prices, random number, and voter address must be equal to the hash previously submitted with submitHash . Emits a PricesRevealed event. Parameters Type Description _epochId uint256 ID of the epoch to which the price hashes are submitted. _ftsoIndices uint256[] List of FTSO indices in ascending order. _prices uint256[] List of submitted prices in USD. _random uint256 Submitted random number.","title":"revealPrices"},{"location":"apis/smart-contracts/IPriceSubmitter/#fn_submithash_8fc6f667","text":"Defined in IPriceSubmitter ( Docs , Source ). function submitHash ( uint256 _epochId , bytes32 _hash ) external ; Submits a hash for the current epoch. Can only be called by FTSO data providers whitelisted through the VoterWhitelisted contract. Emits the HashSubmitted event. Parameters Type Description _epochId uint256 ID of the target epoch to which the hash is submitted. _hash bytes32 A hash of the FTSO indices, prices, random number, and voter address.","title":"submitHash"},{"location":"apis/smart-contracts/IPriceSubmitter/#fn_voterwhitelistbitmap_7ac420ad","text":"Defined in IPriceSubmitter ( Docs , Source ). function voterWhitelistBitmap ( address _voter ) external view returns ( uint256 ); Returns a bitmap of all FTSOs for which a data provider is allowed to submit prices or hashes. Parameters Type Description _voter address Address of the voter. Returns Type Description [0] uint256 If a data provider is allowed to vote for a given FTSO index, the corresponding bit in the result is 1.","title":"voterWhitelistBitmap"},{"location":"apis/smart-contracts/IVPContractEvents/","text":"IVPContractEvents # Source Events interface for vote-power related operations. Events # Delegate # Defined in IVPContractEvents ( Docs , Source ). event Delegate ( address from , address to , uint256 priorVotePower , uint256 newVotePower ) Emitted when the amount of vote power delegated from one account to another changes. Note : This event is always emitted from VPToken 's writeVotePowerContract . Parameters Type Description from address The account that has changed the amount of vote power it is delegating. to address The account whose received vote power has changed. priorVotePower uint256 The vote power originally delegated. newVotePower uint256 The new vote power that triggered this event. It can be 0 if the delegation is completely canceled. Revoke # Defined in IVPContractEvents ( Docs , Source ). event Revoke ( address delegator , address delegatee , uint256 votePower , uint256 blockNumber ) Emitted when an account revokes its vote power delegation to another account for a single current or past block (typically the current vote block). Note : This event is always emitted from VPToken 's writeVotePowerContract or readVotePowerContract . See revokeDelegationAt in IVPToken . Parameters Type Description delegator address The account that revoked the delegation. delegatee address The account that has been revoked. votePower uint256 The revoked vote power. blockNumber uint256 The block number at which the delegation has been revoked.","title":"IVPContractEvents"},{"location":"apis/smart-contracts/IVPContractEvents/#ct_ivpcontractevents","text":"Source Events interface for vote-power related operations.","title":"IVPContractEvents"},{"location":"apis/smart-contracts/IVPContractEvents/#events","text":"","title":"Events"},{"location":"apis/smart-contracts/IVPContractEvents/#ev_delegate","text":"Defined in IVPContractEvents ( Docs , Source ). event Delegate ( address from , address to , uint256 priorVotePower , uint256 newVotePower ) Emitted when the amount of vote power delegated from one account to another changes. Note : This event is always emitted from VPToken 's writeVotePowerContract . Parameters Type Description from address The account that has changed the amount of vote power it is delegating. to address The account whose received vote power has changed. priorVotePower uint256 The vote power originally delegated. newVotePower uint256 The new vote power that triggered this event. It can be 0 if the delegation is completely canceled.","title":"Delegate"},{"location":"apis/smart-contracts/IVPContractEvents/#ev_revoke","text":"Defined in IVPContractEvents ( Docs , Source ). event Revoke ( address delegator , address delegatee , uint256 votePower , uint256 blockNumber ) Emitted when an account revokes its vote power delegation to another account for a single current or past block (typically the current vote block). Note : This event is always emitted from VPToken 's writeVotePowerContract or readVotePowerContract . See revokeDelegationAt in IVPToken . Parameters Type Description delegator address The account that revoked the delegation. delegatee address The account that has been revoked. votePower uint256 The revoked vote power. blockNumber uint256 The block number at which the delegation has been revoked.","title":"Revoke"},{"location":"apis/smart-contracts/IVPToken/","text":"IVPToken # Source | Inherits from IERC20 Vote power token interface. Functions # allowance # Defined in IERC20 ( Source ). function allowance ( address owner , address spender ) external view returns ( uint256 ); Returns the remaining number of tokens that spender will be allowed to spend on behalf of owner through transferFrom . This is zero by default. This value changes when approve or transferFrom are called. approve # Defined in IERC20 ( Source ). function approve ( address spender , uint256 amount ) external returns ( bool ); Sets amount as the allowance of spender over the caller's tokens. Returns a boolean value indicating whether the operation succeeded. IMPORTANT: Beware that changing an allowance with this method brings the risk that someone may use both the old and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 Emits an Approval event. balanceOf # Defined in IERC20 ( Source ). function balanceOf ( address account ) external view returns ( uint256 ); Returns the amount of tokens owned by account . balanceOfAt # Defined in IVPToken ( Docs , Source ). function balanceOfAt ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Queries the token balance of _owner at a specific _blockNumber . Parameters Type Description _owner address The address from which the balance will be retrieved. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The balance at _blockNumber . batchDelegate # Defined in IVPToken ( Docs , Source ). function batchDelegate ( address [] _delegatees , uint256 [] _bips ) external ; Undelegate all percentage delegations from the sender and then delegate corresponding _bips percentage of voting power from the sender to each member of the _delegatees array. Parameters Type Description _delegatees address[] The addresses of the new recipients. _bips uint256[] The percentages of voting power to be delegated expressed in basis points (1/100 of one percent). The sum of all _bips values must be at most 10000 (100%). decimals # Defined in IVPToken ( Docs , Source ). function decimals ( ) external view returns ( uint8 ); Returns the number of decimals used to get its user representation. For example, if decimals equals 2, a balance of 505 tokens should be displayed to a user as 5.05 (505 / 10 2 ). Tokens usually opt for a value of 18, imitating the relationship between Ether and wei. This is the default value returned by this function, unless it's overridden. NOTE: This information is only used for display purposes: it in no way affects any of the arithmetic of the contract, including balanceOf and transfer . Should be compatible with ERC20 method. delegate # Defined in IVPToken ( Docs , Source ). function delegate ( address _to , uint256 _bips ) external ; Delegate voting power to account _to from msg.sender , by percentage. Parameters Type Description _to address The address of the recipient. _bips uint256 The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: every call resets the delegation value (and a value of 0 revokes all previous delegations). delegateExplicit # Defined in IVPToken ( Docs , Source ). function delegateExplicit ( address _to , uint256 _amount ) external ; Explicitly delegate _amount voting power to account _to from msg.sender . Compare with delegate which delegates by percentage. Parameters Type Description _to address The address of the recipient. _amount uint256 An explicit vote power amount to be delegated. Not cumulative: every call resets the delegation value (and a value of 0 revokes all previous delegations). delegatesOf # Defined in IVPToken ( Docs , Source ). function delegatesOf ( address _who ) external view returns ( address [] _delegateAddresses , uint256 [] _bips , uint256 _count , uint256 _delegationMode ); Get the list of addresses to which _who is delegating, and their percentages. Parameters Type Description _who address The address to query. Returns Type Description _delegateAddresses address[] Positional array of addresses being delegated to. _bips uint256[] Positional array of delegation percents specified in basis points (1/100 of 1 percent). Each one matches the address in the same position in the _delegateAddresses array. _count uint256 The number of delegates. _delegationMode uint256 Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit). delegatesOfAt # Defined in IVPToken ( Docs , Source ). function delegatesOfAt ( address _who , uint256 _blockNumber ) external view returns ( address [] _delegateAddresses , uint256 [] _bips , uint256 _count , uint256 _delegationMode ); Get the list of addresses to which _who is delegating, and their percentages, at the given block. Parameters Type Description _who address The address to query. _blockNumber uint256 The block number to query. Returns Type Description _delegateAddresses address[] Positional array of addresses being delegated to. _bips uint256[] Positional array of delegation percents specified in basis points (1/100 of 1 percent). Each one matches the address in the same position in the _delegateAddresses array. _count uint256 The number of delegates. _delegationMode uint256 Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit). delegationModeOf # Defined in IVPToken ( Docs , Source ). function delegationModeOf ( address _who ) external view returns ( uint256 ); Get the delegation mode for account '_who'. This mode determines whether vote power is allocated by percentage or by explicit amount. Once the delegation mode is set, it can never be changed, even if all delegations are removed. Parameters Type Description _who address The address to get delegation mode. Returns Type Description [0] uint256 Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit). governanceVotePower # Defined in IVPToken ( Docs , Source ). function governanceVotePower ( ) external view returns ( contract IGovernanceVotePower ); When set, allows token owners to participate in governance voting and delegating governance vote power. name # Defined in IVPToken ( Docs , Source ). function name ( ) external view returns ( string ); Returns the name of the token. Should be compatible with ERC20 method. readVotePowerContract # Defined in IVPToken ( Docs , Source ). function readVotePowerContract ( ) external view returns ( contract IVPContractEvents ); Returns VPContract event interface used for read-only operations (view methods). The only non-view method that might be called on it is revokeDelegationAt . readVotePowerContract is almost always equal to writeVotePowerContract except during an upgrade from one VPContract to a new version (which should happen rarely or never and will be announced beforehand). Do not call any methods on VPContract directly. State changing methods are forbidden from direct calls. All methods are exposed via VPToken . This is the reason that this method returns IVPContractEvents . Use it only for listening to events and revoking. revokeDelegationAt # Defined in IVPToken ( Docs , Source ). function revokeDelegationAt ( address _who , uint256 _blockNumber ) external ; Revoke all delegation from sender to _who at given block. Only affects the reads via votePowerOfAtCached() in the block _blockNumber . Block _blockNumber must be in the past. This method should be used only to prevent rogue delegate voting in the current voting block. To stop delegating use delegate / delegateExplicit with value of 0 or undelegateAll / undelegateAllExplicit . Parameters Type Description _who address Address of the delegatee. _blockNumber uint256 The block number at which to revoke delegation.. symbol # Defined in IVPToken ( Docs , Source ). function symbol ( ) external view returns ( string ); Returns the symbol of the token, usually a shorter version of the name . Should be compatible with ERC20 method. totalSupply # Defined in IERC20 ( Source ). function totalSupply ( ) external view returns ( uint256 ); Returns the amount of tokens in existence. totalSupplyAt # Defined in IVPToken ( Docs , Source ). function totalSupplyAt ( uint256 _blockNumber ) external view returns ( uint256 ); Total amount of tokens held by all accounts at a specific block number. Parameters Type Description _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The total amount of tokens at _blockNumber . totalVotePower # Defined in IVPToken ( Docs , Source ). function totalVotePower ( ) external view returns ( uint256 ); Get the current total vote power. Returns Type Description [0] uint256 The current total vote power (sum of all accounts' vote power). totalVotePowerAt # Defined in IVPToken ( Docs , Source ). function totalVotePowerAt ( uint256 _blockNumber ) external view returns ( uint256 ); Get the total vote power at block _blockNumber . Parameters Type Description _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The total vote power at the queried block (sum of all accounts' vote powers). transfer # Defined in IERC20 ( Source ). function transfer ( address recipient , uint256 amount ) external returns ( bool ); Moves amount tokens from the caller's account to recipient . Returns a boolean value indicating whether the operation succeeded. Emits a Transfer event. transferFrom # Defined in IERC20 ( Source ). function transferFrom ( address sender , address recipient , uint256 amount ) external returns ( bool ); Moves amount tokens from sender to recipient using the allowance mechanism. amount is then deducted from the caller's allowance . Returns a boolean value indicating whether the operation succeeded. Emits a Transfer event. undelegateAll # Defined in IVPToken ( Docs , Source ). function undelegateAll ( ) external ; Undelegate all voting power of msg.sender . This effectively revokes all previous delegations. Can only be used with percentage delegation. Does not reset delegation mode back to NOT SET. undelegateAllExplicit # Defined in IVPToken ( Docs , Source ). function undelegateAllExplicit ( address [] _delegateAddresses ) external returns ( uint256 ); Undelegate all explicit vote power by amount of msg.sender . Can only be used with explicit delegation. Does not reset delegation mode back to NOT SET. Parameters Type Description _delegateAddresses address[] Explicit delegation does not store delegatees' addresses, so the caller must supply them. Returns Type Description [0] uint256 The amount still delegated (in case the list of delegates was incomplete). undelegatedVotePowerOf # Defined in IVPToken ( Docs , Source ). function undelegatedVotePowerOf ( address _owner ) external view returns ( uint256 ); Compute the current undelegated vote power of the _owner account. Parameters Type Description _owner address The address to query. Returns Type Description [0] uint256 The unallocated vote power of _owner . undelegatedVotePowerOfAt # Defined in IVPToken ( Docs , Source ). function undelegatedVotePowerOfAt ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Get the undelegated vote power of the _owner account at a given block number. Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The unallocated vote power of _owner . votePowerFromTo # Defined in IVPToken ( Docs , Source ). function votePowerFromTo ( address _from , address _to ) external view returns ( uint256 ); Get current delegated vote power from delegator _from to delegatee _to . Parameters Type Description _from address Address of delegator. _to address Address of delegatee. Returns Type Description [0] uint256 votePower The delegated vote power. votePowerFromToAt # Defined in IVPToken ( Docs , Source ). function votePowerFromToAt ( address _from , address _to , uint256 _blockNumber ) external view returns ( uint256 ); Get delegated vote power from delegator _from to delegatee _to at _blockNumber . Parameters Type Description _from address Address of delegator. _to address Address of delegatee. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The delegated vote power. votePowerOf # Defined in IVPToken ( Docs , Source ). function votePowerOf ( address _owner ) external view returns ( uint256 ); Get the current vote power of _owner . Parameters Type Description _owner address The address to query. Returns Type Description [0] uint256 Current vote power of _owner . votePowerOfAt # Defined in IVPToken ( Docs , Source ). function votePowerOfAt ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Get the vote power of _owner at block _blockNumber Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 Vote power of _owner at block number _blockNumber . votePowerOfAtIgnoringRevocation # Defined in IVPToken ( Docs , Source ). function votePowerOfAtIgnoringRevocation ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Get the vote power of _owner at block _blockNumber , ignoring revocation information (and cache). Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 Vote power of _owner at block number _blockNumber . Result doesn't change if vote power is revoked. writeVotePowerContract # Defined in IVPToken ( Docs , Source ). function writeVotePowerContract ( ) external view returns ( contract IVPContractEvents ); Returns VPContract event interface used for state-changing operations (non-view methods). The only non-view method that might be called on it is revokeDelegationAt . writeVotePowerContract is almost always equal to readVotePowerContract , except during upgrade from one VPContract to a new version (which should happen rarely or never and will be announced beforehand). In the case of an upgrade, writeVotePowerContract is replaced first to establish delegations. After some period (e.g., after a reward epoch ends), readVotePowerContract is set equal to it. Do not call any methods on VPContract directly. State changing methods are forbidden from direct calls. All are exposed via VPToken . This is the reason that this method returns IVPContractEvents Use it only for listening to events, delegating, and revoking.","title":"IVPToken"},{"location":"apis/smart-contracts/IVPToken/#ct_ivptoken","text":"Source | Inherits from IERC20 Vote power token interface.","title":"IVPToken"},{"location":"apis/smart-contracts/IVPToken/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IVPToken/#fn_allowance_dd62ed3e","text":"Defined in IERC20 ( Source ). function allowance ( address owner , address spender ) external view returns ( uint256 ); Returns the remaining number of tokens that spender will be allowed to spend on behalf of owner through transferFrom . This is zero by default. This value changes when approve or transferFrom are called.","title":"allowance"},{"location":"apis/smart-contracts/IVPToken/#fn_approve_095ea7b3","text":"Defined in IERC20 ( Source ). function approve ( address spender , uint256 amount ) external returns ( bool ); Sets amount as the allowance of spender over the caller's tokens. Returns a boolean value indicating whether the operation succeeded. IMPORTANT: Beware that changing an allowance with this method brings the risk that someone may use both the old and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 Emits an Approval event.","title":"approve"},{"location":"apis/smart-contracts/IVPToken/#fn_balanceof_70a08231","text":"Defined in IERC20 ( Source ). function balanceOf ( address account ) external view returns ( uint256 ); Returns the amount of tokens owned by account .","title":"balanceOf"},{"location":"apis/smart-contracts/IVPToken/#fn_balanceofat_4ee2cd7e","text":"Defined in IVPToken ( Docs , Source ). function balanceOfAt ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Queries the token balance of _owner at a specific _blockNumber . Parameters Type Description _owner address The address from which the balance will be retrieved. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The balance at _blockNumber .","title":"balanceOfAt"},{"location":"apis/smart-contracts/IVPToken/#fn_batchdelegate_dc4fcda7","text":"Defined in IVPToken ( Docs , Source ). function batchDelegate ( address [] _delegatees , uint256 [] _bips ) external ; Undelegate all percentage delegations from the sender and then delegate corresponding _bips percentage of voting power from the sender to each member of the _delegatees array. Parameters Type Description _delegatees address[] The addresses of the new recipients. _bips uint256[] The percentages of voting power to be delegated expressed in basis points (1/100 of one percent). The sum of all _bips values must be at most 10000 (100%).","title":"batchDelegate"},{"location":"apis/smart-contracts/IVPToken/#fn_decimals_313ce567","text":"Defined in IVPToken ( Docs , Source ). function decimals ( ) external view returns ( uint8 ); Returns the number of decimals used to get its user representation. For example, if decimals equals 2, a balance of 505 tokens should be displayed to a user as 5.05 (505 / 10 2 ). Tokens usually opt for a value of 18, imitating the relationship between Ether and wei. This is the default value returned by this function, unless it's overridden. NOTE: This information is only used for display purposes: it in no way affects any of the arithmetic of the contract, including balanceOf and transfer . Should be compatible with ERC20 method.","title":"decimals"},{"location":"apis/smart-contracts/IVPToken/#fn_delegate_026e402b","text":"Defined in IVPToken ( Docs , Source ). function delegate ( address _to , uint256 _bips ) external ; Delegate voting power to account _to from msg.sender , by percentage. Parameters Type Description _to address The address of the recipient. _bips uint256 The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: every call resets the delegation value (and a value of 0 revokes all previous delegations).","title":"delegate"},{"location":"apis/smart-contracts/IVPToken/#fn_delegateexplicit_d06dc3ad","text":"Defined in IVPToken ( Docs , Source ). function delegateExplicit ( address _to , uint256 _amount ) external ; Explicitly delegate _amount voting power to account _to from msg.sender . Compare with delegate which delegates by percentage. Parameters Type Description _to address The address of the recipient. _amount uint256 An explicit vote power amount to be delegated. Not cumulative: every call resets the delegation value (and a value of 0 revokes all previous delegations).","title":"delegateExplicit"},{"location":"apis/smart-contracts/IVPToken/#fn_delegatesof_7de5b8ed","text":"Defined in IVPToken ( Docs , Source ). function delegatesOf ( address _who ) external view returns ( address [] _delegateAddresses , uint256 [] _bips , uint256 _count , uint256 _delegationMode ); Get the list of addresses to which _who is delegating, and their percentages. Parameters Type Description _who address The address to query. Returns Type Description _delegateAddresses address[] Positional array of addresses being delegated to. _bips uint256[] Positional array of delegation percents specified in basis points (1/100 of 1 percent). Each one matches the address in the same position in the _delegateAddresses array. _count uint256 The number of delegates. _delegationMode uint256 Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).","title":"delegatesOf"},{"location":"apis/smart-contracts/IVPToken/#fn_delegatesofat_ed475a79","text":"Defined in IVPToken ( Docs , Source ). function delegatesOfAt ( address _who , uint256 _blockNumber ) external view returns ( address [] _delegateAddresses , uint256 [] _bips , uint256 _count , uint256 _delegationMode ); Get the list of addresses to which _who is delegating, and their percentages, at the given block. Parameters Type Description _who address The address to query. _blockNumber uint256 The block number to query. Returns Type Description _delegateAddresses address[] Positional array of addresses being delegated to. _bips uint256[] Positional array of delegation percents specified in basis points (1/100 of 1 percent). Each one matches the address in the same position in the _delegateAddresses array. _count uint256 The number of delegates. _delegationMode uint256 Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).","title":"delegatesOfAt"},{"location":"apis/smart-contracts/IVPToken/#fn_delegationmodeof_f6837767","text":"Defined in IVPToken ( Docs , Source ). function delegationModeOf ( address _who ) external view returns ( uint256 ); Get the delegation mode for account '_who'. This mode determines whether vote power is allocated by percentage or by explicit amount. Once the delegation mode is set, it can never be changed, even if all delegations are removed. Parameters Type Description _who address The address to get delegation mode. Returns Type Description [0] uint256 Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).","title":"delegationModeOf"},{"location":"apis/smart-contracts/IVPToken/#fn_governancevotepower_8c2b8ae1","text":"Defined in IVPToken ( Docs , Source ). function governanceVotePower ( ) external view returns ( contract IGovernanceVotePower ); When set, allows token owners to participate in governance voting and delegating governance vote power.","title":"governanceVotePower"},{"location":"apis/smart-contracts/IVPToken/#fn_name_06fdde03","text":"Defined in IVPToken ( Docs , Source ). function name ( ) external view returns ( string ); Returns the name of the token. Should be compatible with ERC20 method.","title":"name"},{"location":"apis/smart-contracts/IVPToken/#fn_readvotepowercontract_9b3baa0e","text":"Defined in IVPToken ( Docs , Source ). function readVotePowerContract ( ) external view returns ( contract IVPContractEvents ); Returns VPContract event interface used for read-only operations (view methods). The only non-view method that might be called on it is revokeDelegationAt . readVotePowerContract is almost always equal to writeVotePowerContract except during an upgrade from one VPContract to a new version (which should happen rarely or never and will be announced beforehand). Do not call any methods on VPContract directly. State changing methods are forbidden from direct calls. All methods are exposed via VPToken . This is the reason that this method returns IVPContractEvents . Use it only for listening to events and revoking.","title":"readVotePowerContract"},{"location":"apis/smart-contracts/IVPToken/#fn_revokedelegationat_bbd6fbf8","text":"Defined in IVPToken ( Docs , Source ). function revokeDelegationAt ( address _who , uint256 _blockNumber ) external ; Revoke all delegation from sender to _who at given block. Only affects the reads via votePowerOfAtCached() in the block _blockNumber . Block _blockNumber must be in the past. This method should be used only to prevent rogue delegate voting in the current voting block. To stop delegating use delegate / delegateExplicit with value of 0 or undelegateAll / undelegateAllExplicit . Parameters Type Description _who address Address of the delegatee. _blockNumber uint256 The block number at which to revoke delegation..","title":"revokeDelegationAt"},{"location":"apis/smart-contracts/IVPToken/#fn_symbol_95d89b41","text":"Defined in IVPToken ( Docs , Source ). function symbol ( ) external view returns ( string ); Returns the symbol of the token, usually a shorter version of the name . Should be compatible with ERC20 method.","title":"symbol"},{"location":"apis/smart-contracts/IVPToken/#fn_totalsupply_18160ddd","text":"Defined in IERC20 ( Source ). function totalSupply ( ) external view returns ( uint256 ); Returns the amount of tokens in existence.","title":"totalSupply"},{"location":"apis/smart-contracts/IVPToken/#fn_totalsupplyat_981b24d0","text":"Defined in IVPToken ( Docs , Source ). function totalSupplyAt ( uint256 _blockNumber ) external view returns ( uint256 ); Total amount of tokens held by all accounts at a specific block number. Parameters Type Description _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The total amount of tokens at _blockNumber .","title":"totalSupplyAt"},{"location":"apis/smart-contracts/IVPToken/#fn_totalvotepower_f5f3d4f7","text":"Defined in IVPToken ( Docs , Source ). function totalVotePower ( ) external view returns ( uint256 ); Get the current total vote power. Returns Type Description [0] uint256 The current total vote power (sum of all accounts' vote power).","title":"totalVotePower"},{"location":"apis/smart-contracts/IVPToken/#fn_totalvotepowerat_3e5aa26a","text":"Defined in IVPToken ( Docs , Source ). function totalVotePowerAt ( uint256 _blockNumber ) external view returns ( uint256 ); Get the total vote power at block _blockNumber . Parameters Type Description _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The total vote power at the queried block (sum of all accounts' vote powers).","title":"totalVotePowerAt"},{"location":"apis/smart-contracts/IVPToken/#fn_transfer_a9059cbb","text":"Defined in IERC20 ( Source ). function transfer ( address recipient , uint256 amount ) external returns ( bool ); Moves amount tokens from the caller's account to recipient . Returns a boolean value indicating whether the operation succeeded. Emits a Transfer event.","title":"transfer"},{"location":"apis/smart-contracts/IVPToken/#fn_transferfrom_23b872dd","text":"Defined in IERC20 ( Source ). function transferFrom ( address sender , address recipient , uint256 amount ) external returns ( bool ); Moves amount tokens from sender to recipient using the allowance mechanism. amount is then deducted from the caller's allowance . Returns a boolean value indicating whether the operation succeeded. Emits a Transfer event.","title":"transferFrom"},{"location":"apis/smart-contracts/IVPToken/#fn_undelegateall_b302f393","text":"Defined in IVPToken ( Docs , Source ). function undelegateAll ( ) external ; Undelegate all voting power of msg.sender . This effectively revokes all previous delegations. Can only be used with percentage delegation. Does not reset delegation mode back to NOT SET.","title":"undelegateAll"},{"location":"apis/smart-contracts/IVPToken/#fn_undelegateallexplicit_5d6d11eb","text":"Defined in IVPToken ( Docs , Source ). function undelegateAllExplicit ( address [] _delegateAddresses ) external returns ( uint256 ); Undelegate all explicit vote power by amount of msg.sender . Can only be used with explicit delegation. Does not reset delegation mode back to NOT SET. Parameters Type Description _delegateAddresses address[] Explicit delegation does not store delegatees' addresses, so the caller must supply them. Returns Type Description [0] uint256 The amount still delegated (in case the list of delegates was incomplete).","title":"undelegateAllExplicit"},{"location":"apis/smart-contracts/IVPToken/#fn_undelegatedvotepowerof_d6aa0b77","text":"Defined in IVPToken ( Docs , Source ). function undelegatedVotePowerOf ( address _owner ) external view returns ( uint256 ); Compute the current undelegated vote power of the _owner account. Parameters Type Description _owner address The address to query. Returns Type Description [0] uint256 The unallocated vote power of _owner .","title":"undelegatedVotePowerOf"},{"location":"apis/smart-contracts/IVPToken/#fn_undelegatedvotepowerofat_83035a82","text":"Defined in IVPToken ( Docs , Source ). function undelegatedVotePowerOfAt ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Get the undelegated vote power of the _owner account at a given block number. Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The unallocated vote power of _owner .","title":"undelegatedVotePowerOfAt"},{"location":"apis/smart-contracts/IVPToken/#fn_votepowerfromto_be0ca747","text":"Defined in IVPToken ( Docs , Source ). function votePowerFromTo ( address _from , address _to ) external view returns ( uint256 ); Get current delegated vote power from delegator _from to delegatee _to . Parameters Type Description _from address Address of delegator. _to address Address of delegatee. Returns Type Description [0] uint256 votePower The delegated vote power.","title":"votePowerFromTo"},{"location":"apis/smart-contracts/IVPToken/#fn_votepowerfromtoat_e64767aa","text":"Defined in IVPToken ( Docs , Source ). function votePowerFromToAt ( address _from , address _to , uint256 _blockNumber ) external view returns ( uint256 ); Get delegated vote power from delegator _from to delegatee _to at _blockNumber . Parameters Type Description _from address Address of delegator. _to address Address of delegatee. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The delegated vote power.","title":"votePowerFromToAt"},{"location":"apis/smart-contracts/IVPToken/#fn_votepowerof_142d1018","text":"Defined in IVPToken ( Docs , Source ). function votePowerOf ( address _owner ) external view returns ( uint256 ); Get the current vote power of _owner . Parameters Type Description _owner address The address to query. Returns Type Description [0] uint256 Current vote power of _owner .","title":"votePowerOf"},{"location":"apis/smart-contracts/IVPToken/#fn_votepowerofat_92bfe6d8","text":"Defined in IVPToken ( Docs , Source ). function votePowerOfAt ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Get the vote power of _owner at block _blockNumber Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 Vote power of _owner at block number _blockNumber .","title":"votePowerOfAt"},{"location":"apis/smart-contracts/IVPToken/#fn_votepowerofatignoringrevocation_04bb4e43","text":"Defined in IVPToken ( Docs , Source ). function votePowerOfAtIgnoringRevocation ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Get the vote power of _owner at block _blockNumber , ignoring revocation information (and cache). Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 Vote power of _owner at block number _blockNumber . Result doesn't change if vote power is revoked.","title":"votePowerOfAtIgnoringRevocation"},{"location":"apis/smart-contracts/IVPToken/#fn_writevotepowercontract_1fec092a","text":"Defined in IVPToken ( Docs , Source ). function writeVotePowerContract ( ) external view returns ( contract IVPContractEvents ); Returns VPContract event interface used for state-changing operations (non-view methods). The only non-view method that might be called on it is revokeDelegationAt . writeVotePowerContract is almost always equal to readVotePowerContract , except during upgrade from one VPContract to a new version (which should happen rarely or never and will be announced beforehand). In the case of an upgrade, writeVotePowerContract is replaced first to establish delegations. After some period (e.g., after a reward epoch ends), readVotePowerContract is set equal to it. Do not call any methods on VPContract directly. State changing methods are forbidden from direct calls. All are exposed via VPToken . This is the reason that this method returns IVPContractEvents Use it only for listening to events, delegating, and revoking.","title":"writeVotePowerContract"},{"location":"apis/smart-contracts/IVoterWhitelister/","text":"IVoterWhitelister # Source Interface for managers of the FTSO whitelist . Only addresses registered in this contract can submit data to the FTSO system. Events # VoterChilled # Defined in IVoterWhitelister ( Docs , Source ). event VoterChilled ( address voter , uint256 untilRewardEpoch ) Emitted when an account is chilled from the voter whitelist. Parameters Type Description voter address Address of the chilled account. untilRewardEpoch uint256 Epoch ID when the chill will be lifted. VoterRemovedFromWhitelist # Defined in IVoterWhitelister ( Docs , Source ). event VoterRemovedFromWhitelist ( address voter , uint256 ftsoIndex ) Emitted when an account is removed from the voter whitelist. Parameters Type Description voter address Address of the removed account. ftsoIndex uint256 Index of the FTSO in which it was registered. VoterWhitelisted # Defined in IVoterWhitelister ( Docs , Source ). event VoterWhitelisted ( address voter , uint256 ftsoIndex ) Emitted when an account is added to the voter whitelist. Parameters Type Description voter address Address of the added account. ftsoIndex uint256 Index of the FTSO to which it has been registered. Functions # chilledUntilRewardEpoch # Defined in IVoterWhitelister ( Docs , Source ). function chilledUntilRewardEpoch ( address _voter ) external view returns ( uint256 ); In case of providing bad prices (e.g. collusion), the voter can be chilled for a few reward epochs. A voter can whitelist again from a returned reward epoch onwards. Parameters Type Description _voter address Address of the queried data provider. Returns Type Description [0] uint256 uint256 ID of the epoch where the data provider can start submitting prices again. defaultMaxVotersForFtso # Defined in IVoterWhitelister ( Docs , Source ). function defaultMaxVotersForFtso ( ) external view returns ( uint256 ); Maximum number of voters in the whitelist for a new FTSO. Returns Type Description [0] uint256 uint256 Default maximum allowed voters. getFtsoWhitelistedPriceProviders # Defined in IVoterWhitelister ( Docs , Source ). function getFtsoWhitelistedPriceProviders ( uint256 _ftsoIndex ) external view returns ( address []); Gets whitelisted price providers for the FTSO at a given index. Parameters Type Description _ftsoIndex uint256 Queried index. Returns Type Description [0] address[] Array of addresses of the whitelisted data providers. getFtsoWhitelistedPriceProvidersBySymbol # Defined in IVoterWhitelister ( Docs , Source ). function getFtsoWhitelistedPriceProvidersBySymbol ( string _symbol ) external view returns ( address []); Gets whitelisted price providers for the FTSO with a specified symbol. Parameters Type Description _symbol string Queried symbol. Returns Type Description [0] address[] Array of addresses of the whitelisted data providers. maxVotersForFtso # Defined in IVoterWhitelister ( Docs , Source ). function maxVotersForFtso ( uint256 _ftsoIndex ) external view returns ( uint256 ); Maximum number of voters in the whitelist for a specific FTSO. Adjustable separately for each index. Parameters Type Description _ftsoIndex uint256 Index of the FTSO. Returns Type Description [0] uint256 uint256 Maximum allowed voters. requestFullVoterWhitelisting # Defined in IVoterWhitelister ( Docs , Source ). function requestFullVoterWhitelisting ( address _voter ) external returns ( uint256 [] _supportedIndices , bool [] _success ); Requests whitelisting an account to act as a data provider for all active FTSOs. May be called by any address, including the voter itself. Parameters Type Description _voter address Address of the voter to be whitelisted. Returns Type Description _supportedIndices uint256[] Array of currently supported FTSO indices. _success bool[] Array of success flags by FTSO index. requestWhitelistingVoter # Defined in IVoterWhitelister ( Docs , Source ). function requestWhitelistingVoter ( address _voter , uint256 _ftsoIndex ) external ; Requests whitelisting an account to act as a data provider for a specific FTSO. Reverts if the vote power of the account is too low. May be called by any address, including the voter itself. Parameters Type Description _voter address Address of the voter to be whitelisted. _ftsoIndex uint256 Index of the FTSO.","title":"IVoterWhitelister"},{"location":"apis/smart-contracts/IVoterWhitelister/#ct_ivoterwhitelister","text":"Source Interface for managers of the FTSO whitelist . Only addresses registered in this contract can submit data to the FTSO system.","title":"IVoterWhitelister"},{"location":"apis/smart-contracts/IVoterWhitelister/#events","text":"","title":"Events"},{"location":"apis/smart-contracts/IVoterWhitelister/#ev_voterchilled","text":"Defined in IVoterWhitelister ( Docs , Source ). event VoterChilled ( address voter , uint256 untilRewardEpoch ) Emitted when an account is chilled from the voter whitelist. Parameters Type Description voter address Address of the chilled account. untilRewardEpoch uint256 Epoch ID when the chill will be lifted.","title":"VoterChilled"},{"location":"apis/smart-contracts/IVoterWhitelister/#ev_voterremovedfromwhitelist","text":"Defined in IVoterWhitelister ( Docs , Source ). event VoterRemovedFromWhitelist ( address voter , uint256 ftsoIndex ) Emitted when an account is removed from the voter whitelist. Parameters Type Description voter address Address of the removed account. ftsoIndex uint256 Index of the FTSO in which it was registered.","title":"VoterRemovedFromWhitelist"},{"location":"apis/smart-contracts/IVoterWhitelister/#ev_voterwhitelisted","text":"Defined in IVoterWhitelister ( Docs , Source ). event VoterWhitelisted ( address voter , uint256 ftsoIndex ) Emitted when an account is added to the voter whitelist. Parameters Type Description voter address Address of the added account. ftsoIndex uint256 Index of the FTSO to which it has been registered.","title":"VoterWhitelisted"},{"location":"apis/smart-contracts/IVoterWhitelister/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IVoterWhitelister/#fn_chilleduntilrewardepoch_46538074","text":"Defined in IVoterWhitelister ( Docs , Source ). function chilledUntilRewardEpoch ( address _voter ) external view returns ( uint256 ); In case of providing bad prices (e.g. collusion), the voter can be chilled for a few reward epochs. A voter can whitelist again from a returned reward epoch onwards. Parameters Type Description _voter address Address of the queried data provider. Returns Type Description [0] uint256 uint256 ID of the epoch where the data provider can start submitting prices again.","title":"chilledUntilRewardEpoch"},{"location":"apis/smart-contracts/IVoterWhitelister/#fn_defaultmaxvotersforftso_47ed51b1","text":"Defined in IVoterWhitelister ( Docs , Source ). function defaultMaxVotersForFtso ( ) external view returns ( uint256 ); Maximum number of voters in the whitelist for a new FTSO. Returns Type Description [0] uint256 uint256 Default maximum allowed voters.","title":"defaultMaxVotersForFtso"},{"location":"apis/smart-contracts/IVoterWhitelister/#fn_getftsowhitelistedpriceproviders_09fcb400","text":"Defined in IVoterWhitelister ( Docs , Source ). function getFtsoWhitelistedPriceProviders ( uint256 _ftsoIndex ) external view returns ( address []); Gets whitelisted price providers for the FTSO at a given index. Parameters Type Description _ftsoIndex uint256 Queried index. Returns Type Description [0] address[] Array of addresses of the whitelisted data providers.","title":"getFtsoWhitelistedPriceProviders"},{"location":"apis/smart-contracts/IVoterWhitelister/#fn_getftsowhitelistedpriceprovidersbysymbol_aa89dfd4","text":"Defined in IVoterWhitelister ( Docs , Source ). function getFtsoWhitelistedPriceProvidersBySymbol ( string _symbol ) external view returns ( address []); Gets whitelisted price providers for the FTSO with a specified symbol. Parameters Type Description _symbol string Queried symbol. Returns Type Description [0] address[] Array of addresses of the whitelisted data providers.","title":"getFtsoWhitelistedPriceProvidersBySymbol"},{"location":"apis/smart-contracts/IVoterWhitelister/#fn_maxvotersforftso_98dccfc2","text":"Defined in IVoterWhitelister ( Docs , Source ). function maxVotersForFtso ( uint256 _ftsoIndex ) external view returns ( uint256 ); Maximum number of voters in the whitelist for a specific FTSO. Adjustable separately for each index. Parameters Type Description _ftsoIndex uint256 Index of the FTSO. Returns Type Description [0] uint256 uint256 Maximum allowed voters.","title":"maxVotersForFtso"},{"location":"apis/smart-contracts/IVoterWhitelister/#fn_requestfullvoterwhitelisting_b06cbaf7","text":"Defined in IVoterWhitelister ( Docs , Source ). function requestFullVoterWhitelisting ( address _voter ) external returns ( uint256 [] _supportedIndices , bool [] _success ); Requests whitelisting an account to act as a data provider for all active FTSOs. May be called by any address, including the voter itself. Parameters Type Description _voter address Address of the voter to be whitelisted. Returns Type Description _supportedIndices uint256[] Array of currently supported FTSO indices. _success bool[] Array of success flags by FTSO index.","title":"requestFullVoterWhitelisting"},{"location":"apis/smart-contracts/IVoterWhitelister/#fn_requestwhitelistingvoter_3de2cb1c","text":"Defined in IVoterWhitelister ( Docs , Source ). function requestWhitelistingVoter ( address _voter , uint256 _ftsoIndex ) external ; Requests whitelisting an account to act as a data provider for a specific FTSO. Reverts if the vote power of the account is too low. May be called by any address, including the voter itself. Parameters Type Description _voter address Address of the voter to be whitelisted. _ftsoIndex uint256 Index of the FTSO.","title":"requestWhitelistingVoter"},{"location":"apis/smart-contracts/IWNat/","text":"IWNat # Source Wrapped native token interface. This contract converts native tokens into WNAT (wrapped native) tokens and vice versa. WNAT tokens are a one-to-one ERC20 representation of native tokens, which are minted and burned as needed by this contract. The wrapped versions of the native FLR and SGB tokens are called WFLR and WSGB respectively. Code attribution: WETH9. Functions # deposit # Defined in IWNat ( Docs , Source ). function deposit ( ) external payable ; Deposits native tokens and mints the same amount of WNAT tokens, which are added to the msg.sender 's balance. This operation is commonly known as \"wrapping\". depositTo # Defined in IWNat ( Docs , Source ). function depositTo ( address _recipient ) external payable ; Deposits native tokens and mints the same amount of WNAT tokens, which are added to _recipient 's balance. This operation is commonly known as \"wrapping\". This is equivalent to using deposit followed by transfer . Parameters Type Description _recipient address The address to receive the minted WNAT . withdraw # Defined in IWNat ( Docs , Source ). function withdraw ( uint256 _amount ) external ; Burns _amount of WNAT tokens from msg.sender 's WNAT balance and transfers the same amount of native tokens to msg.sender . This operation is commonly known as \"unwrapping\". Reverts if _amount is higher than msg.sender 's WNAT balance. Parameters Type Description _amount uint256 The amount to withdraw. withdrawFrom # Defined in IWNat ( Docs , Source ). function withdrawFrom ( address _owner , uint256 _amount ) external ; Burns _amount of WNAT tokens from _owner 's WNAT balance and transfers the same amount of native tokens to msg.sender . This operation is commonly known as \"unwrapping\". msg.sender must have been authorized to withdraw from _owner 's account through ERC-20's approve mechanism. Reverts if _amount is higher than _owners 's WNAT balance or than msg.sender 's allowance over _owner 's tokens. Parameters Type Description _owner address The address containing the tokens to withdraw. _amount uint256 The amount to withdraw.","title":"IWNat"},{"location":"apis/smart-contracts/IWNat/#ct_iwnat","text":"Source Wrapped native token interface. This contract converts native tokens into WNAT (wrapped native) tokens and vice versa. WNAT tokens are a one-to-one ERC20 representation of native tokens, which are minted and burned as needed by this contract. The wrapped versions of the native FLR and SGB tokens are called WFLR and WSGB respectively. Code attribution: WETH9.","title":"IWNat"},{"location":"apis/smart-contracts/IWNat/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/IWNat/#fn_deposit_d0e30db0","text":"Defined in IWNat ( Docs , Source ). function deposit ( ) external payable ; Deposits native tokens and mints the same amount of WNAT tokens, which are added to the msg.sender 's balance. This operation is commonly known as \"wrapping\".","title":"deposit"},{"location":"apis/smart-contracts/IWNat/#fn_depositto_b760faf9","text":"Defined in IWNat ( Docs , Source ). function depositTo ( address _recipient ) external payable ; Deposits native tokens and mints the same amount of WNAT tokens, which are added to _recipient 's balance. This operation is commonly known as \"wrapping\". This is equivalent to using deposit followed by transfer . Parameters Type Description _recipient address The address to receive the minted WNAT .","title":"depositTo"},{"location":"apis/smart-contracts/IWNat/#fn_withdraw_2e1a7d4d","text":"Defined in IWNat ( Docs , Source ). function withdraw ( uint256 _amount ) external ; Burns _amount of WNAT tokens from msg.sender 's WNAT balance and transfers the same amount of native tokens to msg.sender . This operation is commonly known as \"unwrapping\". Reverts if _amount is higher than msg.sender 's WNAT balance. Parameters Type Description _amount uint256 The amount to withdraw.","title":"withdraw"},{"location":"apis/smart-contracts/IWNat/#fn_withdrawfrom_9470b0bd","text":"Defined in IWNat ( Docs , Source ). function withdrawFrom ( address _owner , uint256 _amount ) external ; Burns _amount of WNAT tokens from _owner 's WNAT balance and transfers the same amount of native tokens to msg.sender . This operation is commonly known as \"unwrapping\". msg.sender must have been authorized to withdraw from _owner 's account through ERC-20's approve mechanism. Reverts if _amount is higher than _owners 's WNAT balance or than msg.sender 's allowance over _owner 's tokens. Parameters Type Description _owner address The address containing the tokens to withdraw. _amount uint256 The amount to withdraw.","title":"withdrawFrom"},{"location":"apis/smart-contracts/Inflation/","text":"Inflation # Source | Inherits from IInflationGenesis , GovernedAndFlareDaemonized , IFlareDaemonize , AddressUpdatable Recognizes, authorizes, mints, and funds native tokens to Flare services that are rewardable through inflation. See the technical specification . Events # GovernanceCallTimelocked # Defined in GovernedBase ( Docs , Source ). event GovernanceCallTimelocked ( bytes4 selector , uint256 allowedAfterTimestamp , bytes encodedCall ) Emitted when a new governance call has been recorded and is now waiting for the time lock to expire. GovernanceInitialised # Defined in GovernedBase ( Docs , Source ). event GovernanceInitialised ( address initialGovernance ) Emitted when the governance address is initialized. This address will be used until production mode is entered (see GovernedProductionModeEntered ). At that point the governance address is taken from GovernanceSettings . GovernedProductionModeEntered # Defined in GovernedBase ( Docs , Source ). event GovernedProductionModeEntered ( address governanceSettings ) Emitted when governance is enabled and the governance address cannot be changed anymore (only through a network fork). InflationAllocationSet # Defined in Inflation ( Docs , Source ). event InflationAllocationSet ( contract IIInflationAllocation inflationAllocation ) InflationAuthorized # Defined in Inflation ( Docs , Source ). event InflationAuthorized ( uint256 amountWei ) InflationRewardServiceDailyAuthorizedInflationComputed # Defined in Inflation ( Docs , Source ). event InflationRewardServiceDailyAuthorizedInflationComputed ( contract IIInflationReceiver inflationReceiver , uint256 amountWei ) InflationRewardServiceTopupComputed # Defined in Inflation ( Docs , Source ). event InflationRewardServiceTopupComputed ( contract IIInflationReceiver inflationReceiver , uint256 amountWei ) InflationRewardServiceTopupRequestReceived # Defined in Inflation ( Docs , Source ). event InflationRewardServiceTopupRequestReceived ( contract IIInflationReceiver inflationReceiver , uint256 amountWei ) MintingReceived # Defined in Inflation ( Docs , Source ). event MintingReceived ( uint256 amountWei , uint256 selfDestructAmountWei ) NewTimeSlotInitialized # Defined in Inflation ( Docs , Source ). event NewTimeSlotInitialized ( uint256 startTimeStamp , uint256 endTimeStamp , uint256 inflatableSupplyWei , uint256 recognizedInflationWei ) SupplySet # Defined in Inflation ( Docs , Source ). event SupplySet ( contract IISupply oldSupply , contract IISupply newSupply ) TimelockedGovernanceCallCanceled # Defined in GovernedBase ( Docs , Source ). event TimelockedGovernanceCallCanceled ( bytes4 selector , uint256 timestamp ) Emitted when a timelocked governance call is canceled before execution. TimelockedGovernanceCallExecuted # Defined in GovernedBase ( Docs , Source ). event TimelockedGovernanceCallExecuted ( bytes4 selector , uint256 timestamp ) Emitted when a timelocked governance call is executed. TopupConfigurationSet # Defined in Inflation ( Docs , Source ). event TopupConfigurationSet ( struct TopupConfiguration topupConfiguration ) TopupRequested # Defined in Inflation ( Docs , Source ). event TopupRequested ( uint256 requestAmountWei , uint256 reRequestAmountWei ) Functions # cancelGovernanceCall # Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector. constructor # Defined in Inflation ( Docs , Source ). constructor ( address _governance , contract FlareDaemon _flareDaemon , address _addressUpdater , uint256 _rewardEpochStartTs ) public ; constructor # Defined in GovernedAndFlareDaemonized ( Docs , Source ). constructor ( address _governance , contract FlareDaemon _flareDaemon ) public ; constructor # Defined in Governed ( Docs , Source ). constructor ( address _governance ) public ; Parameters Type Description _governance address Governance contract. Must not be zero. daemonize # Defined in IFlareDaemonize ( Docs , Source ). function daemonize ( ) external returns ( bool ); Implement this function to receive a trigger from the FlareDaemon . The trigger method is called by the validator right at the end of block state transition. Returns Type Description [0] bool bool Whether the contract is still active after the call. Currently unused. executeGovernanceCall # Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored). getAddressUpdater # Defined in AddressUpdatable ( Docs , Source ). function getAddressUpdater ( ) public view returns ( address _addressUpdater ); Returns the configured address updater. Returns Type Description _addressUpdater address The AddresUpdater contract that can update our contract address list, as a response to a governance call. getContractName # Defined in Inflation ( Docs , Source ). function getContractName ( ) external pure returns ( string ); Implement this function to allow updating daemonized contracts through the AddressUpdater . Returns Type Description [0] string string Contract name. getCurrentTimeSlot # Defined in Inflation ( Docs , Source ). function getCurrentTimeSlot ( ) external view returns ( struct InflationTimeSlots . InflationTimeSlot ); Return the current time slot. Expect library to revert if there is no current time slot. Returns Type Description [0] struct InflationTimeSlots.InflationTimeSlot The inflation time slot state of the current time slot. getCurrentTimeSlotId # Defined in Inflation ( Docs , Source ). function getCurrentTimeSlotId ( ) external view returns ( uint256 ); Return current time slot id. Expect library to revert if there is no current time slot. Returns Type Description [0] uint256 Id of the current time slot. getNextExpectedTopupTs # Defined in Inflation ( Docs , Source ). function getNextExpectedTopupTs ( ) external view returns ( uint256 _nextTopupTs ); Returns next expected inflation topup time stamp which is also inflation authorization time. The returned time from this API is actually the time of the block in which the topup is requested. The Actual topup will take place in the next block. Expected diff is up to a few seconds (max is less then a minute). getRewardServices # Defined in Inflation ( Docs , Source ). function getRewardServices ( ) external view returns ( struct InflationRewardServices . RewardService []); Return the structure of reward services. Returns Type Description [0] struct InflationRewardServices.RewardService[] Reward services structure. getTimeSlot # Defined in Inflation ( Docs , Source ). function getTimeSlot ( uint256 _index ) external view returns ( struct InflationTimeSlots . InflationTimeSlot ); Given an index, return the time slot at that index. Expect library to revert if index not found. Parameters Type Description _index uint256 The index of the time slot to fetch. Returns Type Description [0] struct InflationTimeSlots.InflationTimeSlot The inflation time slot state. getTopupConfiguration # Defined in Inflation ( Docs , Source ). function getTopupConfiguration ( contract IIInflationReceiver _inflationReceiver ) external view returns ( struct TopupConfiguration _topupConfiguration ); Given an inflation receiver, get the topup configuration. Parameters Type Description _inflationReceiver contract IIInflationReceiver The reward service. Returns Type Description _topupConfiguration struct TopupConfiguration The configuration of how the topup requests are calculated for a given reward service. getTotals # Defined in Inflation ( Docs , Source ). function getTotals ( ) external view returns ( uint256 _totalAuthorizedInflationWei , uint256 _totalInflationTopupRequestedWei , uint256 _totalInflationTopupDistributedWei , uint256 _totalRecognizedInflationWei ); Get a tuple of totals across inflation time slots. Returns Type Description _totalAuthorizedInflationWei uint256 Total inflation authorized to be mintable _totalInflationTopupRequestedWei uint256 Total inflation requested to be topped up for rewarding _totalInflationTopupDistributedWei uint256 Total inflation received for funding reward services _totalRecognizedInflationWei uint256 Total inflation recognized for rewarding governance # Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address. receiveMinting # Defined in Inflation ( Docs , Source ). function receiveMinting ( ) external payable ; Receive newly minted native tokens from the FlareDaemon . Assume that the received amount will be >= last topup requested across all services. If there is not enough balance sent to cover the topup request, expect the library method to revert. Also assume that any received balance greater than the calculated topup request came from self-destructor sending a balance to this contract. setInitialData # Defined in Inflation ( Docs , Source ). function setInitialData ( contract IIInflationV1 _oldInflation , uint256 _noOfAnnums ) external ; Used to copy data from old inflation contract. Only governance can call. Parameters Type Description _oldInflation contract IIInflationV1 Address of old inflation. _noOfAnnums uint256 Number of annums in old inflation. setPreInflationCalculation # Defined in Inflation ( Docs , Source ). function setPreInflationCalculation ( contract IIPreInflationCalculation _preInflationCalculation ) external ; Set contract that should be triggered before new inflation is calculated (it can be address(0)) Only governance can call. setTopupConfiguration # Defined in Inflation ( Docs , Source ). function setTopupConfiguration ( contract IIInflationReceiver _inflationReceiver , enum TopupType _topupType , uint256 _topupFactorX100 ) external ; Set the topup configuration for a reward service. Only governance can call. Topup factor, if _topupType == FACTOROFDAILYAUTHORIZED, must be greater than 100. Parameters Type Description _inflationReceiver contract IIInflationReceiver The reward service to receive the inflation funds for distribution. _topupType enum TopupType The type to signal how the topup amounts are to be calculated. FACTOROFDAILYAUTHORIZED = Use a factor of last daily authorized to set a target balance for a reward service to maintain as a reserve for claiming. ALLAUTHORIZED = Mint enough native tokens to topup reward service contract to hold all authorized but unrequested rewards. _topupFactorX100 uint256 If _topupType == FACTOROFDAILYAUTHORIZED, then this factor (times 100) is multiplied by last daily authorized inflation to obtain the maximum balance that a reward service can hold at any given time. If it holds less, then this max amount is used to compute the mint request topup required to bring the reward service contract native token balance up to that amount. switchToFallbackMode # Defined in Inflation ( Docs , Source ). function switchToFallbackMode ( ) external view returns ( bool ); This function will be called after an error is caught in daemonize . It will switch the contract to a simpler fallback mode, which hopefully works when full mode doesn't. Not every contract needs to support fallback mode ( FtsoManager does), so this method may be empty. Switching back to normal mode is left to the contract (typically a governed method call). This function may be called due to low-gas error, so it shouldn't use more than ~30.000 gas. Returns Type Description [0] bool True if switched to fallback mode, false if already in fallback mode or if fallback mode is not supported. switchToProductionMode # Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered . updateContractAddresses # Defined in AddressUpdatable ( Docs , Source ). function updateContractAddresses ( bytes32 [] _contractNameHashes , address [] _contractAddresses ) external ; External method called from AddressUpdater only. Modifiers # notZero # Defined in Inflation ( Docs , Source ). modifier notZero ( address _address ) onlyAddressUpdater # Defined in AddressUpdatable ( Docs , Source ). modifier onlyAddressUpdater () Only the AdressUpdater contract can call this method. Its address is set at construction time but it can also update itself. onlyFlareDaemon # Defined in GovernedAndFlareDaemonized ( Docs , Source ). modifier onlyFlareDaemon () Only the flareDaemon can call this method. onlyGovernance # Defined in GovernedBase ( Docs , Source ). modifier onlyGovernance () onlyImmediateGovernance # Defined in GovernedBase ( Docs , Source ). modifier onlyImmediateGovernance () Variables # flareDaemon # Defined in GovernedAndFlareDaemonized ( Docs , Source ). contract FlareDaemon flareDaemon The FlareDaemon contract, set at construction time. governanceSettings # Defined in GovernedBase ( Docs , Source ). contract IGovernanceSettings governanceSettings Governance Settings. inflationAllocation # Defined in Inflation ( Docs , Source ). contract IIInflationAllocation inflationAllocation lastAuthorizationTs # Defined in Inflation ( Docs , Source ). uint256 lastAuthorizationTs The last time inflation was authorized. preInflationCalculation # Defined in Inflation ( Docs , Source ). contract IIPreInflationCalculation preInflationCalculation productionMode # Defined in GovernedBase ( Docs , Source ). bool productionMode When true, governance is enabled and cannot be disabled. See switchToProductionMode . rewardEpochStartTs # Defined in Inflation ( Docs , Source ). uint256 rewardEpochStartTs Do not start inflation time slots before this, in seconds after UNIX epoch. rewardEpochStartedTs # Defined in Inflation ( Docs , Source ). uint256 rewardEpochStartedTs When the first reward epoch was started, in seconds after UNIX epoch. supply # Defined in Inflation ( Docs , Source ). contract IISupply supply timelockedCalls # Defined in GovernedBase ( Docs , Source ). mapping ( bytes4 => struct GovernedBase . TimelockedCall ) timelockedCalls List of pending timelocked governance calls.","title":"Inflation"},{"location":"apis/smart-contracts/Inflation/#ct_inflation","text":"Source | Inherits from IInflationGenesis , GovernedAndFlareDaemonized , IFlareDaemonize , AddressUpdatable Recognizes, authorizes, mints, and funds native tokens to Flare services that are rewardable through inflation. See the technical specification .","title":"Inflation"},{"location":"apis/smart-contracts/Inflation/#events","text":"","title":"Events"},{"location":"apis/smart-contracts/Inflation/#ev_governancecalltimelocked","text":"Defined in GovernedBase ( Docs , Source ). event GovernanceCallTimelocked ( bytes4 selector , uint256 allowedAfterTimestamp , bytes encodedCall ) Emitted when a new governance call has been recorded and is now waiting for the time lock to expire.","title":"GovernanceCallTimelocked"},{"location":"apis/smart-contracts/Inflation/#ev_governanceinitialised","text":"Defined in GovernedBase ( Docs , Source ). event GovernanceInitialised ( address initialGovernance ) Emitted when the governance address is initialized. This address will be used until production mode is entered (see GovernedProductionModeEntered ). At that point the governance address is taken from GovernanceSettings .","title":"GovernanceInitialised"},{"location":"apis/smart-contracts/Inflation/#ev_governedproductionmodeentered","text":"Defined in GovernedBase ( Docs , Source ). event GovernedProductionModeEntered ( address governanceSettings ) Emitted when governance is enabled and the governance address cannot be changed anymore (only through a network fork).","title":"GovernedProductionModeEntered"},{"location":"apis/smart-contracts/Inflation/#ev_inflationallocationset","text":"Defined in Inflation ( Docs , Source ). event InflationAllocationSet ( contract IIInflationAllocation inflationAllocation )","title":"InflationAllocationSet"},{"location":"apis/smart-contracts/Inflation/#ev_inflationauthorized","text":"Defined in Inflation ( Docs , Source ). event InflationAuthorized ( uint256 amountWei )","title":"InflationAuthorized"},{"location":"apis/smart-contracts/Inflation/#ev_inflationrewardservicedailyauthorizedinflationcomputed","text":"Defined in Inflation ( Docs , Source ). event InflationRewardServiceDailyAuthorizedInflationComputed ( contract IIInflationReceiver inflationReceiver , uint256 amountWei )","title":"InflationRewardServiceDailyAuthorizedInflationComputed"},{"location":"apis/smart-contracts/Inflation/#ev_inflationrewardservicetopupcomputed","text":"Defined in Inflation ( Docs , Source ). event InflationRewardServiceTopupComputed ( contract IIInflationReceiver inflationReceiver , uint256 amountWei )","title":"InflationRewardServiceTopupComputed"},{"location":"apis/smart-contracts/Inflation/#ev_inflationrewardservicetopuprequestreceived","text":"Defined in Inflation ( Docs , Source ). event InflationRewardServiceTopupRequestReceived ( contract IIInflationReceiver inflationReceiver , uint256 amountWei )","title":"InflationRewardServiceTopupRequestReceived"},{"location":"apis/smart-contracts/Inflation/#ev_mintingreceived","text":"Defined in Inflation ( Docs , Source ). event MintingReceived ( uint256 amountWei , uint256 selfDestructAmountWei )","title":"MintingReceived"},{"location":"apis/smart-contracts/Inflation/#ev_newtimeslotinitialized","text":"Defined in Inflation ( Docs , Source ). event NewTimeSlotInitialized ( uint256 startTimeStamp , uint256 endTimeStamp , uint256 inflatableSupplyWei , uint256 recognizedInflationWei )","title":"NewTimeSlotInitialized"},{"location":"apis/smart-contracts/Inflation/#ev_supplyset","text":"Defined in Inflation ( Docs , Source ). event SupplySet ( contract IISupply oldSupply , contract IISupply newSupply )","title":"SupplySet"},{"location":"apis/smart-contracts/Inflation/#ev_timelockedgovernancecallcanceled","text":"Defined in GovernedBase ( Docs , Source ). event TimelockedGovernanceCallCanceled ( bytes4 selector , uint256 timestamp ) Emitted when a timelocked governance call is canceled before execution.","title":"TimelockedGovernanceCallCanceled"},{"location":"apis/smart-contracts/Inflation/#ev_timelockedgovernancecallexecuted","text":"Defined in GovernedBase ( Docs , Source ). event TimelockedGovernanceCallExecuted ( bytes4 selector , uint256 timestamp ) Emitted when a timelocked governance call is executed.","title":"TimelockedGovernanceCallExecuted"},{"location":"apis/smart-contracts/Inflation/#ev_topupconfigurationset","text":"Defined in Inflation ( Docs , Source ). event TopupConfigurationSet ( struct TopupConfiguration topupConfiguration )","title":"TopupConfigurationSet"},{"location":"apis/smart-contracts/Inflation/#ev_topuprequested","text":"Defined in Inflation ( Docs , Source ). event TopupRequested ( uint256 requestAmountWei , uint256 reRequestAmountWei )","title":"TopupRequested"},{"location":"apis/smart-contracts/Inflation/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/Inflation/#fn_cancelgovernancecall_67fc4029","text":"Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector.","title":"cancelGovernanceCall"},{"location":"apis/smart-contracts/Inflation/#fn_constructor_undefined","text":"Defined in Inflation ( Docs , Source ). constructor ( address _governance , contract FlareDaemon _flareDaemon , address _addressUpdater , uint256 _rewardEpochStartTs ) public ;","title":"constructor"},{"location":"apis/smart-contracts/Inflation/#fn_constructor_undefined","text":"Defined in GovernedAndFlareDaemonized ( Docs , Source ). constructor ( address _governance , contract FlareDaemon _flareDaemon ) public ;","title":"constructor"},{"location":"apis/smart-contracts/Inflation/#fn_constructor_undefined","text":"Defined in Governed ( Docs , Source ). constructor ( address _governance ) public ; Parameters Type Description _governance address Governance contract. Must not be zero.","title":"constructor"},{"location":"apis/smart-contracts/Inflation/#fn_daemonize_6d0e8c34","text":"Defined in IFlareDaemonize ( Docs , Source ). function daemonize ( ) external returns ( bool ); Implement this function to receive a trigger from the FlareDaemon . The trigger method is called by the validator right at the end of block state transition. Returns Type Description [0] bool bool Whether the contract is still active after the call. Currently unused.","title":"daemonize"},{"location":"apis/smart-contracts/Inflation/#fn_executegovernancecall_5ff27079","text":"Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored).","title":"executeGovernanceCall"},{"location":"apis/smart-contracts/Inflation/#fn_getaddressupdater_5267a15d","text":"Defined in AddressUpdatable ( Docs , Source ). function getAddressUpdater ( ) public view returns ( address _addressUpdater ); Returns the configured address updater. Returns Type Description _addressUpdater address The AddresUpdater contract that can update our contract address list, as a response to a governance call.","title":"getAddressUpdater"},{"location":"apis/smart-contracts/Inflation/#fn_getcontractname_f5f5ba72","text":"Defined in Inflation ( Docs , Source ). function getContractName ( ) external pure returns ( string ); Implement this function to allow updating daemonized contracts through the AddressUpdater . Returns Type Description [0] string string Contract name.","title":"getContractName"},{"location":"apis/smart-contracts/Inflation/#fn_getcurrenttimeslot_5f61a576","text":"Defined in Inflation ( Docs , Source ). function getCurrentTimeSlot ( ) external view returns ( struct InflationTimeSlots . InflationTimeSlot ); Return the current time slot. Expect library to revert if there is no current time slot. Returns Type Description [0] struct InflationTimeSlots.InflationTimeSlot The inflation time slot state of the current time slot.","title":"getCurrentTimeSlot"},{"location":"apis/smart-contracts/Inflation/#fn_getcurrenttimeslotid_7292d727","text":"Defined in Inflation ( Docs , Source ). function getCurrentTimeSlotId ( ) external view returns ( uint256 ); Return current time slot id. Expect library to revert if there is no current time slot. Returns Type Description [0] uint256 Id of the current time slot.","title":"getCurrentTimeSlotId"},{"location":"apis/smart-contracts/Inflation/#fn_getnextexpectedtopupts_f639c12c","text":"Defined in Inflation ( Docs , Source ). function getNextExpectedTopupTs ( ) external view returns ( uint256 _nextTopupTs ); Returns next expected inflation topup time stamp which is also inflation authorization time. The returned time from this API is actually the time of the block in which the topup is requested. The Actual topup will take place in the next block. Expected diff is up to a few seconds (max is less then a minute).","title":"getNextExpectedTopupTs"},{"location":"apis/smart-contracts/Inflation/#fn_getrewardservices_aa5b5eca","text":"Defined in Inflation ( Docs , Source ). function getRewardServices ( ) external view returns ( struct InflationRewardServices . RewardService []); Return the structure of reward services. Returns Type Description [0] struct InflationRewardServices.RewardService[] Reward services structure.","title":"getRewardServices"},{"location":"apis/smart-contracts/Inflation/#fn_gettimeslot_2b85dcc9","text":"Defined in Inflation ( Docs , Source ). function getTimeSlot ( uint256 _index ) external view returns ( struct InflationTimeSlots . InflationTimeSlot ); Given an index, return the time slot at that index. Expect library to revert if index not found. Parameters Type Description _index uint256 The index of the time slot to fetch. Returns Type Description [0] struct InflationTimeSlots.InflationTimeSlot The inflation time slot state.","title":"getTimeSlot"},{"location":"apis/smart-contracts/Inflation/#fn_gettopupconfiguration_4b13e872","text":"Defined in Inflation ( Docs , Source ). function getTopupConfiguration ( contract IIInflationReceiver _inflationReceiver ) external view returns ( struct TopupConfiguration _topupConfiguration ); Given an inflation receiver, get the topup configuration. Parameters Type Description _inflationReceiver contract IIInflationReceiver The reward service. Returns Type Description _topupConfiguration struct TopupConfiguration The configuration of how the topup requests are calculated for a given reward service.","title":"getTopupConfiguration"},{"location":"apis/smart-contracts/Inflation/#fn_gettotals_84e10a90","text":"Defined in Inflation ( Docs , Source ). function getTotals ( ) external view returns ( uint256 _totalAuthorizedInflationWei , uint256 _totalInflationTopupRequestedWei , uint256 _totalInflationTopupDistributedWei , uint256 _totalRecognizedInflationWei ); Get a tuple of totals across inflation time slots. Returns Type Description _totalAuthorizedInflationWei uint256 Total inflation authorized to be mintable _totalInflationTopupRequestedWei uint256 Total inflation requested to be topped up for rewarding _totalInflationTopupDistributedWei uint256 Total inflation received for funding reward services _totalRecognizedInflationWei uint256 Total inflation recognized for rewarding","title":"getTotals"},{"location":"apis/smart-contracts/Inflation/#fn_governance_5aa6e675","text":"Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address.","title":"governance"},{"location":"apis/smart-contracts/Inflation/#fn_receiveminting_c611c2c5","text":"Defined in Inflation ( Docs , Source ). function receiveMinting ( ) external payable ; Receive newly minted native tokens from the FlareDaemon . Assume that the received amount will be >= last topup requested across all services. If there is not enough balance sent to cover the topup request, expect the library method to revert. Also assume that any received balance greater than the calculated topup request came from self-destructor sending a balance to this contract.","title":"receiveMinting"},{"location":"apis/smart-contracts/Inflation/#fn_setinitialdata_b6f1f749","text":"Defined in Inflation ( Docs , Source ). function setInitialData ( contract IIInflationV1 _oldInflation , uint256 _noOfAnnums ) external ; Used to copy data from old inflation contract. Only governance can call. Parameters Type Description _oldInflation contract IIInflationV1 Address of old inflation. _noOfAnnums uint256 Number of annums in old inflation.","title":"setInitialData"},{"location":"apis/smart-contracts/Inflation/#fn_setpreinflationcalculation_095bfd5a","text":"Defined in Inflation ( Docs , Source ). function setPreInflationCalculation ( contract IIPreInflationCalculation _preInflationCalculation ) external ; Set contract that should be triggered before new inflation is calculated (it can be address(0)) Only governance can call.","title":"setPreInflationCalculation"},{"location":"apis/smart-contracts/Inflation/#fn_settopupconfiguration_6e61ab96","text":"Defined in Inflation ( Docs , Source ). function setTopupConfiguration ( contract IIInflationReceiver _inflationReceiver , enum TopupType _topupType , uint256 _topupFactorX100 ) external ; Set the topup configuration for a reward service. Only governance can call. Topup factor, if _topupType == FACTOROFDAILYAUTHORIZED, must be greater than 100. Parameters Type Description _inflationReceiver contract IIInflationReceiver The reward service to receive the inflation funds for distribution. _topupType enum TopupType The type to signal how the topup amounts are to be calculated. FACTOROFDAILYAUTHORIZED = Use a factor of last daily authorized to set a target balance for a reward service to maintain as a reserve for claiming. ALLAUTHORIZED = Mint enough native tokens to topup reward service contract to hold all authorized but unrequested rewards. _topupFactorX100 uint256 If _topupType == FACTOROFDAILYAUTHORIZED, then this factor (times 100) is multiplied by last daily authorized inflation to obtain the maximum balance that a reward service can hold at any given time. If it holds less, then this max amount is used to compute the mint request topup required to bring the reward service contract native token balance up to that amount.","title":"setTopupConfiguration"},{"location":"apis/smart-contracts/Inflation/#fn_switchtofallbackmode_e22fdece","text":"Defined in Inflation ( Docs , Source ). function switchToFallbackMode ( ) external view returns ( bool ); This function will be called after an error is caught in daemonize . It will switch the contract to a simpler fallback mode, which hopefully works when full mode doesn't. Not every contract needs to support fallback mode ( FtsoManager does), so this method may be empty. Switching back to normal mode is left to the contract (typically a governed method call). This function may be called due to low-gas error, so it shouldn't use more than ~30.000 gas. Returns Type Description [0] bool True if switched to fallback mode, false if already in fallback mode or if fallback mode is not supported.","title":"switchToFallbackMode"},{"location":"apis/smart-contracts/Inflation/#fn_switchtoproductionmode_f5a98383","text":"Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered .","title":"switchToProductionMode"},{"location":"apis/smart-contracts/Inflation/#fn_updatecontractaddresses_b00c0b76","text":"Defined in AddressUpdatable ( Docs , Source ). function updateContractAddresses ( bytes32 [] _contractNameHashes , address [] _contractAddresses ) external ; External method called from AddressUpdater only.","title":"updateContractAddresses"},{"location":"apis/smart-contracts/Inflation/#modifiers","text":"","title":"Modifiers"},{"location":"apis/smart-contracts/Inflation/#md_notzero","text":"Defined in Inflation ( Docs , Source ). modifier notZero ( address _address )","title":"notZero"},{"location":"apis/smart-contracts/Inflation/#md_onlyaddressupdater","text":"Defined in AddressUpdatable ( Docs , Source ). modifier onlyAddressUpdater () Only the AdressUpdater contract can call this method. Its address is set at construction time but it can also update itself.","title":"onlyAddressUpdater"},{"location":"apis/smart-contracts/Inflation/#md_onlyflaredaemon","text":"Defined in GovernedAndFlareDaemonized ( Docs , Source ). modifier onlyFlareDaemon () Only the flareDaemon can call this method.","title":"onlyFlareDaemon"},{"location":"apis/smart-contracts/Inflation/#md_onlygovernance","text":"Defined in GovernedBase ( Docs , Source ). modifier onlyGovernance ()","title":"onlyGovernance"},{"location":"apis/smart-contracts/Inflation/#md_onlyimmediategovernance","text":"Defined in GovernedBase ( Docs , Source ). modifier onlyImmediateGovernance ()","title":"onlyImmediateGovernance"},{"location":"apis/smart-contracts/Inflation/#variables","text":"","title":"Variables"},{"location":"apis/smart-contracts/Inflation/#va_flaredaemon","text":"Defined in GovernedAndFlareDaemonized ( Docs , Source ). contract FlareDaemon flareDaemon The FlareDaemon contract, set at construction time.","title":"flareDaemon"},{"location":"apis/smart-contracts/Inflation/#va_governancesettings","text":"Defined in GovernedBase ( Docs , Source ). contract IGovernanceSettings governanceSettings Governance Settings.","title":"governanceSettings"},{"location":"apis/smart-contracts/Inflation/#va_inflationallocation","text":"Defined in Inflation ( Docs , Source ). contract IIInflationAllocation inflationAllocation","title":"inflationAllocation"},{"location":"apis/smart-contracts/Inflation/#va_lastauthorizationts","text":"Defined in Inflation ( Docs , Source ). uint256 lastAuthorizationTs The last time inflation was authorized.","title":"lastAuthorizationTs"},{"location":"apis/smart-contracts/Inflation/#va_preinflationcalculation","text":"Defined in Inflation ( Docs , Source ). contract IIPreInflationCalculation preInflationCalculation","title":"preInflationCalculation"},{"location":"apis/smart-contracts/Inflation/#va_productionmode","text":"Defined in GovernedBase ( Docs , Source ). bool productionMode When true, governance is enabled and cannot be disabled. See switchToProductionMode .","title":"productionMode"},{"location":"apis/smart-contracts/Inflation/#va_rewardepochstartts","text":"Defined in Inflation ( Docs , Source ). uint256 rewardEpochStartTs Do not start inflation time slots before this, in seconds after UNIX epoch.","title":"rewardEpochStartTs"},{"location":"apis/smart-contracts/Inflation/#va_rewardepochstartedts","text":"Defined in Inflation ( Docs , Source ). uint256 rewardEpochStartedTs When the first reward epoch was started, in seconds after UNIX epoch.","title":"rewardEpochStartedTs"},{"location":"apis/smart-contracts/Inflation/#va_supply","text":"Defined in Inflation ( Docs , Source ). contract IISupply supply","title":"supply"},{"location":"apis/smart-contracts/Inflation/#va_timelockedcalls","text":"Defined in GovernedBase ( Docs , Source ). mapping ( bytes4 => struct GovernedBase . TimelockedCall ) timelockedCalls List of pending timelocked governance calls.","title":"timelockedCalls"},{"location":"apis/smart-contracts/PriceSubmitter/","text":"PriceSubmitter # Source | Inherits from IIPriceSubmitter , GovernedAtGenesis , AddressUpdatable Receives prices from FTSO data providers . It then forwards the submissions to the appropriate FTSO contract, allowing data providers to perform all required operations in a single transaction per price epoch. Functions # cancelGovernanceCall # Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector. constructor # Defined in PriceSubmitter ( Docs , Source ). constructor ( ) public ; This constructor should contain no code as this contract is pre-loaded into the genesis block. The super constructors are called for testing convenience. executeGovernanceCall # Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored). getAddressUpdater # Defined in AddressUpdatable ( Docs , Source ). function getAddressUpdater ( ) public view returns ( address _addressUpdater ); Returns the configured address updater. Returns Type Description _addressUpdater address The AddresUpdater contract that can update our contract address list, as a response to a governance call. getCurrentRandom # Defined in PriceSubmitter ( Docs , Source ). function getCurrentRandom ( ) external view returns ( uint256 ); Returns the random number for the previous epoch, obtained from the random numbers provided by all data providers along with their data submissions. Note that the random number for the previous epoch keeps updating as new submissions are revealed. It never reverts. Returns Type Description [0] uint256 Random number calculated from all data provider's submissions. getFtsoManager # Defined in PriceSubmitter ( Docs , Source ). function getFtsoManager ( ) external view returns ( contract IFtsoManagerGenesis ); Returns the address of the FtsoManager contract. getFtsoRegistry # Defined in PriceSubmitter ( Docs , Source ). function getFtsoRegistry ( ) external view returns ( contract IFtsoRegistryGenesis ); Returns the address of the FtsoRegistry contract. getRandom # Defined in PriceSubmitter ( Docs , Source ). function getRandom ( uint256 _epochId ) external view returns ( uint256 ); Returns the random number used in a specific past epoch, obtained from the random numbers provided by all data providers along with their data submissions. Parameters Type Description _epochId uint256 ID of the queried epoch. Current epoch cannot be queried, and the previous epoch is constantly updated as data providers reveal their prices and random numbers. Note that only the last 50 epochs can be queried and there is no bounds checking for this parameter. Out-of-bounds queries return undefined values. Returns Type Description [0] uint256 The random number used in that epoch. getTrustedAddresses # Defined in PriceSubmitter ( Docs , Source ). function getTrustedAddresses ( ) external view returns ( address []); Returns the list of trusted addresses that are always allowed to submit and reveal. Returns Type Description [0] address[] address[] Array of trusted voter addresses. getVoterWhitelister # Defined in PriceSubmitter ( Docs , Source ). function getVoterWhitelister ( ) external view returns ( address ); Returns the address of the VoterWhitelister contract managing the data provider whitelist. governance # Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address. initialise # Defined in GovernedAtGenesis ( Docs , Source ). function initialise ( address _governance ) public pure ; Disallow initialise to be called. Parameters Type Description _governance address The governance address for initial claiming. revealPrices # Defined in PriceSubmitter ( Docs , Source ). function revealPrices ( uint256 _epochId , uint256 [] _ftsoIndices , uint256 [] _prices , uint256 _random ) external ; Reveals submitted prices during the epoch reveal period. The hash of FTSO indices, prices, random number, and voter address must be equal to the hash previously submitted with submitHash . Emits a PricesRevealed event. Parameters Type Description _epochId uint256 ID of the epoch to which the price hashes are submitted. _ftsoIndices uint256[] List of FTSO indices in ascending order. _prices uint256[] List of submitted prices in USD. _random uint256 Submitted random number. setAddressUpdater # Defined in PriceSubmitter ( Docs , Source ). function setAddressUpdater ( address _addressUpdater ) external ; Sets the address updater contract. Only governance cal call this method. Parameters Type Description _addressUpdater address Address of the AddressUpdater contract. setTrustedAddresses # Defined in PriceSubmitter ( Docs , Source ). function setTrustedAddresses ( address [] _trustedAddresses ) external ; Set the trusted addresses that are always allowed to submit and reveal. Trusted addresses are used, for example, in fallback mode. Only FTSO Manager can call this method. Parameters Type Description _trustedAddresses address[] Array of FTSO data provider addresses (voters). The previous list of trusted addresses is discarded. submitHash # Defined in PriceSubmitter ( Docs , Source ). function submitHash ( uint256 _epochId , bytes32 _hash ) external ; Submits a hash for the current epoch. Can only be called by FTSO data providers whitelisted through the VoterWhitelisted contract. Emits the HashSubmitted event. Parameters Type Description _epochId uint256 ID of the target epoch to which the hash is submitted. _hash bytes32 A hash of the FTSO indices, prices, random number, and voter address. switchToProductionMode # Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered . updateContractAddresses # Defined in AddressUpdatable ( Docs , Source ). function updateContractAddresses ( bytes32 [] _contractNameHashes , address [] _contractAddresses ) external ; External method called from AddressUpdater only. voterWhitelistBitmap # Defined in PriceSubmitter ( Docs , Source ). function voterWhitelistBitmap ( address _voter ) external view returns ( uint256 ); Returns a bitmap of all FTSOs for which a data provider is allowed to submit prices or hashes. Parameters Type Description _voter address Address of the voter. Returns Type Description [0] uint256 If a data provider is allowed to vote for a given FTSO index, the corresponding bit in the result is 1. voterWhitelisted # Defined in PriceSubmitter ( Docs , Source ). function voterWhitelisted ( address _voter , uint256 _ftsoIndex ) external ; Called from the VoterWhitelister contract when a new voter has been whitelisted. Only the VoterWhitelister contract can call this method. Parameters Type Description _voter address Voter address that has been added to the whitelist. _ftsoIndex uint256 Index of the FTSO to which the voter has registered. Each FTSO has its own whitelist. votersRemovedFromWhitelist # Defined in PriceSubmitter ( Docs , Source ). function votersRemovedFromWhitelist ( address [] _removedVoters , uint256 _ftsoIndex ) external ; Called from the VoterWhitelister contract when one or more voters have been removed. Only the VoterWhitelister contract can call this method. Parameters Type Description _removedVoters address[] _ftsoIndex uint256 Index of the FTSO to which the voters were registered. Each FTSO has its own whitelist. Modifiers # onlyAddressUpdater # Defined in AddressUpdatable ( Docs , Source ). modifier onlyAddressUpdater () Only the AdressUpdater contract can call this method. Its address is set at construction time but it can also update itself. onlyFtsoManager # Defined in PriceSubmitter ( Docs , Source ). modifier onlyFtsoManager () Only the ftsoManager can call this method. onlyGovernance # Defined in GovernedBase ( Docs , Source ). modifier onlyGovernance () onlyImmediateGovernance # Defined in GovernedBase ( Docs , Source ). modifier onlyImmediateGovernance () onlyWhitelister # Defined in PriceSubmitter ( Docs , Source ). modifier onlyWhitelister () Only the voterWhitelister can call this method. Variables # MINIMAL_RANDOM # Defined in PriceSubmitter ( Docs , Source ). uint256 MINIMAL_RANDOM Minimal random value accepted along price submissions. Submitted random values below this threshold will revert. RANDOM_EPOCH_CYCLIC_BUFFER_SIZE # Defined in PriceSubmitter ( Docs , Source ). uint256 RANDOM_EPOCH_CYCLIC_BUFFER_SIZE Number of past random numbers remembered. governanceSettings # Defined in GovernedBase ( Docs , Source ). contract IGovernanceSettings governanceSettings Governance Settings. productionMode # Defined in GovernedBase ( Docs , Source ). bool productionMode When true, governance is enabled and cannot be disabled. See switchToProductionMode . timelockedCalls # Defined in GovernedBase ( Docs , Source ). mapping ( bytes4 => struct GovernedBase . TimelockedCall ) timelockedCalls List of pending timelocked governance calls.","title":"PriceSubmitter"},{"location":"apis/smart-contracts/PriceSubmitter/#ct_pricesubmitter","text":"Source | Inherits from IIPriceSubmitter , GovernedAtGenesis , AddressUpdatable Receives prices from FTSO data providers . It then forwards the submissions to the appropriate FTSO contract, allowing data providers to perform all required operations in a single transaction per price epoch.","title":"PriceSubmitter"},{"location":"apis/smart-contracts/PriceSubmitter/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/PriceSubmitter/#fn_cancelgovernancecall_67fc4029","text":"Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector.","title":"cancelGovernanceCall"},{"location":"apis/smart-contracts/PriceSubmitter/#fn_constructor_undefined","text":"Defined in PriceSubmitter ( Docs , Source ). constructor ( ) public ; This constructor should contain no code as this contract is pre-loaded into the genesis block. The super constructors are called for testing convenience.","title":"constructor"},{"location":"apis/smart-contracts/PriceSubmitter/#fn_executegovernancecall_5ff27079","text":"Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored).","title":"executeGovernanceCall"},{"location":"apis/smart-contracts/PriceSubmitter/#fn_getaddressupdater_5267a15d","text":"Defined in AddressUpdatable ( Docs , Source ). function getAddressUpdater ( ) public view returns ( address _addressUpdater ); Returns the configured address updater. Returns Type Description _addressUpdater address The AddresUpdater contract that can update our contract address list, as a response to a governance call.","title":"getAddressUpdater"},{"location":"apis/smart-contracts/PriceSubmitter/#fn_getcurrentrandom_d89601fd","text":"Defined in PriceSubmitter ( Docs , Source ). function getCurrentRandom ( ) external view returns ( uint256 ); Returns the random number for the previous epoch, obtained from the random numbers provided by all data providers along with their data submissions. Note that the random number for the previous epoch keeps updating as new submissions are revealed. It never reverts. Returns Type Description [0] uint256 Random number calculated from all data provider's submissions.","title":"getCurrentRandom"},{"location":"apis/smart-contracts/PriceSubmitter/#fn_getftsomanager_b39c6858","text":"Defined in PriceSubmitter ( Docs , Source ). function getFtsoManager ( ) external view returns ( contract IFtsoManagerGenesis ); Returns the address of the FtsoManager contract.","title":"getFtsoManager"},{"location":"apis/smart-contracts/PriceSubmitter/#fn_getftsoregistry_8c9d28b6","text":"Defined in PriceSubmitter ( Docs , Source ). function getFtsoRegistry ( ) external view returns ( contract IFtsoRegistryGenesis ); Returns the address of the FtsoRegistry contract.","title":"getFtsoRegistry"},{"location":"apis/smart-contracts/PriceSubmitter/#fn_getrandom_cd4b6914","text":"Defined in PriceSubmitter ( Docs , Source ). function getRandom ( uint256 _epochId ) external view returns ( uint256 ); Returns the random number used in a specific past epoch, obtained from the random numbers provided by all data providers along with their data submissions. Parameters Type Description _epochId uint256 ID of the queried epoch. Current epoch cannot be queried, and the previous epoch is constantly updated as data providers reveal their prices and random numbers. Note that only the last 50 epochs can be queried and there is no bounds checking for this parameter. Out-of-bounds queries return undefined values. Returns Type Description [0] uint256 The random number used in that epoch.","title":"getRandom"},{"location":"apis/smart-contracts/PriceSubmitter/#fn_gettrustedaddresses_ffacb84e","text":"Defined in PriceSubmitter ( Docs , Source ). function getTrustedAddresses ( ) external view returns ( address []); Returns the list of trusted addresses that are always allowed to submit and reveal. Returns Type Description [0] address[] address[] Array of trusted voter addresses.","title":"getTrustedAddresses"},{"location":"apis/smart-contracts/PriceSubmitter/#fn_getvoterwhitelister_71e1fad9","text":"Defined in PriceSubmitter ( Docs , Source ). function getVoterWhitelister ( ) external view returns ( address ); Returns the address of the VoterWhitelister contract managing the data provider whitelist.","title":"getVoterWhitelister"},{"location":"apis/smart-contracts/PriceSubmitter/#fn_governance_5aa6e675","text":"Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address.","title":"governance"},{"location":"apis/smart-contracts/PriceSubmitter/#fn_initialise_9d6a890f","text":"Defined in GovernedAtGenesis ( Docs , Source ). function initialise ( address _governance ) public pure ; Disallow initialise to be called. Parameters Type Description _governance address The governance address for initial claiming.","title":"initialise"},{"location":"apis/smart-contracts/PriceSubmitter/#fn_revealprices_e2db5a52","text":"Defined in PriceSubmitter ( Docs , Source ). function revealPrices ( uint256 _epochId , uint256 [] _ftsoIndices , uint256 [] _prices , uint256 _random ) external ; Reveals submitted prices during the epoch reveal period. The hash of FTSO indices, prices, random number, and voter address must be equal to the hash previously submitted with submitHash . Emits a PricesRevealed event. Parameters Type Description _epochId uint256 ID of the epoch to which the price hashes are submitted. _ftsoIndices uint256[] List of FTSO indices in ascending order. _prices uint256[] List of submitted prices in USD. _random uint256 Submitted random number.","title":"revealPrices"},{"location":"apis/smart-contracts/PriceSubmitter/#fn_setaddressupdater_aea36b53","text":"Defined in PriceSubmitter ( Docs , Source ). function setAddressUpdater ( address _addressUpdater ) external ; Sets the address updater contract. Only governance cal call this method. Parameters Type Description _addressUpdater address Address of the AddressUpdater contract.","title":"setAddressUpdater"},{"location":"apis/smart-contracts/PriceSubmitter/#fn_settrustedaddresses_9ec2b581","text":"Defined in PriceSubmitter ( Docs , Source ). function setTrustedAddresses ( address [] _trustedAddresses ) external ; Set the trusted addresses that are always allowed to submit and reveal. Trusted addresses are used, for example, in fallback mode. Only FTSO Manager can call this method. Parameters Type Description _trustedAddresses address[] Array of FTSO data provider addresses (voters). The previous list of trusted addresses is discarded.","title":"setTrustedAddresses"},{"location":"apis/smart-contracts/PriceSubmitter/#fn_submithash_8fc6f667","text":"Defined in PriceSubmitter ( Docs , Source ). function submitHash ( uint256 _epochId , bytes32 _hash ) external ; Submits a hash for the current epoch. Can only be called by FTSO data providers whitelisted through the VoterWhitelisted contract. Emits the HashSubmitted event. Parameters Type Description _epochId uint256 ID of the target epoch to which the hash is submitted. _hash bytes32 A hash of the FTSO indices, prices, random number, and voter address.","title":"submitHash"},{"location":"apis/smart-contracts/PriceSubmitter/#fn_switchtoproductionmode_f5a98383","text":"Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered .","title":"switchToProductionMode"},{"location":"apis/smart-contracts/PriceSubmitter/#fn_updatecontractaddresses_b00c0b76","text":"Defined in AddressUpdatable ( Docs , Source ). function updateContractAddresses ( bytes32 [] _contractNameHashes , address [] _contractAddresses ) external ; External method called from AddressUpdater only.","title":"updateContractAddresses"},{"location":"apis/smart-contracts/PriceSubmitter/#fn_voterwhitelistbitmap_7ac420ad","text":"Defined in PriceSubmitter ( Docs , Source ). function voterWhitelistBitmap ( address _voter ) external view returns ( uint256 ); Returns a bitmap of all FTSOs for which a data provider is allowed to submit prices or hashes. Parameters Type Description _voter address Address of the voter. Returns Type Description [0] uint256 If a data provider is allowed to vote for a given FTSO index, the corresponding bit in the result is 1.","title":"voterWhitelistBitmap"},{"location":"apis/smart-contracts/PriceSubmitter/#fn_voterwhitelisted_9d986f91","text":"Defined in PriceSubmitter ( Docs , Source ). function voterWhitelisted ( address _voter , uint256 _ftsoIndex ) external ; Called from the VoterWhitelister contract when a new voter has been whitelisted. Only the VoterWhitelister contract can call this method. Parameters Type Description _voter address Voter address that has been added to the whitelist. _ftsoIndex uint256 Index of the FTSO to which the voter has registered. Each FTSO has its own whitelist.","title":"voterWhitelisted"},{"location":"apis/smart-contracts/PriceSubmitter/#fn_votersremovedfromwhitelist_76794efb","text":"Defined in PriceSubmitter ( Docs , Source ). function votersRemovedFromWhitelist ( address [] _removedVoters , uint256 _ftsoIndex ) external ; Called from the VoterWhitelister contract when one or more voters have been removed. Only the VoterWhitelister contract can call this method. Parameters Type Description _removedVoters address[] _ftsoIndex uint256 Index of the FTSO to which the voters were registered. Each FTSO has its own whitelist.","title":"votersRemovedFromWhitelist"},{"location":"apis/smart-contracts/PriceSubmitter/#modifiers","text":"","title":"Modifiers"},{"location":"apis/smart-contracts/PriceSubmitter/#md_onlyaddressupdater","text":"Defined in AddressUpdatable ( Docs , Source ). modifier onlyAddressUpdater () Only the AdressUpdater contract can call this method. Its address is set at construction time but it can also update itself.","title":"onlyAddressUpdater"},{"location":"apis/smart-contracts/PriceSubmitter/#md_onlyftsomanager","text":"Defined in PriceSubmitter ( Docs , Source ). modifier onlyFtsoManager () Only the ftsoManager can call this method.","title":"onlyFtsoManager"},{"location":"apis/smart-contracts/PriceSubmitter/#md_onlygovernance","text":"Defined in GovernedBase ( Docs , Source ). modifier onlyGovernance ()","title":"onlyGovernance"},{"location":"apis/smart-contracts/PriceSubmitter/#md_onlyimmediategovernance","text":"Defined in GovernedBase ( Docs , Source ). modifier onlyImmediateGovernance ()","title":"onlyImmediateGovernance"},{"location":"apis/smart-contracts/PriceSubmitter/#md_onlywhitelister","text":"Defined in PriceSubmitter ( Docs , Source ). modifier onlyWhitelister () Only the voterWhitelister can call this method.","title":"onlyWhitelister"},{"location":"apis/smart-contracts/PriceSubmitter/#variables","text":"","title":"Variables"},{"location":"apis/smart-contracts/PriceSubmitter/#va_minimal_random","text":"Defined in PriceSubmitter ( Docs , Source ). uint256 MINIMAL_RANDOM Minimal random value accepted along price submissions. Submitted random values below this threshold will revert.","title":"MINIMAL_RANDOM"},{"location":"apis/smart-contracts/PriceSubmitter/#va_random_epoch_cyclic_buffer_size","text":"Defined in PriceSubmitter ( Docs , Source ). uint256 RANDOM_EPOCH_CYCLIC_BUFFER_SIZE Number of past random numbers remembered.","title":"RANDOM_EPOCH_CYCLIC_BUFFER_SIZE"},{"location":"apis/smart-contracts/PriceSubmitter/#va_governancesettings","text":"Defined in GovernedBase ( Docs , Source ). contract IGovernanceSettings governanceSettings Governance Settings.","title":"governanceSettings"},{"location":"apis/smart-contracts/PriceSubmitter/#va_productionmode","text":"Defined in GovernedBase ( Docs , Source ). bool productionMode When true, governance is enabled and cannot be disabled. See switchToProductionMode .","title":"productionMode"},{"location":"apis/smart-contracts/PriceSubmitter/#va_timelockedcalls","text":"Defined in GovernedBase ( Docs , Source ). mapping ( bytes4 => struct GovernedBase . TimelockedCall ) timelockedCalls List of pending timelocked governance calls.","title":"timelockedCalls"},{"location":"apis/smart-contracts/RevertErrorTracking/","text":"RevertErrorTracking # Source Revert error tracking contract. A contract to track and store revert errors. Events # ContractRevertError # Defined in RevertErrorTracking ( Docs , Source ). event ContractRevertError ( address theContract , uint256 atBlock , string theMessage ) Emitted when a contract reverts. Parameters Type Description theContract address The culprit's address. atBlock uint256 Block number where the error happened. theMessage string Reason for the revert, as reported by the contract. Functions # showLastRevertedError # Defined in RevertErrorTracking ( Docs , Source ). function showLastRevertedError ( ) external view returns ( uint256 [] _lastErrorBlock , uint256 [] _numErrors , string [] _errorString , address [] _erroringContract , uint256 _totalRevertedErrors ); Returns latest error information. All arrays will contain only one entry. Returns Type Description _lastErrorBlock uint256[] Array of block numbers where the errors occurred. _numErrors uint256[] Array of number of times same error with same contract address has been reverted. _errorString string[] Array of revert error messages. _erroringContract address[] Array of addresses of the reverting contracts. _totalRevertedErrors uint256 Total number of revert errors across all contracts. showRevertedErrors # Defined in RevertErrorTracking ( Docs , Source ). function showRevertedErrors ( uint256 startIndex , uint256 numErrorTypesToShow ) public view returns ( uint256 [] _lastErrorBlock , uint256 [] _numErrors , string [] _errorString , address [] _erroringContract , uint256 _totalRevertedErrors ); Returns latest errors. Parameters Type Description startIndex uint256 Starting index in the error list array. numErrorTypesToShow uint256 Number of errors to show. The total amount can be found in errorData . Returns Type Description _lastErrorBlock uint256[] Array of block numbers where the errors occurred. _numErrors uint256[] Array of number of times same error with same contract address has been reverted. _errorString string[] Array of revert error messages. _erroringContract address[] Array of addresses of the reverting contracts. _totalRevertedErrors uint256 Total number of revert errors across all contracts. Structures # LastErrorData # Defined in RevertErrorTracking ( Docs , Source ). struct LastErrorData { uint192 totalRevertedErrors ; uint64 lastErrorTypeIndex ; } RevertedError # Defined in RevertErrorTracking ( Docs , Source ). struct RevertedError { uint192 lastErrorBlock ; uint64 numErrors ; address fromContract ; uint64 errorTypeIndex ; string errorMessage ; } Variables # errorData # Defined in RevertErrorTracking ( Docs , Source ). struct RevertErrorTracking . LastErrorData errorData Most recent error information.","title":"RevertErrorTracking"},{"location":"apis/smart-contracts/RevertErrorTracking/#ct_reverterrortracking","text":"Source Revert error tracking contract. A contract to track and store revert errors.","title":"RevertErrorTracking"},{"location":"apis/smart-contracts/RevertErrorTracking/#events","text":"","title":"Events"},{"location":"apis/smart-contracts/RevertErrorTracking/#ev_contractreverterror","text":"Defined in RevertErrorTracking ( Docs , Source ). event ContractRevertError ( address theContract , uint256 atBlock , string theMessage ) Emitted when a contract reverts. Parameters Type Description theContract address The culprit's address. atBlock uint256 Block number where the error happened. theMessage string Reason for the revert, as reported by the contract.","title":"ContractRevertError"},{"location":"apis/smart-contracts/RevertErrorTracking/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/RevertErrorTracking/#fn_showlastrevertederror_2b3c41a4","text":"Defined in RevertErrorTracking ( Docs , Source ). function showLastRevertedError ( ) external view returns ( uint256 [] _lastErrorBlock , uint256 [] _numErrors , string [] _errorString , address [] _erroringContract , uint256 _totalRevertedErrors ); Returns latest error information. All arrays will contain only one entry. Returns Type Description _lastErrorBlock uint256[] Array of block numbers where the errors occurred. _numErrors uint256[] Array of number of times same error with same contract address has been reverted. _errorString string[] Array of revert error messages. _erroringContract address[] Array of addresses of the reverting contracts. _totalRevertedErrors uint256 Total number of revert errors across all contracts.","title":"showLastRevertedError"},{"location":"apis/smart-contracts/RevertErrorTracking/#fn_showrevertederrors_6ea0aa31","text":"Defined in RevertErrorTracking ( Docs , Source ). function showRevertedErrors ( uint256 startIndex , uint256 numErrorTypesToShow ) public view returns ( uint256 [] _lastErrorBlock , uint256 [] _numErrors , string [] _errorString , address [] _erroringContract , uint256 _totalRevertedErrors ); Returns latest errors. Parameters Type Description startIndex uint256 Starting index in the error list array. numErrorTypesToShow uint256 Number of errors to show. The total amount can be found in errorData . Returns Type Description _lastErrorBlock uint256[] Array of block numbers where the errors occurred. _numErrors uint256[] Array of number of times same error with same contract address has been reverted. _errorString string[] Array of revert error messages. _erroringContract address[] Array of addresses of the reverting contracts. _totalRevertedErrors uint256 Total number of revert errors across all contracts.","title":"showRevertedErrors"},{"location":"apis/smart-contracts/RevertErrorTracking/#structures","text":"","title":"Structures"},{"location":"apis/smart-contracts/RevertErrorTracking/#st_lasterrordata","text":"Defined in RevertErrorTracking ( Docs , Source ). struct LastErrorData { uint192 totalRevertedErrors ; uint64 lastErrorTypeIndex ; }","title":"LastErrorData"},{"location":"apis/smart-contracts/RevertErrorTracking/#st_revertederror","text":"Defined in RevertErrorTracking ( Docs , Source ). struct RevertedError { uint192 lastErrorBlock ; uint64 numErrors ; address fromContract ; uint64 errorTypeIndex ; string errorMessage ; }","title":"RevertedError"},{"location":"apis/smart-contracts/RevertErrorTracking/#variables","text":"","title":"Variables"},{"location":"apis/smart-contracts/RevertErrorTracking/#va_errordata","text":"Defined in RevertErrorTracking ( Docs , Source ). struct RevertErrorTracking . LastErrorData errorData Most recent error information.","title":"errorData"},{"location":"apis/smart-contracts/VPContract/","text":"VPContract # Source | Inherits from IIVPContract , Delegatable Helper contract handling all the vote power and delegation functionality for an associated VPToken . Functions # batchVotePowerOfAt # Defined in VPContract ( Docs , Source ). function batchVotePowerOfAt ( address [] _owners , uint256 _blockNumber ) external view returns ( uint256 [] _votePowers ); Get the vote power of a set of addresses at a given block number. Parameters Type Description _owners address[] The list of addresses being queried. _blockNumber uint256 The block number being queried. Returns Type Description _votePowers uint256[] Vote power of each address at _blockNumber , including any delegation received. cleanupBlockNumber # Defined in VPContract ( Docs , Source ). function cleanupBlockNumber ( ) external view returns ( uint256 ); Get the current cleanup block number set with setCleanupBlockNumber . Returns Type Description [0] uint256 The currently set cleanup block number. constructor # Defined in VPContract ( Docs , Source ). constructor ( contract IVPToken _ownerToken , bool _isReplacement ) public ; Construct VPContract for given VPToken . delegate # Defined in VPContract ( Docs , Source ). function delegate ( address _from , address _to , uint256 _balance , uint256 _bips ) external ; Delegate _bips percentage of voting power from a delegator address to a delegatee address. Parameters Type Description _from address The address of the delegator. _to address The address of the delegatee. _balance uint256 The delegator's current balance _bips uint256 The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: every call resets the delegation value (and a value of 0 revokes delegation). delegateExplicit # Defined in VPContract ( Docs , Source ). function delegateExplicit ( address _from , address _to , uint256 _balance , uint256 _amount ) external ; Explicitly delegate _amount tokens of voting power from a delegator address to a delegatee address. Parameters Type Description _from address The address of the delegator. _to address The address of the delegatee. _balance uint256 The delegator's current balance. _amount uint256 An explicit vote power amount to be delegated. Not cumulative: every call resets the delegation value (and a value of 0 undelegates _to ). delegatesOf # Defined in VPContract ( Docs , Source ). function delegatesOf ( address _owner ) external view returns ( address [] _delegateAddresses , uint256 [] _bips , uint256 _count , uint256 _delegationMode ); Get the percentages and addresses being delegated to by a vote power delegator. Parameters Type Description _owner address The address of the delegator being queried. Returns Type Description _delegateAddresses address[] Array of delegatee addresses. _bips uint256[] Array of delegation percents specified in basis points (1/100 or 1 percent), for each delegatee. _count uint256 The number of returned delegatees. _delegationMode uint256 The mode of the delegation (NOTSET=0, PERCENTAGE=1, AMOUNT=2). See Delegatable .DelegationMode. delegatesOfAt # Defined in VPContract ( Docs , Source ). function delegatesOfAt ( address _owner , uint256 _blockNumber ) public view returns ( address [] _delegateAddresses , uint256 [] _bips , uint256 _count , uint256 _delegationMode ); Get the percentages and addresses being delegated to by a vote power delegator, at a given block. Parameters Type Description _owner address The address of the delegator being queried. _blockNumber uint256 The block number being queried. Returns Type Description _delegateAddresses address[] Array of delegatee addresses. _bips uint256[] Array of delegation percents specified in basis points (1/100 or 1 percent), for each delegatee. _count uint256 The number of returned delegatees. _delegationMode uint256 The mode of the delegation (NOTSET=0, PERCENTAGE=1, AMOUNT=2). See Delegatable .DelegationMode. delegationModeOf # Defined in VPContract ( Docs , Source ). function delegationModeOf ( address _who ) external view returns ( uint256 ); Get the delegation mode of an address. This mode determines whether vote power is allocated by percentage or by explicit value and cannot be changed once set with delegate or delegateExplicit . Parameters Type Description _who address The address being queried. Returns Type Description [0] uint256 Delegation mode (NOTSET=0, PERCENTAGE=1, AMOUNT=2). See Delegatable .DelegationMode. explicitDelegationHistoryCleanup # Defined in Delegatable ( Docs , Source ). function explicitDelegationHistoryCleanup ( address _from , address _to , uint256 _count ) external returns ( uint256 ); Delete explicit delegation checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _from address Delegator address. _to address Delegatee address. _count uint256 Maximum number of checkpoints to delete. Returns Type Description [0] uint256 Number of checkpoints deleted. isReplacement # Defined in IIVPContract ( Docs , Source ). function isReplacement ( ) external view returns ( bool ); Return true if this IIVPContract is configured to be used as a replacement for other contract. It means that vote powers are not necessarily correct at the initialization, therefore every method that reads vote power must check whether it is initialized for that address and block. ownerToken # Defined in IIVPContract ( Docs , Source ). function ownerToken ( ) external view returns ( contract IVPToken ); The VPToken (or some other contract) that owns this VPContract . All state changing methods may be called only from this address. This is because original msg.sender is typically sent in a parameter and we must make sure that it cannot be faked by directly calling IIVPContract methods. Owner token is also used in case of replacement to recover vote powers from balances. percentageDelegationHistoryCleanup # Defined in Delegatable ( Docs , Source ). function percentageDelegationHistoryCleanup ( address _owner , uint256 _count ) external returns ( uint256 ); Delete percentage delegation checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _owner address Balance owner account address. _count uint256 Maximum number of checkpoints to delete. Returns Type Description [0] uint256 Number of deleted checkpoints. revocationCleanup # Defined in Delegatable ( Docs , Source ). function revocationCleanup ( address _from , address _to , uint256 _blockNumber ) external returns ( uint256 ); Delete revocation entry that expired (i.e. is before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _from address Delegator address. _to address Delegatee address. _blockNumber uint256 Block number for which total supply value was cached. Returns Type Description [0] uint256 Number of revocation entries deleted (always 0 or 1). revokeDelegationAt # Defined in VPContract ( Docs , Source ). function revokeDelegationAt ( address _from , address _to , uint256 _balance , uint256 _blockNumber ) external ; Revoke all vote power delegation from a delegator address to a delegatee address at a given block. Only affects the reads via votePowerOfAtCached in the block _blockNumber . This method should be used only to prevent rogue delegate voting in the current voting block. To stop delegating use delegate or delegateExplicit with value of 0, or undelegateAll / undelegateAllExplicit . Parameters Type Description _from address The address of the delegator. _to address Address of the delegatee. _balance uint256 The delegator's current balance. _blockNumber uint256 The block number at which to revoke delegation. Must be in the past. setCleanerContract # Defined in VPContract ( Docs , Source ). function setCleanerContract ( address _cleanerContract ) external ; Set the contract that is allowed to call history cleaning methods. Parameters Type Description _cleanerContract address Address of the cleanup contract. Usually this will be an instance of CleanupBlockNumberManager . setCleanupBlockNumber # Defined in VPContract ( Docs , Source ). function setCleanupBlockNumber ( uint256 _blockNumber ) external ; Set the cleanup block number. Historic data for the blocks before cleanupBlockNumber can be erased. History before that block should never be used since it can be inconsistent. In particular, cleanup block number must be lower than the current vote power block. The method can be called only by the owner token. Parameters Type Description _blockNumber uint256 The new cleanup block number. undelegateAll # Defined in VPContract ( Docs , Source ). function undelegateAll ( address _from , uint256 _balance ) external ; Undelegate all voting power for a delegator address. Can only be used with percentage delegation. Does not reset delegation mode back to NOTSET . Parameters Type Description _from address The address of the delegator. _balance uint256 The delegator's current balance. undelegateAllExplicit # Defined in VPContract ( Docs , Source ). function undelegateAllExplicit ( address _from , address [] _delegateAddresses ) external returns ( uint256 ); Undelegate all explicit vote power by amount for a delegator address. Can only be used with explicit delegation. Does not reset delegation mode back to NOTSET . Parameters Type Description _from address The address of the delegator. _delegateAddresses address[] Explicit delegation does not store delegatees' addresses, so the caller must supply them. Returns Type Description [0] uint256 The amount still delegated (in case the list of delegates was incomplete). undelegatedVotePowerOf # Defined in VPContract ( Docs , Source ). function undelegatedVotePowerOf ( address _owner , uint256 _balance ) external view returns ( uint256 ); Compute the current undelegated vote power of an address. Parameters Type Description _owner address The address being queried. _balance uint256 Current balance of that address. Returns Type Description [0] uint256 The unallocated vote power of _owner , this is, the amount of vote power currently not being delegated to other addresses. undelegatedVotePowerOfAt # Defined in VPContract ( Docs , Source ). function undelegatedVotePowerOfAt ( address _owner , uint256 _balance , uint256 _blockNumber ) external view returns ( uint256 ); Compute the undelegated vote power of an address at a given block. Parameters Type Description _owner address The address being queried. _balance uint256 _blockNumber uint256 The block number being queried. Returns Type Description [0] uint256 The unallocated vote power of _owner , this is, the amount of vote power that was not being delegated to other addresses at that block number. updateAtTokenTransfer # Defined in VPContract ( Docs , Source ). function updateAtTokenTransfer ( address _from , address _to , uint256 _fromBalance , uint256 _toBalance , uint256 _amount ) external ; Update vote powers when tokens are transferred. Also update delegated vote powers for percentage delegation and check for enough funds for explicit delegations. Parameters Type Description _from address Source account of the transfer. _to address Destination account of the transfer. _fromBalance uint256 Balance of the source account before the transfer. _toBalance uint256 Balance of the destination account before the transfer. _amount uint256 Amount that has been transferred. votePowerCacheCleanup # Defined in Delegatable ( Docs , Source ). function votePowerCacheCleanup ( address _owner , uint256 _blockNumber ) external returns ( uint256 ); Delete vote power cache entry that expired (i.e. is before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _owner address Vote power owner account address. _blockNumber uint256 Block number for which total supply value was cached. Returns Type Description [0] uint256 Number of deleted cache entries (always 0 or 1). votePowerFromTo # Defined in VPContract ( Docs , Source ). function votePowerFromTo ( address _from , address _to , uint256 _balance ) external view returns ( uint256 ); Get current delegated vote power from a delegator to a delegatee. Parameters Type Description _from address Address of the delegator. _to address Address of the delegatee. _balance uint256 The delegator's current balance. Returns Type Description [0] uint256 The delegated vote power. votePowerFromToAt # Defined in VPContract ( Docs , Source ). function votePowerFromToAt ( address _from , address _to , uint256 _balance , uint256 _blockNumber ) external view returns ( uint256 ); Get delegated the vote power from a delegator to a delegatee at a given block number. Parameters Type Description _from address Address of the delegator. _to address Address of the delegatee. _balance uint256 The delegator's current balance. _blockNumber uint256 The block number being queried. Returns Type Description [0] uint256 The delegated vote power. votePowerHistoryCleanup # Defined in Delegatable ( Docs , Source ). function votePowerHistoryCleanup ( address _owner , uint256 _count ) external returns ( uint256 ); Delete vote power checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _owner address Vote power owner account address. _count uint256 Maximum number of checkpoints to delete. Returns Type Description [0] uint256 Number of deleted checkpoints. votePowerOf # Defined in VPContract ( Docs , Source ). function votePowerOf ( address _who ) external view returns ( uint256 ); Get the current vote power of an address. Parameters Type Description _who address The address being queried. Returns Type Description [0] uint256 Current vote power of _who , including any delegation received. votePowerOfAt # Defined in VPContract ( Docs , Source ). function votePowerOfAt ( address _who , uint256 _blockNumber ) public view returns ( uint256 ); Get the vote power of an address at a given block number Parameters Type Description _who address The address being queried. _blockNumber uint256 The block number being queried. Returns Type Description [0] uint256 Vote power of _who at _blockNumber , including any delegation received. votePowerOfAtCached # Defined in VPContract ( Docs , Source ). function votePowerOfAtCached ( address _who , uint256 _blockNumber ) external returns ( uint256 ); Get the vote power of an address at a given block number. Reads/updates cache and upholds revocations. Parameters Type Description _who address The address being queried. _blockNumber uint256 The block number being queried. Returns Type Description [0] uint256 Vote power of _who at _blockNumber , including any delegation received. votePowerOfAtIgnoringRevocation # Defined in VPContract ( Docs , Source ). function votePowerOfAtIgnoringRevocation ( address _who , uint256 _blockNumber ) external view returns ( uint256 ); Get the vote power of an address at a given block number, ignoring revocation information and cache. Parameters Type Description _who address The address being queried. _blockNumber uint256 The block number being queried. Returns Type Description [0] uint256 Vote power of _who at _blockNumber , including any delegation received. Result doesn't change if vote power is revoked. Modifiers # notBeforeCleanupBlock # Defined in Delegatable ( Docs , Source ). modifier notBeforeCleanupBlock ( uint256 _blockNumber ) Reading from history is not allowed before cleanupBlockNumber , since data before that might have been deleted and is thus unreliable. Parameters Type Description _blockNumber uint256 The block number being checked for validity. onlyCleaner # Defined in Delegatable ( Docs , Source ). modifier onlyCleaner () History cleaning methods can be called only from cleanerContract . onlyExplicit # Defined in VPContract ( Docs , Source ). modifier onlyExplicit ( address sender ) If a delegate cannot be added by explicit amount, revert. onlyOwnerToken # Defined in VPContract ( Docs , Source ). modifier onlyOwnerToken () All external methods in VPContract can only be executed by the owner token. onlyPercent # Defined in VPContract ( Docs , Source ). modifier onlyPercent ( address sender ) If a delegate cannot be added by percentage, revert. Variables # cleanerContract # Defined in Delegatable ( Docs , Source ). address cleanerContract Address of the contract that is allowed to call methods for history cleaning. isReplacement # Defined in VPContract ( Docs , Source ). bool isReplacement Return true if this IIVPContract is configured to be used as a replacement for other contract. It means that vote powers are not necessarily correct at the initialization, therefore every method that reads vote power must check whether it is initialized for that address and block. ownerToken # Defined in VPContract ( Docs , Source ). contract IVPToken ownerToken The VPToken (or some other contract) that owns this VPContract . All state changing methods may be called only from this address. This is because original msg.sender is typically sent in a parameter and we must make sure that it cannot be faked by directly calling IIVPContract methods. Owner token is also used in case of replacement to recover vote powers from balances.","title":"VPContract"},{"location":"apis/smart-contracts/VPContract/#ct_vpcontract","text":"Source | Inherits from IIVPContract , Delegatable Helper contract handling all the vote power and delegation functionality for an associated VPToken .","title":"VPContract"},{"location":"apis/smart-contracts/VPContract/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/VPContract/#fn_batchvotepowerofat_49e3c7e5","text":"Defined in VPContract ( Docs , Source ). function batchVotePowerOfAt ( address [] _owners , uint256 _blockNumber ) external view returns ( uint256 [] _votePowers ); Get the vote power of a set of addresses at a given block number. Parameters Type Description _owners address[] The list of addresses being queried. _blockNumber uint256 The block number being queried. Returns Type Description _votePowers uint256[] Vote power of each address at _blockNumber , including any delegation received.","title":"batchVotePowerOfAt"},{"location":"apis/smart-contracts/VPContract/#fn_cleanupblocknumber_deea13e7","text":"Defined in VPContract ( Docs , Source ). function cleanupBlockNumber ( ) external view returns ( uint256 ); Get the current cleanup block number set with setCleanupBlockNumber . Returns Type Description [0] uint256 The currently set cleanup block number.","title":"cleanupBlockNumber"},{"location":"apis/smart-contracts/VPContract/#fn_constructor_undefined","text":"Defined in VPContract ( Docs , Source ). constructor ( contract IVPToken _ownerToken , bool _isReplacement ) public ; Construct VPContract for given VPToken .","title":"constructor"},{"location":"apis/smart-contracts/VPContract/#fn_delegate_6230001a","text":"Defined in VPContract ( Docs , Source ). function delegate ( address _from , address _to , uint256 _balance , uint256 _bips ) external ; Delegate _bips percentage of voting power from a delegator address to a delegatee address. Parameters Type Description _from address The address of the delegator. _to address The address of the delegatee. _balance uint256 The delegator's current balance _bips uint256 The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: every call resets the delegation value (and a value of 0 revokes delegation).","title":"delegate"},{"location":"apis/smart-contracts/VPContract/#fn_delegateexplicit_404d9e82","text":"Defined in VPContract ( Docs , Source ). function delegateExplicit ( address _from , address _to , uint256 _balance , uint256 _amount ) external ; Explicitly delegate _amount tokens of voting power from a delegator address to a delegatee address. Parameters Type Description _from address The address of the delegator. _to address The address of the delegatee. _balance uint256 The delegator's current balance. _amount uint256 An explicit vote power amount to be delegated. Not cumulative: every call resets the delegation value (and a value of 0 undelegates _to ).","title":"delegateExplicit"},{"location":"apis/smart-contracts/VPContract/#fn_delegatesof_7de5b8ed","text":"Defined in VPContract ( Docs , Source ). function delegatesOf ( address _owner ) external view returns ( address [] _delegateAddresses , uint256 [] _bips , uint256 _count , uint256 _delegationMode ); Get the percentages and addresses being delegated to by a vote power delegator. Parameters Type Description _owner address The address of the delegator being queried. Returns Type Description _delegateAddresses address[] Array of delegatee addresses. _bips uint256[] Array of delegation percents specified in basis points (1/100 or 1 percent), for each delegatee. _count uint256 The number of returned delegatees. _delegationMode uint256 The mode of the delegation (NOTSET=0, PERCENTAGE=1, AMOUNT=2). See Delegatable .DelegationMode.","title":"delegatesOf"},{"location":"apis/smart-contracts/VPContract/#fn_delegatesofat_ed475a79","text":"Defined in VPContract ( Docs , Source ). function delegatesOfAt ( address _owner , uint256 _blockNumber ) public view returns ( address [] _delegateAddresses , uint256 [] _bips , uint256 _count , uint256 _delegationMode ); Get the percentages and addresses being delegated to by a vote power delegator, at a given block. Parameters Type Description _owner address The address of the delegator being queried. _blockNumber uint256 The block number being queried. Returns Type Description _delegateAddresses address[] Array of delegatee addresses. _bips uint256[] Array of delegation percents specified in basis points (1/100 or 1 percent), for each delegatee. _count uint256 The number of returned delegatees. _delegationMode uint256 The mode of the delegation (NOTSET=0, PERCENTAGE=1, AMOUNT=2). See Delegatable .DelegationMode.","title":"delegatesOfAt"},{"location":"apis/smart-contracts/VPContract/#fn_delegationmodeof_f6837767","text":"Defined in VPContract ( Docs , Source ). function delegationModeOf ( address _who ) external view returns ( uint256 ); Get the delegation mode of an address. This mode determines whether vote power is allocated by percentage or by explicit value and cannot be changed once set with delegate or delegateExplicit . Parameters Type Description _who address The address being queried. Returns Type Description [0] uint256 Delegation mode (NOTSET=0, PERCENTAGE=1, AMOUNT=2). See Delegatable .DelegationMode.","title":"delegationModeOf"},{"location":"apis/smart-contracts/VPContract/#fn_explicitdelegationhistorycleanup_cabc4528","text":"Defined in Delegatable ( Docs , Source ). function explicitDelegationHistoryCleanup ( address _from , address _to , uint256 _count ) external returns ( uint256 ); Delete explicit delegation checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _from address Delegator address. _to address Delegatee address. _count uint256 Maximum number of checkpoints to delete. Returns Type Description [0] uint256 Number of checkpoints deleted.","title":"explicitDelegationHistoryCleanup"},{"location":"apis/smart-contracts/VPContract/#fn_isreplacement_aa94d3f2","text":"Defined in IIVPContract ( Docs , Source ). function isReplacement ( ) external view returns ( bool ); Return true if this IIVPContract is configured to be used as a replacement for other contract. It means that vote powers are not necessarily correct at the initialization, therefore every method that reads vote power must check whether it is initialized for that address and block.","title":"isReplacement"},{"location":"apis/smart-contracts/VPContract/#fn_ownertoken_65371883","text":"Defined in IIVPContract ( Docs , Source ). function ownerToken ( ) external view returns ( contract IVPToken ); The VPToken (or some other contract) that owns this VPContract . All state changing methods may be called only from this address. This is because original msg.sender is typically sent in a parameter and we must make sure that it cannot be faked by directly calling IIVPContract methods. Owner token is also used in case of replacement to recover vote powers from balances.","title":"ownerToken"},{"location":"apis/smart-contracts/VPContract/#fn_percentagedelegationhistorycleanup_7f57d58f","text":"Defined in Delegatable ( Docs , Source ). function percentageDelegationHistoryCleanup ( address _owner , uint256 _count ) external returns ( uint256 ); Delete percentage delegation checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _owner address Balance owner account address. _count uint256 Maximum number of checkpoints to delete. Returns Type Description [0] uint256 Number of deleted checkpoints.","title":"percentageDelegationHistoryCleanup"},{"location":"apis/smart-contracts/VPContract/#fn_revocationcleanup_8c0b6b40","text":"Defined in Delegatable ( Docs , Source ). function revocationCleanup ( address _from , address _to , uint256 _blockNumber ) external returns ( uint256 ); Delete revocation entry that expired (i.e. is before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _from address Delegator address. _to address Delegatee address. _blockNumber uint256 Block number for which total supply value was cached. Returns Type Description [0] uint256 Number of revocation entries deleted (always 0 or 1).","title":"revocationCleanup"},{"location":"apis/smart-contracts/VPContract/#fn_revokedelegationat_c7c62fab","text":"Defined in VPContract ( Docs , Source ). function revokeDelegationAt ( address _from , address _to , uint256 _balance , uint256 _blockNumber ) external ; Revoke all vote power delegation from a delegator address to a delegatee address at a given block. Only affects the reads via votePowerOfAtCached in the block _blockNumber . This method should be used only to prevent rogue delegate voting in the current voting block. To stop delegating use delegate or delegateExplicit with value of 0, or undelegateAll / undelegateAllExplicit . Parameters Type Description _from address The address of the delegator. _to address Address of the delegatee. _balance uint256 The delegator's current balance. _blockNumber uint256 The block number at which to revoke delegation. Must be in the past.","title":"revokeDelegationAt"},{"location":"apis/smart-contracts/VPContract/#fn_setcleanercontract_f6a494af","text":"Defined in VPContract ( Docs , Source ). function setCleanerContract ( address _cleanerContract ) external ; Set the contract that is allowed to call history cleaning methods. Parameters Type Description _cleanerContract address Address of the cleanup contract. Usually this will be an instance of CleanupBlockNumberManager .","title":"setCleanerContract"},{"location":"apis/smart-contracts/VPContract/#fn_setcleanupblocknumber_13de97f5","text":"Defined in VPContract ( Docs , Source ). function setCleanupBlockNumber ( uint256 _blockNumber ) external ; Set the cleanup block number. Historic data for the blocks before cleanupBlockNumber can be erased. History before that block should never be used since it can be inconsistent. In particular, cleanup block number must be lower than the current vote power block. The method can be called only by the owner token. Parameters Type Description _blockNumber uint256 The new cleanup block number.","title":"setCleanupBlockNumber"},{"location":"apis/smart-contracts/VPContract/#fn_undelegateall_05109ecf","text":"Defined in VPContract ( Docs , Source ). function undelegateAll ( address _from , uint256 _balance ) external ; Undelegate all voting power for a delegator address. Can only be used with percentage delegation. Does not reset delegation mode back to NOTSET . Parameters Type Description _from address The address of the delegator. _balance uint256 The delegator's current balance.","title":"undelegateAll"},{"location":"apis/smart-contracts/VPContract/#fn_undelegateallexplicit_0f8b8af7","text":"Defined in VPContract ( Docs , Source ). function undelegateAllExplicit ( address _from , address [] _delegateAddresses ) external returns ( uint256 ); Undelegate all explicit vote power by amount for a delegator address. Can only be used with explicit delegation. Does not reset delegation mode back to NOTSET . Parameters Type Description _from address The address of the delegator. _delegateAddresses address[] Explicit delegation does not store delegatees' addresses, so the caller must supply them. Returns Type Description [0] uint256 The amount still delegated (in case the list of delegates was incomplete).","title":"undelegateAllExplicit"},{"location":"apis/smart-contracts/VPContract/#fn_undelegatedvotepowerof_4a03d556","text":"Defined in VPContract ( Docs , Source ). function undelegatedVotePowerOf ( address _owner , uint256 _balance ) external view returns ( uint256 ); Compute the current undelegated vote power of an address. Parameters Type Description _owner address The address being queried. _balance uint256 Current balance of that address. Returns Type Description [0] uint256 The unallocated vote power of _owner , this is, the amount of vote power currently not being delegated to other addresses.","title":"undelegatedVotePowerOf"},{"location":"apis/smart-contracts/VPContract/#fn_undelegatedvotepowerofat_31503927","text":"Defined in VPContract ( Docs , Source ). function undelegatedVotePowerOfAt ( address _owner , uint256 _balance , uint256 _blockNumber ) external view returns ( uint256 ); Compute the undelegated vote power of an address at a given block. Parameters Type Description _owner address The address being queried. _balance uint256 _blockNumber uint256 The block number being queried. Returns Type Description [0] uint256 The unallocated vote power of _owner , this is, the amount of vote power that was not being delegated to other addresses at that block number.","title":"undelegatedVotePowerOfAt"},{"location":"apis/smart-contracts/VPContract/#fn_updateattokentransfer_eadb4362","text":"Defined in VPContract ( Docs , Source ). function updateAtTokenTransfer ( address _from , address _to , uint256 _fromBalance , uint256 _toBalance , uint256 _amount ) external ; Update vote powers when tokens are transferred. Also update delegated vote powers for percentage delegation and check for enough funds for explicit delegations. Parameters Type Description _from address Source account of the transfer. _to address Destination account of the transfer. _fromBalance uint256 Balance of the source account before the transfer. _toBalance uint256 Balance of the destination account before the transfer. _amount uint256 Amount that has been transferred.","title":"updateAtTokenTransfer"},{"location":"apis/smart-contracts/VPContract/#fn_votepowercachecleanup_891339a8","text":"Defined in Delegatable ( Docs , Source ). function votePowerCacheCleanup ( address _owner , uint256 _blockNumber ) external returns ( uint256 ); Delete vote power cache entry that expired (i.e. is before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _owner address Vote power owner account address. _blockNumber uint256 Block number for which total supply value was cached. Returns Type Description [0] uint256 Number of deleted cache entries (always 0 or 1).","title":"votePowerCacheCleanup"},{"location":"apis/smart-contracts/VPContract/#fn_votepowerfromto_9dc6b9f2","text":"Defined in VPContract ( Docs , Source ). function votePowerFromTo ( address _from , address _to , uint256 _balance ) external view returns ( uint256 ); Get current delegated vote power from a delegator to a delegatee. Parameters Type Description _from address Address of the delegator. _to address Address of the delegatee. _balance uint256 The delegator's current balance. Returns Type Description [0] uint256 The delegated vote power.","title":"votePowerFromTo"},{"location":"apis/smart-contracts/VPContract/#fn_votepowerfromtoat_833aca92","text":"Defined in VPContract ( Docs , Source ). function votePowerFromToAt ( address _from , address _to , uint256 _balance , uint256 _blockNumber ) external view returns ( uint256 ); Get delegated the vote power from a delegator to a delegatee at a given block number. Parameters Type Description _from address Address of the delegator. _to address Address of the delegatee. _balance uint256 The delegator's current balance. _blockNumber uint256 The block number being queried. Returns Type Description [0] uint256 The delegated vote power.","title":"votePowerFromToAt"},{"location":"apis/smart-contracts/VPContract/#fn_votepowerhistorycleanup_1a05274c","text":"Defined in Delegatable ( Docs , Source ). function votePowerHistoryCleanup ( address _owner , uint256 _count ) external returns ( uint256 ); Delete vote power checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _owner address Vote power owner account address. _count uint256 Maximum number of checkpoints to delete. Returns Type Description [0] uint256 Number of deleted checkpoints.","title":"votePowerHistoryCleanup"},{"location":"apis/smart-contracts/VPContract/#fn_votepowerof_142d1018","text":"Defined in VPContract ( Docs , Source ). function votePowerOf ( address _who ) external view returns ( uint256 ); Get the current vote power of an address. Parameters Type Description _who address The address being queried. Returns Type Description [0] uint256 Current vote power of _who , including any delegation received.","title":"votePowerOf"},{"location":"apis/smart-contracts/VPContract/#fn_votepowerofat_92bfe6d8","text":"Defined in VPContract ( Docs , Source ). function votePowerOfAt ( address _who , uint256 _blockNumber ) public view returns ( uint256 ); Get the vote power of an address at a given block number Parameters Type Description _who address The address being queried. _blockNumber uint256 The block number being queried. Returns Type Description [0] uint256 Vote power of _who at _blockNumber , including any delegation received.","title":"votePowerOfAt"},{"location":"apis/smart-contracts/VPContract/#fn_votepowerofatcached_e587497e","text":"Defined in VPContract ( Docs , Source ). function votePowerOfAtCached ( address _who , uint256 _blockNumber ) external returns ( uint256 ); Get the vote power of an address at a given block number. Reads/updates cache and upholds revocations. Parameters Type Description _who address The address being queried. _blockNumber uint256 The block number being queried. Returns Type Description [0] uint256 Vote power of _who at _blockNumber , including any delegation received.","title":"votePowerOfAtCached"},{"location":"apis/smart-contracts/VPContract/#fn_votepowerofatignoringrevocation_04bb4e43","text":"Defined in VPContract ( Docs , Source ). function votePowerOfAtIgnoringRevocation ( address _who , uint256 _blockNumber ) external view returns ( uint256 ); Get the vote power of an address at a given block number, ignoring revocation information and cache. Parameters Type Description _who address The address being queried. _blockNumber uint256 The block number being queried. Returns Type Description [0] uint256 Vote power of _who at _blockNumber , including any delegation received. Result doesn't change if vote power is revoked.","title":"votePowerOfAtIgnoringRevocation"},{"location":"apis/smart-contracts/VPContract/#modifiers","text":"","title":"Modifiers"},{"location":"apis/smart-contracts/VPContract/#md_notbeforecleanupblock","text":"Defined in Delegatable ( Docs , Source ). modifier notBeforeCleanupBlock ( uint256 _blockNumber ) Reading from history is not allowed before cleanupBlockNumber , since data before that might have been deleted and is thus unreliable. Parameters Type Description _blockNumber uint256 The block number being checked for validity.","title":"notBeforeCleanupBlock"},{"location":"apis/smart-contracts/VPContract/#md_onlycleaner","text":"Defined in Delegatable ( Docs , Source ). modifier onlyCleaner () History cleaning methods can be called only from cleanerContract .","title":"onlyCleaner"},{"location":"apis/smart-contracts/VPContract/#md_onlyexplicit","text":"Defined in VPContract ( Docs , Source ). modifier onlyExplicit ( address sender ) If a delegate cannot be added by explicit amount, revert.","title":"onlyExplicit"},{"location":"apis/smart-contracts/VPContract/#md_onlyownertoken","text":"Defined in VPContract ( Docs , Source ). modifier onlyOwnerToken () All external methods in VPContract can only be executed by the owner token.","title":"onlyOwnerToken"},{"location":"apis/smart-contracts/VPContract/#md_onlypercent","text":"Defined in VPContract ( Docs , Source ). modifier onlyPercent ( address sender ) If a delegate cannot be added by percentage, revert.","title":"onlyPercent"},{"location":"apis/smart-contracts/VPContract/#variables","text":"","title":"Variables"},{"location":"apis/smart-contracts/VPContract/#va_cleanercontract","text":"Defined in Delegatable ( Docs , Source ). address cleanerContract Address of the contract that is allowed to call methods for history cleaning.","title":"cleanerContract"},{"location":"apis/smart-contracts/VPContract/#va_isreplacement","text":"Defined in VPContract ( Docs , Source ). bool isReplacement Return true if this IIVPContract is configured to be used as a replacement for other contract. It means that vote powers are not necessarily correct at the initialization, therefore every method that reads vote power must check whether it is initialized for that address and block.","title":"isReplacement"},{"location":"apis/smart-contracts/VPContract/#va_ownertoken","text":"Defined in VPContract ( Docs , Source ). contract IVPToken ownerToken The VPToken (or some other contract) that owns this VPContract . All state changing methods may be called only from this address. This is because original msg.sender is typically sent in a parameter and we must make sure that it cannot be faked by directly calling IIVPContract methods. Owner token is also used in case of replacement to recover vote powers from balances.","title":"ownerToken"},{"location":"apis/smart-contracts/VPToken/","text":"VPToken # Source | Inherits from IIVPToken , ERC20, CheckPointable , Governed Vote power token. An ERC20 token that enables the holder to delegate a voting power equal to their balance, with history tracking by block height. Actual vote power and delegation functionality is implemented in an associated VPContract . Events # Approval # Defined in IERC20 ( Source ). event Approval ( address owner , address spender , uint256 value ) Emitted when the allowance of a spender for an owner is set by a call to approve . value is the new allowance . CreatedTotalSupplyCache # Defined in CheckPointable ( Docs , Source ). event CreatedTotalSupplyCache ( uint256 _blockNumber ) Emitted when a total supply cache entry is created. Allows history cleaners to track total supply cache cleanup opportunities off-chain. GovernanceCallTimelocked # Defined in GovernedBase ( Docs , Source ). event GovernanceCallTimelocked ( bytes4 selector , uint256 allowedAfterTimestamp , bytes encodedCall ) Emitted when a new governance call has been recorded and is now waiting for the time lock to expire. GovernanceInitialised # Defined in GovernedBase ( Docs , Source ). event GovernanceInitialised ( address initialGovernance ) Emitted when the governance address is initialized. This address will be used until production mode is entered (see GovernedProductionModeEntered ). At that point the governance address is taken from GovernanceSettings . GovernedProductionModeEntered # Defined in GovernedBase ( Docs , Source ). event GovernedProductionModeEntered ( address governanceSettings ) Emitted when governance is enabled and the governance address cannot be changed anymore (only through a network fork). TimelockedGovernanceCallCanceled # Defined in GovernedBase ( Docs , Source ). event TimelockedGovernanceCallCanceled ( bytes4 selector , uint256 timestamp ) Emitted when a timelocked governance call is canceled before execution. TimelockedGovernanceCallExecuted # Defined in GovernedBase ( Docs , Source ). event TimelockedGovernanceCallExecuted ( bytes4 selector , uint256 timestamp ) Emitted when a timelocked governance call is executed. Transfer # Defined in IERC20 ( Source ). event Transfer ( address from , address to , uint256 value ) Emitted when value tokens are moved from one account ( from ) to another ( to ). Note that value may be zero. VotePowerContractChanged # Defined in VPToken ( Docs , Source ). event VotePowerContractChanged ( uint256 _contractType , address _oldContractAddress , address _newContractAddress ) Emitted when one of the vote power contracts is changed. It is used to track the history of VPToken -> VPContract / GovernanceVotePower associations (e.g. by external cleaners). Parameters Type Description _contractType uint256 0 = Read VPContract , 1 = Write VPContract , 2 = Governance vote power. _oldContractAddress address Contract address before change. _newContractAddress address Contract address after change. Functions # allowance # Defined in IERC20 ( Source ). function allowance ( address owner , address spender ) external view returns ( uint256 ); Returns the remaining number of tokens that spender will be allowed to spend on behalf of owner through transferFrom . This is zero by default. This value changes when approve or transferFrom are called. approve # Defined in IERC20 ( Source ). function approve ( address spender , uint256 amount ) external returns ( bool ); Sets amount as the allowance of spender over the caller's tokens. Returns a boolean value indicating whether the operation succeeded. IMPORTANT: Beware that changing an allowance with this method brings the risk that someone may use both the old and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 Emits an Approval event. balanceHistoryCleanup # Defined in CheckPointable ( Docs , Source ). function balanceHistoryCleanup ( address _owner , uint256 _count ) external returns ( uint256 ); Delete balance checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _owner address balance owner account address _count uint256 maximum number of checkpoints to delete Returns Type Description [0] uint256 the number of checkpoints deleted balanceOf # Defined in IERC20 ( Source ). function balanceOf ( address account ) external view returns ( uint256 ); Returns the amount of tokens owned by account . balanceOfAt # Defined in VPToken ( Docs , Source ). function balanceOfAt ( address _owner , uint256 _blockNumber ) public view returns ( uint256 ); Queries the token balance of _owner at a specific _blockNumber . Parameters Type Description _owner address The address from which the balance will be retrieved. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 batchDelegate # Defined in VPToken ( Docs , Source ). function batchDelegate ( address [] _delegatees , uint256 [] _bips ) external ; Undelegate all percentage delegations from the sender and then delegate corresponding _bips percentage of voting power from the sender to each member of the _delegatees array. Parameters Type Description _delegatees address[] The addresses of the new recipients. _bips uint256[] The percentages of voting power to be delegated expressed in basis points (1/100 of one percent). The sum of all _bips values must be at most 10000 (100%). batchVotePowerOfAt # Defined in VPToken ( Docs , Source ). function batchVotePowerOfAt ( address [] _owners , uint256 _blockNumber ) external view returns ( uint256 []); Return the vote power for several addresses. Parameters Type Description _owners address[] The list of addresses to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256[] Array of vote power for each queried address. cancelGovernanceCall # Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector. cleanupBlockNumber # Defined in VPToken ( Docs , Source ). function cleanupBlockNumber ( ) external view returns ( uint256 ); Get the current cleanup block number set with setCleanupBlockNumber . Returns Type Description [0] uint256 The currently set cleanup block number. constructor # Defined in VPToken ( Docs , Source ). constructor ( address _governance , string _name , string _symbol ) public ; constructor # Defined in Governed ( Docs , Source ). constructor ( address _governance ) public ; Parameters Type Description _governance address Governance contract. Must not be zero. constructor # Defined in ERC20 ( Source ). constructor ( string name_ , string symbol_ ) public ; Sets the values for name and symbol , initializes decimals with a default value of 18. To select a different value for decimals , use _setupDecimals. All three of these values are immutable: they can only be set once during construction. decimals # Defined in VPToken ( Docs , Source ). function decimals ( ) public view returns ( uint8 ); Returns the number of decimals used to get its user representation. For example, if decimals equals 2, a balance of 505 tokens should be displayed to a user as 5.05 (505 / 10 2 ). Tokens usually opt for a value of 18, imitating the relationship between Ether and wei. This is the default value returned by this function, unless it's overridden. NOTE: This information is only used for display purposes: it in no way affects any of the arithmetic of the contract, including balanceOf and transfer . Should be compatible with ERC20 method. delegate # Defined in VPToken ( Docs , Source ). function delegate ( address _to , uint256 _bips ) external ; Delegate voting power to account _to from msg.sender , by percentage. Parameters Type Description _to address The address of the recipient. _bips uint256 The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: every call resets the delegation value (and a value of 0 revokes all previous delegations). delegateExplicit # Defined in VPToken ( Docs , Source ). function delegateExplicit ( address _to , uint256 _amount ) external ; Explicitly delegate _amount voting power to account _to from msg.sender . Compare with delegate which delegates by percentage. Parameters Type Description _to address The address of the recipient. _amount uint256 An explicit vote power amount to be delegated. Not cumulative: every call resets the delegation value (and a value of 0 revokes all previous delegations). delegatesOf # Defined in VPToken ( Docs , Source ). function delegatesOf ( address _owner ) external view returns ( address [] _delegateAddresses , uint256 [] _bips , uint256 _count , uint256 _delegationMode ); Get the list of addresses to which _who is delegating, and their percentages. Parameters Type Description _owner address Returns Type Description _delegateAddresses address[] Positional array of addresses being delegated to. _bips uint256[] Positional array of delegation percents specified in basis points (1/100 of 1 percent). Each one matches the address in the same position in the _delegateAddresses array. _count uint256 The number of delegates. _delegationMode uint256 Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit). delegatesOfAt # Defined in VPToken ( Docs , Source ). function delegatesOfAt ( address _owner , uint256 _blockNumber ) external view returns ( address [] _delegateAddresses , uint256 [] _bips , uint256 _count , uint256 _delegationMode ); Get the list of addresses to which _who is delegating, and their percentages, at the given block. Parameters Type Description _owner address _blockNumber uint256 The block number to query. Returns Type Description _delegateAddresses address[] Positional array of addresses being delegated to. _bips uint256[] Positional array of delegation percents specified in basis points (1/100 of 1 percent). Each one matches the address in the same position in the _delegateAddresses array. _count uint256 The number of delegates. _delegationMode uint256 Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit). delegationModeOf # Defined in VPToken ( Docs , Source ). function delegationModeOf ( address _who ) external view returns ( uint256 ); Get the delegation mode for account '_who'. This mode determines whether vote power is allocated by percentage or by explicit amount. Once the delegation mode is set, it can never be changed, even if all delegations are removed. Parameters Type Description _who address The address to get delegation mode. Returns Type Description [0] uint256 Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit). executeGovernanceCall # Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored). governance # Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address. governanceVotePower # Defined in VPToken ( Docs , Source ). function governanceVotePower ( ) external view returns ( contract IGovernanceVotePower ); When set, allows token owners to participate in governance voting and delegate governance vote power. name # Defined in VPToken ( Docs , Source ). function name ( ) public view returns ( string ); Returns the name of the token. Should be compatible with ERC20 method. readVotePowerContract # Defined in VPToken ( Docs , Source ). function readVotePowerContract ( ) external view returns ( contract IVPContractEvents ); Returns VPContract event interface used for read-only operations (view methods). The only non-view method that might be called on it is revokeDelegationAt . readVotePowerContract is almost always equal to writeVotePowerContract except during an upgrade from one VPContract to a new version (which should happen rarely or never and will be announced beforehand). Do not call any methods on VPContract directly. State changing methods are forbidden from direct calls. All methods are exposed via VPToken . This is the reason that this method returns IVPContractEvents . Use it only for listening to events and revoking. revokeDelegationAt # Defined in VPToken ( Docs , Source ). function revokeDelegationAt ( address _who , uint256 _blockNumber ) public ; Revoke all delegation from sender to _who at given block. Only affects the reads via votePowerOfAtCached in the block _blockNumber . Block _blockNumber must be in the past. This method should be used only to prevent rogue delegate voting in the current voting block. To stop delegating use delegate / delegateExplicit with value of 0 or undelegateAll / undelegateAllExplicit . Parameters Type Description _who address Address of the delegatee. _blockNumber uint256 The block number at which to revoke delegation.. setCleanerContract # Defined in VPToken ( Docs , Source ). function setCleanerContract ( address _cleanerContract ) external ; Set the contract that is allowed to call history cleaning methods. Parameters Type Description _cleanerContract address Address of the cleanup contract. Usually this will be an instance of CleanupBlockNumberManager . setCleanupBlockNumber # Defined in VPToken ( Docs , Source ). function setCleanupBlockNumber ( uint256 _blockNumber ) external ; Set the cleanup block number. Historic data for the blocks before cleanupBlockNumber can be erased. History before that block should never be used since it can be inconsistent. In particular, cleanup block number must be lower than the current vote power block. Parameters Type Description _blockNumber uint256 The new cleanup block number. setCleanupBlockNumberManager # Defined in VPToken ( Docs , Source ). function setCleanupBlockNumberManager ( address _cleanupBlockNumberManager ) external ; Set the contract that is allowed to set cleanupBlockNumber . Usually this will be an instance of CleanupBlockNumberManager . setGovernanceVotePower # Defined in VPToken ( Docs , Source ). function setGovernanceVotePower ( contract IIGovernanceVotePower _governanceVotePower ) external ; Sets new governance vote power contract that allows token owners to participate in governance voting and delegate governance vote power. setReadVpContract # Defined in VPToken ( Docs , Source ). function setReadVpContract ( contract IIVPContract _vpContract ) external ; Call from governance to set read VpContract on token, e.g. vpToken. setReadVpContract (new VPContract (vpToken)). Read VPContract must be set before any of the VPToken delegation or vote power reading methods are called, otherwise they will revert. NOTE : If readVpContract differs from writeVpContract all reads will be \"frozen\" and will not reflect changes (not even revokes; they may or may not reflect balance transfers). Parameters Type Description _vpContract contract IIVPContract Read vote power contract to be used by this token. setWriteVpContract # Defined in VPToken ( Docs , Source ). function setWriteVpContract ( contract IIVPContract _vpContract ) external ; Call from governance to set write VpContract on token, e.g. vpToken. setWriteVpContract (new VPContract (vpToken)). Write VPContract must be set before any of the VPToken delegation modifying methods are called, otherwise they will revert. Parameters Type Description _vpContract contract IIVPContract Write vote power contract to be used by this token. switchToProductionMode # Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered . symbol # Defined in VPToken ( Docs , Source ). function symbol ( ) public view returns ( string ); Returns the symbol of the token, usually a shorter version of the name . Should be compatible with ERC20 method. totalSupply # Defined in IERC20 ( Source ). function totalSupply ( ) external view returns ( uint256 ); Returns the amount of tokens in existence. totalSupplyAt # Defined in VPToken ( Docs , Source ). function totalSupplyAt ( uint256 _blockNumber ) public view returns ( uint256 ); Total amount of tokens at a specific _blockNumber . Parameters Type Description _blockNumber uint256 The block number when the _totalSupply is queried Returns Type Description [0] uint256 totalSupplyCacheCleanup # Defined in CheckPointable ( Docs , Source ). function totalSupplyCacheCleanup ( uint256 _blockNumber ) external returns ( uint256 ); Delete total supply cache entry that expired (i.e. is before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _blockNumber uint256 the block number for which total supply value was cached Returns Type Description [0] uint256 the number of cache entries deleted (always 0 or 1) totalSupplyHistoryCleanup # Defined in CheckPointable ( Docs , Source ). function totalSupplyHistoryCleanup ( uint256 _count ) external returns ( uint256 ); Delete total supply checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _count uint256 maximum number of checkpoints to delete Returns Type Description [0] uint256 the number of checkpoints deleted totalVotePower # Defined in VPToken ( Docs , Source ). function totalVotePower ( ) external view returns ( uint256 ); Get the current total vote power. Returns Type Description [0] uint256 The current total vote power (sum of all accounts' vote power). totalVotePowerAt # Defined in VPToken ( Docs , Source ). function totalVotePowerAt ( uint256 _blockNumber ) external view returns ( uint256 ); Get the total vote power at block _blockNumber . Parameters Type Description _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The total vote power at the queried block (sum of all accounts' vote powers). totalVotePowerAtCached # Defined in VPToken ( Docs , Source ). function totalVotePowerAtCached ( uint256 _blockNumber ) public returns ( uint256 ); Get the total vote power at block _blockNumber using cache. It tries to read the cached value and if it is not found, reads the actual value and stores it in the cache. Can only be used if _blockNumber is in the past, otherwise reverts. Parameters Type Description _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The total vote power at the queried block (sum of all accounts' vote powers). transfer # Defined in IERC20 ( Source ). function transfer ( address recipient , uint256 amount ) external returns ( bool ); Moves amount tokens from the caller's account to recipient . Returns a boolean value indicating whether the operation succeeded. Emits a Transfer event. transferFrom # Defined in IERC20 ( Source ). function transferFrom ( address sender , address recipient , uint256 amount ) external returns ( bool ); Moves amount tokens from sender to recipient using the allowance mechanism. amount is then deducted from the caller's allowance . Returns a boolean value indicating whether the operation succeeded. Emits a Transfer event. undelegateAll # Defined in VPToken ( Docs , Source ). function undelegateAll ( ) external ; Undelegate all voting power of msg.sender . This effectively revokes all previous delegations. Can only be used with percentage delegation. Does not reset delegation mode back to NOT SET. undelegateAllExplicit # Defined in VPToken ( Docs , Source ). function undelegateAllExplicit ( address [] _delegateAddresses ) external returns ( uint256 _remainingDelegation ); Undelegate all explicit vote power by amount of msg.sender . Can only be used with explicit delegation. Does not reset delegation mode back to NOT SET. Parameters Type Description _delegateAddresses address[] Explicit delegation does not store delegatees' addresses, so the caller must supply them. Returns Type Description _remainingDelegation uint256 The amount still delegated (in case the list of delegates was incomplete). undelegatedVotePowerOf # Defined in VPToken ( Docs , Source ). function undelegatedVotePowerOf ( address _owner ) external view returns ( uint256 ); Compute the current undelegated vote power of the _owner account. Parameters Type Description _owner address The address to query. Returns Type Description [0] uint256 The unallocated vote power of _owner . undelegatedVotePowerOfAt # Defined in VPToken ( Docs , Source ). function undelegatedVotePowerOfAt ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Get the undelegated vote power of the _owner account at a given block number. Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The unallocated vote power of _owner . votePowerFromTo # Defined in VPToken ( Docs , Source ). function votePowerFromTo ( address _from , address _to ) external view returns ( uint256 ); Get current delegated vote power from delegator _from to delegatee _to . Parameters Type Description _from address Address of delegator. _to address Address of delegatee. Returns Type Description [0] uint256 votePower The delegated vote power. votePowerFromToAt # Defined in VPToken ( Docs , Source ). function votePowerFromToAt ( address _from , address _to , uint256 _blockNumber ) external view returns ( uint256 ); Get delegated vote power from delegator _from to delegatee _to at _blockNumber . Parameters Type Description _from address Address of delegator. _to address Address of delegatee. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The delegated vote power. votePowerOf # Defined in VPToken ( Docs , Source ). function votePowerOf ( address _owner ) external view returns ( uint256 ); Get the current vote power of _owner . Parameters Type Description _owner address The address to query. Returns Type Description [0] uint256 Current vote power of _owner . votePowerOfAt # Defined in VPToken ( Docs , Source ). function votePowerOfAt ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Get the vote power of _owner at block _blockNumber Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 Vote power of _owner at block number _blockNumber . votePowerOfAtCached # Defined in VPToken ( Docs , Source ). function votePowerOfAtCached ( address _owner , uint256 _blockNumber ) public returns ( uint256 ); Get the vote power of _owner at block _blockNumber using cache. It tries to read the cached value and if it is not found, reads the actual value and stores it in the cache. Can only be used if _blockNumber is in the past, otherwise reverts. Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 Vote power of _owner at _blockNumber . votePowerOfAtIgnoringRevocation # Defined in VPToken ( Docs , Source ). function votePowerOfAtIgnoringRevocation ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Get the vote power of _owner at block _blockNumber , ignoring revocation information (and cache). Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 Vote power of _owner at block number _blockNumber . Result doesn't change if vote power is revoked. writeVotePowerContract # Defined in VPToken ( Docs , Source ). function writeVotePowerContract ( ) external view returns ( contract IVPContractEvents ); Returns VPContract event interface used for state-changing operations (non-view methods). The only non-view method that might be called on it is revokeDelegationAt . writeVotePowerContract is almost always equal to readVotePowerContract , except during upgrade from one VPContract to a new version (which should happen rarely or never and will be announced beforehand). In the case of an upgrade, writeVotePowerContract is replaced first to establish delegations. After some period (e.g., after a reward epoch ends), readVotePowerContract is set equal to it. Do not call any methods on VPContract directly. State changing methods are forbidden from direct calls. All are exposed via VPToken . This is the reason that this method returns IVPContractEvents Use it only for listening to events, delegating, and revoking. Variables # cleanerContract # Defined in CheckPointable ( Docs , Source ). address cleanerContract Address of the contract that is allowed to call methods for history cleaning. cleanupBlockNumberManager # Defined in VPToken ( Docs , Source ). address cleanupBlockNumberManager The contract that is allowed to set cleanupBlockNumber . Usually this will be an instance of CleanupBlockNumberManager . governanceSettings # Defined in GovernedBase ( Docs , Source ). contract IGovernanceSettings governanceSettings Governance Settings. productionMode # Defined in GovernedBase ( Docs , Source ). bool productionMode When true, governance is enabled and cannot be disabled. See switchToProductionMode . timelockedCalls # Defined in GovernedBase ( Docs , Source ). mapping ( bytes4 => struct GovernedBase . TimelockedCall ) timelockedCalls List of pending timelocked governance calls. vpContractInitialized # Defined in VPToken ( Docs , Source ). bool vpContractInitialized When true, the argument to setWriteVpContract must be a vpContract with isReplacement set to true . To be used for creating the correct VPContract .","title":"VPToken"},{"location":"apis/smart-contracts/VPToken/#ct_vptoken","text":"Source | Inherits from IIVPToken , ERC20, CheckPointable , Governed Vote power token. An ERC20 token that enables the holder to delegate a voting power equal to their balance, with history tracking by block height. Actual vote power and delegation functionality is implemented in an associated VPContract .","title":"VPToken"},{"location":"apis/smart-contracts/VPToken/#events","text":"","title":"Events"},{"location":"apis/smart-contracts/VPToken/#ev_approval","text":"Defined in IERC20 ( Source ). event Approval ( address owner , address spender , uint256 value ) Emitted when the allowance of a spender for an owner is set by a call to approve . value is the new allowance .","title":"Approval"},{"location":"apis/smart-contracts/VPToken/#ev_createdtotalsupplycache","text":"Defined in CheckPointable ( Docs , Source ). event CreatedTotalSupplyCache ( uint256 _blockNumber ) Emitted when a total supply cache entry is created. Allows history cleaners to track total supply cache cleanup opportunities off-chain.","title":"CreatedTotalSupplyCache"},{"location":"apis/smart-contracts/VPToken/#ev_governancecalltimelocked","text":"Defined in GovernedBase ( Docs , Source ). event GovernanceCallTimelocked ( bytes4 selector , uint256 allowedAfterTimestamp , bytes encodedCall ) Emitted when a new governance call has been recorded and is now waiting for the time lock to expire.","title":"GovernanceCallTimelocked"},{"location":"apis/smart-contracts/VPToken/#ev_governanceinitialised","text":"Defined in GovernedBase ( Docs , Source ). event GovernanceInitialised ( address initialGovernance ) Emitted when the governance address is initialized. This address will be used until production mode is entered (see GovernedProductionModeEntered ). At that point the governance address is taken from GovernanceSettings .","title":"GovernanceInitialised"},{"location":"apis/smart-contracts/VPToken/#ev_governedproductionmodeentered","text":"Defined in GovernedBase ( Docs , Source ). event GovernedProductionModeEntered ( address governanceSettings ) Emitted when governance is enabled and the governance address cannot be changed anymore (only through a network fork).","title":"GovernedProductionModeEntered"},{"location":"apis/smart-contracts/VPToken/#ev_timelockedgovernancecallcanceled","text":"Defined in GovernedBase ( Docs , Source ). event TimelockedGovernanceCallCanceled ( bytes4 selector , uint256 timestamp ) Emitted when a timelocked governance call is canceled before execution.","title":"TimelockedGovernanceCallCanceled"},{"location":"apis/smart-contracts/VPToken/#ev_timelockedgovernancecallexecuted","text":"Defined in GovernedBase ( Docs , Source ). event TimelockedGovernanceCallExecuted ( bytes4 selector , uint256 timestamp ) Emitted when a timelocked governance call is executed.","title":"TimelockedGovernanceCallExecuted"},{"location":"apis/smart-contracts/VPToken/#ev_transfer","text":"Defined in IERC20 ( Source ). event Transfer ( address from , address to , uint256 value ) Emitted when value tokens are moved from one account ( from ) to another ( to ). Note that value may be zero.","title":"Transfer"},{"location":"apis/smart-contracts/VPToken/#ev_votepowercontractchanged","text":"Defined in VPToken ( Docs , Source ). event VotePowerContractChanged ( uint256 _contractType , address _oldContractAddress , address _newContractAddress ) Emitted when one of the vote power contracts is changed. It is used to track the history of VPToken -> VPContract / GovernanceVotePower associations (e.g. by external cleaners). Parameters Type Description _contractType uint256 0 = Read VPContract , 1 = Write VPContract , 2 = Governance vote power. _oldContractAddress address Contract address before change. _newContractAddress address Contract address after change.","title":"VotePowerContractChanged"},{"location":"apis/smart-contracts/VPToken/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/VPToken/#fn_allowance_dd62ed3e","text":"Defined in IERC20 ( Source ). function allowance ( address owner , address spender ) external view returns ( uint256 ); Returns the remaining number of tokens that spender will be allowed to spend on behalf of owner through transferFrom . This is zero by default. This value changes when approve or transferFrom are called.","title":"allowance"},{"location":"apis/smart-contracts/VPToken/#fn_approve_095ea7b3","text":"Defined in IERC20 ( Source ). function approve ( address spender , uint256 amount ) external returns ( bool ); Sets amount as the allowance of spender over the caller's tokens. Returns a boolean value indicating whether the operation succeeded. IMPORTANT: Beware that changing an allowance with this method brings the risk that someone may use both the old and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 Emits an Approval event.","title":"approve"},{"location":"apis/smart-contracts/VPToken/#fn_balancehistorycleanup_f0e292c9","text":"Defined in CheckPointable ( Docs , Source ). function balanceHistoryCleanup ( address _owner , uint256 _count ) external returns ( uint256 ); Delete balance checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _owner address balance owner account address _count uint256 maximum number of checkpoints to delete Returns Type Description [0] uint256 the number of checkpoints deleted","title":"balanceHistoryCleanup"},{"location":"apis/smart-contracts/VPToken/#fn_balanceof_70a08231","text":"Defined in IERC20 ( Source ). function balanceOf ( address account ) external view returns ( uint256 ); Returns the amount of tokens owned by account .","title":"balanceOf"},{"location":"apis/smart-contracts/VPToken/#fn_balanceofat_4ee2cd7e","text":"Defined in VPToken ( Docs , Source ). function balanceOfAt ( address _owner , uint256 _blockNumber ) public view returns ( uint256 ); Queries the token balance of _owner at a specific _blockNumber . Parameters Type Description _owner address The address from which the balance will be retrieved. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256","title":"balanceOfAt"},{"location":"apis/smart-contracts/VPToken/#fn_batchdelegate_dc4fcda7","text":"Defined in VPToken ( Docs , Source ). function batchDelegate ( address [] _delegatees , uint256 [] _bips ) external ; Undelegate all percentage delegations from the sender and then delegate corresponding _bips percentage of voting power from the sender to each member of the _delegatees array. Parameters Type Description _delegatees address[] The addresses of the new recipients. _bips uint256[] The percentages of voting power to be delegated expressed in basis points (1/100 of one percent). The sum of all _bips values must be at most 10000 (100%).","title":"batchDelegate"},{"location":"apis/smart-contracts/VPToken/#fn_batchvotepowerofat_49e3c7e5","text":"Defined in VPToken ( Docs , Source ). function batchVotePowerOfAt ( address [] _owners , uint256 _blockNumber ) external view returns ( uint256 []); Return the vote power for several addresses. Parameters Type Description _owners address[] The list of addresses to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256[] Array of vote power for each queried address.","title":"batchVotePowerOfAt"},{"location":"apis/smart-contracts/VPToken/#fn_cancelgovernancecall_67fc4029","text":"Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector.","title":"cancelGovernanceCall"},{"location":"apis/smart-contracts/VPToken/#fn_cleanupblocknumber_deea13e7","text":"Defined in VPToken ( Docs , Source ). function cleanupBlockNumber ( ) external view returns ( uint256 ); Get the current cleanup block number set with setCleanupBlockNumber . Returns Type Description [0] uint256 The currently set cleanup block number.","title":"cleanupBlockNumber"},{"location":"apis/smart-contracts/VPToken/#fn_constructor_undefined","text":"Defined in VPToken ( Docs , Source ). constructor ( address _governance , string _name , string _symbol ) public ;","title":"constructor"},{"location":"apis/smart-contracts/VPToken/#fn_constructor_undefined","text":"Defined in Governed ( Docs , Source ). constructor ( address _governance ) public ; Parameters Type Description _governance address Governance contract. Must not be zero.","title":"constructor"},{"location":"apis/smart-contracts/VPToken/#fn_constructor_undefined","text":"Defined in ERC20 ( Source ). constructor ( string name_ , string symbol_ ) public ; Sets the values for name and symbol , initializes decimals with a default value of 18. To select a different value for decimals , use _setupDecimals. All three of these values are immutable: they can only be set once during construction.","title":"constructor"},{"location":"apis/smart-contracts/VPToken/#fn_decimals_313ce567","text":"Defined in VPToken ( Docs , Source ). function decimals ( ) public view returns ( uint8 ); Returns the number of decimals used to get its user representation. For example, if decimals equals 2, a balance of 505 tokens should be displayed to a user as 5.05 (505 / 10 2 ). Tokens usually opt for a value of 18, imitating the relationship between Ether and wei. This is the default value returned by this function, unless it's overridden. NOTE: This information is only used for display purposes: it in no way affects any of the arithmetic of the contract, including balanceOf and transfer . Should be compatible with ERC20 method.","title":"decimals"},{"location":"apis/smart-contracts/VPToken/#fn_delegate_026e402b","text":"Defined in VPToken ( Docs , Source ). function delegate ( address _to , uint256 _bips ) external ; Delegate voting power to account _to from msg.sender , by percentage. Parameters Type Description _to address The address of the recipient. _bips uint256 The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: every call resets the delegation value (and a value of 0 revokes all previous delegations).","title":"delegate"},{"location":"apis/smart-contracts/VPToken/#fn_delegateexplicit_d06dc3ad","text":"Defined in VPToken ( Docs , Source ). function delegateExplicit ( address _to , uint256 _amount ) external ; Explicitly delegate _amount voting power to account _to from msg.sender . Compare with delegate which delegates by percentage. Parameters Type Description _to address The address of the recipient. _amount uint256 An explicit vote power amount to be delegated. Not cumulative: every call resets the delegation value (and a value of 0 revokes all previous delegations).","title":"delegateExplicit"},{"location":"apis/smart-contracts/VPToken/#fn_delegatesof_7de5b8ed","text":"Defined in VPToken ( Docs , Source ). function delegatesOf ( address _owner ) external view returns ( address [] _delegateAddresses , uint256 [] _bips , uint256 _count , uint256 _delegationMode ); Get the list of addresses to which _who is delegating, and their percentages. Parameters Type Description _owner address Returns Type Description _delegateAddresses address[] Positional array of addresses being delegated to. _bips uint256[] Positional array of delegation percents specified in basis points (1/100 of 1 percent). Each one matches the address in the same position in the _delegateAddresses array. _count uint256 The number of delegates. _delegationMode uint256 Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).","title":"delegatesOf"},{"location":"apis/smart-contracts/VPToken/#fn_delegatesofat_ed475a79","text":"Defined in VPToken ( Docs , Source ). function delegatesOfAt ( address _owner , uint256 _blockNumber ) external view returns ( address [] _delegateAddresses , uint256 [] _bips , uint256 _count , uint256 _delegationMode ); Get the list of addresses to which _who is delegating, and their percentages, at the given block. Parameters Type Description _owner address _blockNumber uint256 The block number to query. Returns Type Description _delegateAddresses address[] Positional array of addresses being delegated to. _bips uint256[] Positional array of delegation percents specified in basis points (1/100 of 1 percent). Each one matches the address in the same position in the _delegateAddresses array. _count uint256 The number of delegates. _delegationMode uint256 Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).","title":"delegatesOfAt"},{"location":"apis/smart-contracts/VPToken/#fn_delegationmodeof_f6837767","text":"Defined in VPToken ( Docs , Source ). function delegationModeOf ( address _who ) external view returns ( uint256 ); Get the delegation mode for account '_who'. This mode determines whether vote power is allocated by percentage or by explicit amount. Once the delegation mode is set, it can never be changed, even if all delegations are removed. Parameters Type Description _who address The address to get delegation mode. Returns Type Description [0] uint256 Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).","title":"delegationModeOf"},{"location":"apis/smart-contracts/VPToken/#fn_executegovernancecall_5ff27079","text":"Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored).","title":"executeGovernanceCall"},{"location":"apis/smart-contracts/VPToken/#fn_governance_5aa6e675","text":"Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address.","title":"governance"},{"location":"apis/smart-contracts/VPToken/#fn_governancevotepower_8c2b8ae1","text":"Defined in VPToken ( Docs , Source ). function governanceVotePower ( ) external view returns ( contract IGovernanceVotePower ); When set, allows token owners to participate in governance voting and delegate governance vote power.","title":"governanceVotePower"},{"location":"apis/smart-contracts/VPToken/#fn_name_06fdde03","text":"Defined in VPToken ( Docs , Source ). function name ( ) public view returns ( string ); Returns the name of the token. Should be compatible with ERC20 method.","title":"name"},{"location":"apis/smart-contracts/VPToken/#fn_readvotepowercontract_9b3baa0e","text":"Defined in VPToken ( Docs , Source ). function readVotePowerContract ( ) external view returns ( contract IVPContractEvents ); Returns VPContract event interface used for read-only operations (view methods). The only non-view method that might be called on it is revokeDelegationAt . readVotePowerContract is almost always equal to writeVotePowerContract except during an upgrade from one VPContract to a new version (which should happen rarely or never and will be announced beforehand). Do not call any methods on VPContract directly. State changing methods are forbidden from direct calls. All methods are exposed via VPToken . This is the reason that this method returns IVPContractEvents . Use it only for listening to events and revoking.","title":"readVotePowerContract"},{"location":"apis/smart-contracts/VPToken/#fn_revokedelegationat_bbd6fbf8","text":"Defined in VPToken ( Docs , Source ). function revokeDelegationAt ( address _who , uint256 _blockNumber ) public ; Revoke all delegation from sender to _who at given block. Only affects the reads via votePowerOfAtCached in the block _blockNumber . Block _blockNumber must be in the past. This method should be used only to prevent rogue delegate voting in the current voting block. To stop delegating use delegate / delegateExplicit with value of 0 or undelegateAll / undelegateAllExplicit . Parameters Type Description _who address Address of the delegatee. _blockNumber uint256 The block number at which to revoke delegation..","title":"revokeDelegationAt"},{"location":"apis/smart-contracts/VPToken/#fn_setcleanercontract_f6a494af","text":"Defined in VPToken ( Docs , Source ). function setCleanerContract ( address _cleanerContract ) external ; Set the contract that is allowed to call history cleaning methods. Parameters Type Description _cleanerContract address Address of the cleanup contract. Usually this will be an instance of CleanupBlockNumberManager .","title":"setCleanerContract"},{"location":"apis/smart-contracts/VPToken/#fn_setcleanupblocknumber_13de97f5","text":"Defined in VPToken ( Docs , Source ). function setCleanupBlockNumber ( uint256 _blockNumber ) external ; Set the cleanup block number. Historic data for the blocks before cleanupBlockNumber can be erased. History before that block should never be used since it can be inconsistent. In particular, cleanup block number must be lower than the current vote power block. Parameters Type Description _blockNumber uint256 The new cleanup block number.","title":"setCleanupBlockNumber"},{"location":"apis/smart-contracts/VPToken/#fn_setcleanupblocknumbermanager_7f4fcaa9","text":"Defined in VPToken ( Docs , Source ). function setCleanupBlockNumberManager ( address _cleanupBlockNumberManager ) external ; Set the contract that is allowed to set cleanupBlockNumber . Usually this will be an instance of CleanupBlockNumberManager .","title":"setCleanupBlockNumberManager"},{"location":"apis/smart-contracts/VPToken/#fn_setgovernancevotepower_9ca2231a","text":"Defined in VPToken ( Docs , Source ). function setGovernanceVotePower ( contract IIGovernanceVotePower _governanceVotePower ) external ; Sets new governance vote power contract that allows token owners to participate in governance voting and delegate governance vote power.","title":"setGovernanceVotePower"},{"location":"apis/smart-contracts/VPToken/#fn_setreadvpcontract_31d12a16","text":"Defined in VPToken ( Docs , Source ). function setReadVpContract ( contract IIVPContract _vpContract ) external ; Call from governance to set read VpContract on token, e.g. vpToken. setReadVpContract (new VPContract (vpToken)). Read VPContract must be set before any of the VPToken delegation or vote power reading methods are called, otherwise they will revert. NOTE : If readVpContract differs from writeVpContract all reads will be \"frozen\" and will not reflect changes (not even revokes; they may or may not reflect balance transfers). Parameters Type Description _vpContract contract IIVPContract Read vote power contract to be used by this token.","title":"setReadVpContract"},{"location":"apis/smart-contracts/VPToken/#fn_setwritevpcontract_755d10a4","text":"Defined in VPToken ( Docs , Source ). function setWriteVpContract ( contract IIVPContract _vpContract ) external ; Call from governance to set write VpContract on token, e.g. vpToken. setWriteVpContract (new VPContract (vpToken)). Write VPContract must be set before any of the VPToken delegation modifying methods are called, otherwise they will revert. Parameters Type Description _vpContract contract IIVPContract Write vote power contract to be used by this token.","title":"setWriteVpContract"},{"location":"apis/smart-contracts/VPToken/#fn_switchtoproductionmode_f5a98383","text":"Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered .","title":"switchToProductionMode"},{"location":"apis/smart-contracts/VPToken/#fn_symbol_95d89b41","text":"Defined in VPToken ( Docs , Source ). function symbol ( ) public view returns ( string ); Returns the symbol of the token, usually a shorter version of the name . Should be compatible with ERC20 method.","title":"symbol"},{"location":"apis/smart-contracts/VPToken/#fn_totalsupply_18160ddd","text":"Defined in IERC20 ( Source ). function totalSupply ( ) external view returns ( uint256 ); Returns the amount of tokens in existence.","title":"totalSupply"},{"location":"apis/smart-contracts/VPToken/#fn_totalsupplyat_981b24d0","text":"Defined in VPToken ( Docs , Source ). function totalSupplyAt ( uint256 _blockNumber ) public view returns ( uint256 ); Total amount of tokens at a specific _blockNumber . Parameters Type Description _blockNumber uint256 The block number when the _totalSupply is queried Returns Type Description [0] uint256","title":"totalSupplyAt"},{"location":"apis/smart-contracts/VPToken/#fn_totalsupplycachecleanup_43ea370b","text":"Defined in CheckPointable ( Docs , Source ). function totalSupplyCacheCleanup ( uint256 _blockNumber ) external returns ( uint256 ); Delete total supply cache entry that expired (i.e. is before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _blockNumber uint256 the block number for which total supply value was cached Returns Type Description [0] uint256 the number of cache entries deleted (always 0 or 1)","title":"totalSupplyCacheCleanup"},{"location":"apis/smart-contracts/VPToken/#fn_totalsupplyhistorycleanup_f62f8f3a","text":"Defined in CheckPointable ( Docs , Source ). function totalSupplyHistoryCleanup ( uint256 _count ) external returns ( uint256 ); Delete total supply checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _count uint256 maximum number of checkpoints to delete Returns Type Description [0] uint256 the number of checkpoints deleted","title":"totalSupplyHistoryCleanup"},{"location":"apis/smart-contracts/VPToken/#fn_totalvotepower_f5f3d4f7","text":"Defined in VPToken ( Docs , Source ). function totalVotePower ( ) external view returns ( uint256 ); Get the current total vote power. Returns Type Description [0] uint256 The current total vote power (sum of all accounts' vote power).","title":"totalVotePower"},{"location":"apis/smart-contracts/VPToken/#fn_totalvotepowerat_3e5aa26a","text":"Defined in VPToken ( Docs , Source ). function totalVotePowerAt ( uint256 _blockNumber ) external view returns ( uint256 ); Get the total vote power at block _blockNumber . Parameters Type Description _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The total vote power at the queried block (sum of all accounts' vote powers).","title":"totalVotePowerAt"},{"location":"apis/smart-contracts/VPToken/#fn_totalvotepoweratcached_caeb942b","text":"Defined in VPToken ( Docs , Source ). function totalVotePowerAtCached ( uint256 _blockNumber ) public returns ( uint256 ); Get the total vote power at block _blockNumber using cache. It tries to read the cached value and if it is not found, reads the actual value and stores it in the cache. Can only be used if _blockNumber is in the past, otherwise reverts. Parameters Type Description _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The total vote power at the queried block (sum of all accounts' vote powers).","title":"totalVotePowerAtCached"},{"location":"apis/smart-contracts/VPToken/#fn_transfer_a9059cbb","text":"Defined in IERC20 ( Source ). function transfer ( address recipient , uint256 amount ) external returns ( bool ); Moves amount tokens from the caller's account to recipient . Returns a boolean value indicating whether the operation succeeded. Emits a Transfer event.","title":"transfer"},{"location":"apis/smart-contracts/VPToken/#fn_transferfrom_23b872dd","text":"Defined in IERC20 ( Source ). function transferFrom ( address sender , address recipient , uint256 amount ) external returns ( bool ); Moves amount tokens from sender to recipient using the allowance mechanism. amount is then deducted from the caller's allowance . Returns a boolean value indicating whether the operation succeeded. Emits a Transfer event.","title":"transferFrom"},{"location":"apis/smart-contracts/VPToken/#fn_undelegateall_b302f393","text":"Defined in VPToken ( Docs , Source ). function undelegateAll ( ) external ; Undelegate all voting power of msg.sender . This effectively revokes all previous delegations. Can only be used with percentage delegation. Does not reset delegation mode back to NOT SET.","title":"undelegateAll"},{"location":"apis/smart-contracts/VPToken/#fn_undelegateallexplicit_5d6d11eb","text":"Defined in VPToken ( Docs , Source ). function undelegateAllExplicit ( address [] _delegateAddresses ) external returns ( uint256 _remainingDelegation ); Undelegate all explicit vote power by amount of msg.sender . Can only be used with explicit delegation. Does not reset delegation mode back to NOT SET. Parameters Type Description _delegateAddresses address[] Explicit delegation does not store delegatees' addresses, so the caller must supply them. Returns Type Description _remainingDelegation uint256 The amount still delegated (in case the list of delegates was incomplete).","title":"undelegateAllExplicit"},{"location":"apis/smart-contracts/VPToken/#fn_undelegatedvotepowerof_d6aa0b77","text":"Defined in VPToken ( Docs , Source ). function undelegatedVotePowerOf ( address _owner ) external view returns ( uint256 ); Compute the current undelegated vote power of the _owner account. Parameters Type Description _owner address The address to query. Returns Type Description [0] uint256 The unallocated vote power of _owner .","title":"undelegatedVotePowerOf"},{"location":"apis/smart-contracts/VPToken/#fn_undelegatedvotepowerofat_83035a82","text":"Defined in VPToken ( Docs , Source ). function undelegatedVotePowerOfAt ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Get the undelegated vote power of the _owner account at a given block number. Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The unallocated vote power of _owner .","title":"undelegatedVotePowerOfAt"},{"location":"apis/smart-contracts/VPToken/#fn_votepowerfromto_be0ca747","text":"Defined in VPToken ( Docs , Source ). function votePowerFromTo ( address _from , address _to ) external view returns ( uint256 ); Get current delegated vote power from delegator _from to delegatee _to . Parameters Type Description _from address Address of delegator. _to address Address of delegatee. Returns Type Description [0] uint256 votePower The delegated vote power.","title":"votePowerFromTo"},{"location":"apis/smart-contracts/VPToken/#fn_votepowerfromtoat_e64767aa","text":"Defined in VPToken ( Docs , Source ). function votePowerFromToAt ( address _from , address _to , uint256 _blockNumber ) external view returns ( uint256 ); Get delegated vote power from delegator _from to delegatee _to at _blockNumber . Parameters Type Description _from address Address of delegator. _to address Address of delegatee. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The delegated vote power.","title":"votePowerFromToAt"},{"location":"apis/smart-contracts/VPToken/#fn_votepowerof_142d1018","text":"Defined in VPToken ( Docs , Source ). function votePowerOf ( address _owner ) external view returns ( uint256 ); Get the current vote power of _owner . Parameters Type Description _owner address The address to query. Returns Type Description [0] uint256 Current vote power of _owner .","title":"votePowerOf"},{"location":"apis/smart-contracts/VPToken/#fn_votepowerofat_92bfe6d8","text":"Defined in VPToken ( Docs , Source ). function votePowerOfAt ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Get the vote power of _owner at block _blockNumber Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 Vote power of _owner at block number _blockNumber .","title":"votePowerOfAt"},{"location":"apis/smart-contracts/VPToken/#fn_votepowerofatcached_e587497e","text":"Defined in VPToken ( Docs , Source ). function votePowerOfAtCached ( address _owner , uint256 _blockNumber ) public returns ( uint256 ); Get the vote power of _owner at block _blockNumber using cache. It tries to read the cached value and if it is not found, reads the actual value and stores it in the cache. Can only be used if _blockNumber is in the past, otherwise reverts. Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 Vote power of _owner at _blockNumber .","title":"votePowerOfAtCached"},{"location":"apis/smart-contracts/VPToken/#fn_votepowerofatignoringrevocation_04bb4e43","text":"Defined in VPToken ( Docs , Source ). function votePowerOfAtIgnoringRevocation ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Get the vote power of _owner at block _blockNumber , ignoring revocation information (and cache). Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 Vote power of _owner at block number _blockNumber . Result doesn't change if vote power is revoked.","title":"votePowerOfAtIgnoringRevocation"},{"location":"apis/smart-contracts/VPToken/#fn_writevotepowercontract_1fec092a","text":"Defined in VPToken ( Docs , Source ). function writeVotePowerContract ( ) external view returns ( contract IVPContractEvents ); Returns VPContract event interface used for state-changing operations (non-view methods). The only non-view method that might be called on it is revokeDelegationAt . writeVotePowerContract is almost always equal to readVotePowerContract , except during upgrade from one VPContract to a new version (which should happen rarely or never and will be announced beforehand). In the case of an upgrade, writeVotePowerContract is replaced first to establish delegations. After some period (e.g., after a reward epoch ends), readVotePowerContract is set equal to it. Do not call any methods on VPContract directly. State changing methods are forbidden from direct calls. All are exposed via VPToken . This is the reason that this method returns IVPContractEvents Use it only for listening to events, delegating, and revoking.","title":"writeVotePowerContract"},{"location":"apis/smart-contracts/VPToken/#variables","text":"","title":"Variables"},{"location":"apis/smart-contracts/VPToken/#va_cleanercontract","text":"Defined in CheckPointable ( Docs , Source ). address cleanerContract Address of the contract that is allowed to call methods for history cleaning.","title":"cleanerContract"},{"location":"apis/smart-contracts/VPToken/#va_cleanupblocknumbermanager","text":"Defined in VPToken ( Docs , Source ). address cleanupBlockNumberManager The contract that is allowed to set cleanupBlockNumber . Usually this will be an instance of CleanupBlockNumberManager .","title":"cleanupBlockNumberManager"},{"location":"apis/smart-contracts/VPToken/#va_governancesettings","text":"Defined in GovernedBase ( Docs , Source ). contract IGovernanceSettings governanceSettings Governance Settings.","title":"governanceSettings"},{"location":"apis/smart-contracts/VPToken/#va_productionmode","text":"Defined in GovernedBase ( Docs , Source ). bool productionMode When true, governance is enabled and cannot be disabled. See switchToProductionMode .","title":"productionMode"},{"location":"apis/smart-contracts/VPToken/#va_timelockedcalls","text":"Defined in GovernedBase ( Docs , Source ). mapping ( bytes4 => struct GovernedBase . TimelockedCall ) timelockedCalls List of pending timelocked governance calls.","title":"timelockedCalls"},{"location":"apis/smart-contracts/VPToken/#va_vpcontractinitialized","text":"Defined in VPToken ( Docs , Source ). bool vpContractInitialized When true, the argument to setWriteVpContract must be a vpContract with isReplacement set to true . To be used for creating the correct VPContract .","title":"vpContractInitialized"},{"location":"apis/smart-contracts/VoterWhitelister/","text":"VoterWhitelister # Source | Inherits from IIVoterWhitelister , Governed , AddressUpdatable Manager of the FTSO whitelist . Only addresses registered in this contract can submit data to the FTSO system. Functions # addFtso # Defined in VoterWhitelister ( Docs , Source ). function addFtso ( uint256 _ftsoIndex ) external ; Create an empty whitelist with default size for a new FTSO. Only ftsoManager can call this method. Parameters Type Description _ftsoIndex uint256 Index of the new FTSO. cancelGovernanceCall # Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector. chillVoter # Defined in VoterWhitelister ( Docs , Source ). function chillVoter ( address _voter , uint256 _noOfRewardEpochs , uint256 [] _ftsoIndices ) external returns ( bool [] _removed , uint256 _untilRewardEpoch ); Used to chill a data provider, this is, remove it from the whitelist for a specified number of reward epochs. Only governance can call this method. Parameters Type Description _voter address Data provider being chilled. _noOfRewardEpochs uint256 Number of epochs to chill the provider for. _ftsoIndices uint256[] Array of indices of the FTSOs that will not allow this provider to submit data. chilledUntilRewardEpoch # Defined in IVoterWhitelister ( Docs , Source ). function chilledUntilRewardEpoch ( address _voter ) external view returns ( uint256 ); In case of providing bad prices (e.g. collusion), the voter can be chilled for a few reward epochs. A voter can whitelist again from a returned reward epoch onwards. Parameters Type Description _voter address Address of the queried data provider. Returns Type Description [0] uint256 uint256 ID of the epoch where the data provider can start submitting prices again. constructor # Defined in VoterWhitelister ( Docs , Source ). constructor ( address _governance , address _addressUpdater , contract IIPriceSubmitter _priceSubmitter , uint256 _defaultMaxVotersForFtso , contract IVoterWhitelister _oldVoterWhitelister ) public ; constructor # Defined in Governed ( Docs , Source ). constructor ( address _governance ) public ; Parameters Type Description _governance address Governance contract. Must not be zero. copyWhitelist # Defined in VoterWhitelister ( Docs , Source ). function copyWhitelist ( uint256 _ftsoIndex ) external ; Copy whitelist data from oldVoterWhitelister for a specific FTSO. Can only be called by governance . Parameters Type Description _ftsoIndex uint256 Index of the FTSO whose whitelist is to be copied. defaultMaxVotersForFtso # Defined in IVoterWhitelister ( Docs , Source ). function defaultMaxVotersForFtso ( ) external view returns ( uint256 ); Maximum number of voters in the whitelist for a new FTSO. Returns Type Description [0] uint256 uint256 Default maximum allowed voters. executeGovernanceCall # Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored). getAddressUpdater # Defined in AddressUpdatable ( Docs , Source ). function getAddressUpdater ( ) public view returns ( address _addressUpdater ); Returns the configured address updater. Returns Type Description _addressUpdater address The AddresUpdater contract that can update our contract address list, as a response to a governance call. getFtsoWhitelistedPriceProviders # Defined in VoterWhitelister ( Docs , Source ). function getFtsoWhitelistedPriceProviders ( uint256 _ftsoIndex ) public view returns ( address []); Gets whitelisted price providers for the FTSO at a given index. Parameters Type Description _ftsoIndex uint256 Queried index. Returns Type Description [0] address[] Array of addresses of the whitelisted data providers. getFtsoWhitelistedPriceProvidersBySymbol # Defined in VoterWhitelister ( Docs , Source ). function getFtsoWhitelistedPriceProvidersBySymbol ( string _symbol ) external view returns ( address []); Gets whitelisted price providers for the FTSO with a specified symbol. Parameters Type Description _symbol string Queried symbol. Returns Type Description [0] address[] Array of addresses of the whitelisted data providers. governance # Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address. maxVotersForFtso # Defined in IVoterWhitelister ( Docs , Source ). function maxVotersForFtso ( uint256 _ftsoIndex ) external view returns ( uint256 ); Maximum number of voters in the whitelist for a specific FTSO. Adjustable separately for each index. Parameters Type Description _ftsoIndex uint256 Index of the FTSO. Returns Type Description [0] uint256 uint256 Maximum allowed voters. removeFtso # Defined in VoterWhitelister ( Docs , Source ). function removeFtso ( uint256 _ftsoIndex ) external ; Clear whitelist for a removed FTSO. Only ftsoManager can call this method. Parameters Type Description _ftsoIndex uint256 Index of the removed FTSO. removeTrustedAddressFromWhitelist # Defined in VoterWhitelister ( Docs , Source ). function removeTrustedAddressFromWhitelist ( address _trustedAddress , uint256 _ftsoIndex ) external ; Remove a trusted address from whitelist. Parameters Type Description _trustedAddress address Address to remove. _ftsoIndex uint256 Index of the FTSO being modified. requestFullVoterWhitelisting # Defined in VoterWhitelister ( Docs , Source ). function requestFullVoterWhitelisting ( address _voter ) external returns ( uint256 [] _supportedIndices , bool [] _success ); Requests whitelisting an account to act as a data provider for all active FTSOs. May be called by any address, including the voter itself. Parameters Type Description _voter address Address of the voter to be whitelisted. Returns Type Description _supportedIndices uint256[] Array of currently supported FTSO indices. _success bool[] Array of success flags by FTSO index. requestWhitelistingVoter # Defined in VoterWhitelister ( Docs , Source ). function requestWhitelistingVoter ( address _voter , uint256 _ftsoIndex ) external ; Requests whitelisting an account to act as a data provider for a specific FTSO. Reverts if the vote power of the account is too low. May be called by any address, including the voter itself. Parameters Type Description _voter address Address of the voter to be whitelisted. _ftsoIndex uint256 Index of the FTSO. setDefaultMaxVotersForFtso # Defined in VoterWhitelister ( Docs , Source ). function setDefaultMaxVotersForFtso ( uint256 _defaultMaxVotersForFtso ) external ; Set the maximum number of voters in the whitelist for a new FTSOs. Only governance can call this method. Parameters Type Description _defaultMaxVotersForFtso uint256 New maximum default value. setMaxVotersForFtso # Defined in VoterWhitelister ( Docs , Source ). function setMaxVotersForFtso ( uint256 _ftsoIndex , uint256 _newMaxVoters ) external ; Set the maximum number of voters in the whitelist for a specific FTSO. Can remove voters with the least votepower from the whitelist. Only governance can call this method. Parameters Type Description _ftsoIndex uint256 Index of the FTSO to modify. _newMaxVoters uint256 New size of the whitelist. switchToProductionMode # Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered . turnOffCopyMode # Defined in VoterWhitelister ( Docs , Source ). function turnOffCopyMode ( ) external ; Turn off copy mode. Can only be called by governance . updateContractAddresses # Defined in AddressUpdatable ( Docs , Source ). function updateContractAddresses ( bytes32 [] _contractNameHashes , address [] _contractAddresses ) external ; External method called from AddressUpdater only. Modifiers # notInCopyMode # Defined in VoterWhitelister ( Docs , Source ). modifier notInCopyMode () Only callable when not in copy mode. onlyAddressUpdater # Defined in AddressUpdatable ( Docs , Source ). modifier onlyAddressUpdater () Only the AdressUpdater contract can call this method. Its address is set at construction time but it can also update itself. onlyFtsoManager # Defined in VoterWhitelister ( Docs , Source ). modifier onlyFtsoManager () Only the ftsoManager can call this method. onlyGovernance # Defined in GovernedBase ( Docs , Source ). modifier onlyGovernance () onlyImmediateGovernance # Defined in GovernedBase ( Docs , Source ). modifier onlyImmediateGovernance () voterNotChilled # Defined in VoterWhitelister ( Docs , Source ). modifier voterNotChilled ( address _voter ) Only data providers that have not been chilled can perform this action. Parameters Type Description _voter address Address of the data provider performing the action. Variables # chilledUntilRewardEpoch # Defined in VoterWhitelister ( Docs , Source ). mapping ( address => uint256 ) chilledUntilRewardEpoch In case of providing bad prices (e.g. collusion), the voter can be chilled for a few reward epochs. A voter can whitelist again from a returned reward epoch onwards. copyMode # Defined in VoterWhitelister ( Docs , Source ). bool copyMode defaultMaxVotersForFtso # Defined in VoterWhitelister ( Docs , Source ). uint256 defaultMaxVotersForFtso Maximum number of voters in the whitelist for a new FTSO. ftsoManager # Defined in VoterWhitelister ( Docs , Source ). contract IFtsoManager ftsoManager Address of the FtsoManager contract. ftsoRegistry # Defined in VoterWhitelister ( Docs , Source ). contract IFtsoRegistry ftsoRegistry Address of the FtsoRegistry contract. governanceSettings # Defined in GovernedBase ( Docs , Source ). contract IGovernanceSettings governanceSettings Governance Settings. maxVotersForFtso # Defined in VoterWhitelister ( Docs , Source ). mapping ( uint256 => uint256 ) maxVotersForFtso Maximum number of voters in the whitelist for a specific FTSO. Adjustable separately for each index. oldVoterWhitelister # Defined in VoterWhitelister ( Docs , Source ). contract IVoterWhitelister oldVoterWhitelister Previous VoterWhitelister contract, set at construction time. Necessary to allow copying the previous whitelist onto a new contract. priceSubmitter # Defined in VoterWhitelister ( Docs , Source ). contract IIPriceSubmitter priceSubmitter Address of the PriceSubmitter contract set at construction time. productionMode # Defined in GovernedBase ( Docs , Source ). bool productionMode When true, governance is enabled and cannot be disabled. See switchToProductionMode . timelockedCalls # Defined in GovernedBase ( Docs , Source ). mapping ( bytes4 => struct GovernedBase . TimelockedCall ) timelockedCalls List of pending timelocked governance calls.","title":"VoterWhitelister"},{"location":"apis/smart-contracts/VoterWhitelister/#ct_voterwhitelister","text":"Source | Inherits from IIVoterWhitelister , Governed , AddressUpdatable Manager of the FTSO whitelist . Only addresses registered in this contract can submit data to the FTSO system.","title":"VoterWhitelister"},{"location":"apis/smart-contracts/VoterWhitelister/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/VoterWhitelister/#fn_addftso_345705a4","text":"Defined in VoterWhitelister ( Docs , Source ). function addFtso ( uint256 _ftsoIndex ) external ; Create an empty whitelist with default size for a new FTSO. Only ftsoManager can call this method. Parameters Type Description _ftsoIndex uint256 Index of the new FTSO.","title":"addFtso"},{"location":"apis/smart-contracts/VoterWhitelister/#fn_cancelgovernancecall_67fc4029","text":"Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector.","title":"cancelGovernanceCall"},{"location":"apis/smart-contracts/VoterWhitelister/#fn_chillvoter_2b4faebb","text":"Defined in VoterWhitelister ( Docs , Source ). function chillVoter ( address _voter , uint256 _noOfRewardEpochs , uint256 [] _ftsoIndices ) external returns ( bool [] _removed , uint256 _untilRewardEpoch ); Used to chill a data provider, this is, remove it from the whitelist for a specified number of reward epochs. Only governance can call this method. Parameters Type Description _voter address Data provider being chilled. _noOfRewardEpochs uint256 Number of epochs to chill the provider for. _ftsoIndices uint256[] Array of indices of the FTSOs that will not allow this provider to submit data.","title":"chillVoter"},{"location":"apis/smart-contracts/VoterWhitelister/#fn_chilleduntilrewardepoch_46538074","text":"Defined in IVoterWhitelister ( Docs , Source ). function chilledUntilRewardEpoch ( address _voter ) external view returns ( uint256 ); In case of providing bad prices (e.g. collusion), the voter can be chilled for a few reward epochs. A voter can whitelist again from a returned reward epoch onwards. Parameters Type Description _voter address Address of the queried data provider. Returns Type Description [0] uint256 uint256 ID of the epoch where the data provider can start submitting prices again.","title":"chilledUntilRewardEpoch"},{"location":"apis/smart-contracts/VoterWhitelister/#fn_constructor_undefined","text":"Defined in VoterWhitelister ( Docs , Source ). constructor ( address _governance , address _addressUpdater , contract IIPriceSubmitter _priceSubmitter , uint256 _defaultMaxVotersForFtso , contract IVoterWhitelister _oldVoterWhitelister ) public ;","title":"constructor"},{"location":"apis/smart-contracts/VoterWhitelister/#fn_constructor_undefined","text":"Defined in Governed ( Docs , Source ). constructor ( address _governance ) public ; Parameters Type Description _governance address Governance contract. Must not be zero.","title":"constructor"},{"location":"apis/smart-contracts/VoterWhitelister/#fn_copywhitelist_8e15c883","text":"Defined in VoterWhitelister ( Docs , Source ). function copyWhitelist ( uint256 _ftsoIndex ) external ; Copy whitelist data from oldVoterWhitelister for a specific FTSO. Can only be called by governance . Parameters Type Description _ftsoIndex uint256 Index of the FTSO whose whitelist is to be copied.","title":"copyWhitelist"},{"location":"apis/smart-contracts/VoterWhitelister/#fn_defaultmaxvotersforftso_47ed51b1","text":"Defined in IVoterWhitelister ( Docs , Source ). function defaultMaxVotersForFtso ( ) external view returns ( uint256 ); Maximum number of voters in the whitelist for a new FTSO. Returns Type Description [0] uint256 uint256 Default maximum allowed voters.","title":"defaultMaxVotersForFtso"},{"location":"apis/smart-contracts/VoterWhitelister/#fn_executegovernancecall_5ff27079","text":"Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored).","title":"executeGovernanceCall"},{"location":"apis/smart-contracts/VoterWhitelister/#fn_getaddressupdater_5267a15d","text":"Defined in AddressUpdatable ( Docs , Source ). function getAddressUpdater ( ) public view returns ( address _addressUpdater ); Returns the configured address updater. Returns Type Description _addressUpdater address The AddresUpdater contract that can update our contract address list, as a response to a governance call.","title":"getAddressUpdater"},{"location":"apis/smart-contracts/VoterWhitelister/#fn_getftsowhitelistedpriceproviders_09fcb400","text":"Defined in VoterWhitelister ( Docs , Source ). function getFtsoWhitelistedPriceProviders ( uint256 _ftsoIndex ) public view returns ( address []); Gets whitelisted price providers for the FTSO at a given index. Parameters Type Description _ftsoIndex uint256 Queried index. Returns Type Description [0] address[] Array of addresses of the whitelisted data providers.","title":"getFtsoWhitelistedPriceProviders"},{"location":"apis/smart-contracts/VoterWhitelister/#fn_getftsowhitelistedpriceprovidersbysymbol_aa89dfd4","text":"Defined in VoterWhitelister ( Docs , Source ). function getFtsoWhitelistedPriceProvidersBySymbol ( string _symbol ) external view returns ( address []); Gets whitelisted price providers for the FTSO with a specified symbol. Parameters Type Description _symbol string Queried symbol. Returns Type Description [0] address[] Array of addresses of the whitelisted data providers.","title":"getFtsoWhitelistedPriceProvidersBySymbol"},{"location":"apis/smart-contracts/VoterWhitelister/#fn_governance_5aa6e675","text":"Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address.","title":"governance"},{"location":"apis/smart-contracts/VoterWhitelister/#fn_maxvotersforftso_98dccfc2","text":"Defined in IVoterWhitelister ( Docs , Source ). function maxVotersForFtso ( uint256 _ftsoIndex ) external view returns ( uint256 ); Maximum number of voters in the whitelist for a specific FTSO. Adjustable separately for each index. Parameters Type Description _ftsoIndex uint256 Index of the FTSO. Returns Type Description [0] uint256 uint256 Maximum allowed voters.","title":"maxVotersForFtso"},{"location":"apis/smart-contracts/VoterWhitelister/#fn_removeftso_d8736171","text":"Defined in VoterWhitelister ( Docs , Source ). function removeFtso ( uint256 _ftsoIndex ) external ; Clear whitelist for a removed FTSO. Only ftsoManager can call this method. Parameters Type Description _ftsoIndex uint256 Index of the removed FTSO.","title":"removeFtso"},{"location":"apis/smart-contracts/VoterWhitelister/#fn_removetrustedaddressfromwhitelist_9dc950ab","text":"Defined in VoterWhitelister ( Docs , Source ). function removeTrustedAddressFromWhitelist ( address _trustedAddress , uint256 _ftsoIndex ) external ; Remove a trusted address from whitelist. Parameters Type Description _trustedAddress address Address to remove. _ftsoIndex uint256 Index of the FTSO being modified.","title":"removeTrustedAddressFromWhitelist"},{"location":"apis/smart-contracts/VoterWhitelister/#fn_requestfullvoterwhitelisting_b06cbaf7","text":"Defined in VoterWhitelister ( Docs , Source ). function requestFullVoterWhitelisting ( address _voter ) external returns ( uint256 [] _supportedIndices , bool [] _success ); Requests whitelisting an account to act as a data provider for all active FTSOs. May be called by any address, including the voter itself. Parameters Type Description _voter address Address of the voter to be whitelisted. Returns Type Description _supportedIndices uint256[] Array of currently supported FTSO indices. _success bool[] Array of success flags by FTSO index.","title":"requestFullVoterWhitelisting"},{"location":"apis/smart-contracts/VoterWhitelister/#fn_requestwhitelistingvoter_3de2cb1c","text":"Defined in VoterWhitelister ( Docs , Source ). function requestWhitelistingVoter ( address _voter , uint256 _ftsoIndex ) external ; Requests whitelisting an account to act as a data provider for a specific FTSO. Reverts if the vote power of the account is too low. May be called by any address, including the voter itself. Parameters Type Description _voter address Address of the voter to be whitelisted. _ftsoIndex uint256 Index of the FTSO.","title":"requestWhitelistingVoter"},{"location":"apis/smart-contracts/VoterWhitelister/#fn_setdefaultmaxvotersforftso_2ee96140","text":"Defined in VoterWhitelister ( Docs , Source ). function setDefaultMaxVotersForFtso ( uint256 _defaultMaxVotersForFtso ) external ; Set the maximum number of voters in the whitelist for a new FTSOs. Only governance can call this method. Parameters Type Description _defaultMaxVotersForFtso uint256 New maximum default value.","title":"setDefaultMaxVotersForFtso"},{"location":"apis/smart-contracts/VoterWhitelister/#fn_setmaxvotersforftso_7ecfcfa3","text":"Defined in VoterWhitelister ( Docs , Source ). function setMaxVotersForFtso ( uint256 _ftsoIndex , uint256 _newMaxVoters ) external ; Set the maximum number of voters in the whitelist for a specific FTSO. Can remove voters with the least votepower from the whitelist. Only governance can call this method. Parameters Type Description _ftsoIndex uint256 Index of the FTSO to modify. _newMaxVoters uint256 New size of the whitelist.","title":"setMaxVotersForFtso"},{"location":"apis/smart-contracts/VoterWhitelister/#fn_switchtoproductionmode_f5a98383","text":"Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered .","title":"switchToProductionMode"},{"location":"apis/smart-contracts/VoterWhitelister/#fn_turnoffcopymode_3a65d7b6","text":"Defined in VoterWhitelister ( Docs , Source ). function turnOffCopyMode ( ) external ; Turn off copy mode. Can only be called by governance .","title":"turnOffCopyMode"},{"location":"apis/smart-contracts/VoterWhitelister/#fn_updatecontractaddresses_b00c0b76","text":"Defined in AddressUpdatable ( Docs , Source ). function updateContractAddresses ( bytes32 [] _contractNameHashes , address [] _contractAddresses ) external ; External method called from AddressUpdater only.","title":"updateContractAddresses"},{"location":"apis/smart-contracts/VoterWhitelister/#modifiers","text":"","title":"Modifiers"},{"location":"apis/smart-contracts/VoterWhitelister/#md_notincopymode","text":"Defined in VoterWhitelister ( Docs , Source ). modifier notInCopyMode () Only callable when not in copy mode.","title":"notInCopyMode"},{"location":"apis/smart-contracts/VoterWhitelister/#md_onlyaddressupdater","text":"Defined in AddressUpdatable ( Docs , Source ). modifier onlyAddressUpdater () Only the AdressUpdater contract can call this method. Its address is set at construction time but it can also update itself.","title":"onlyAddressUpdater"},{"location":"apis/smart-contracts/VoterWhitelister/#md_onlyftsomanager","text":"Defined in VoterWhitelister ( Docs , Source ). modifier onlyFtsoManager () Only the ftsoManager can call this method.","title":"onlyFtsoManager"},{"location":"apis/smart-contracts/VoterWhitelister/#md_onlygovernance","text":"Defined in GovernedBase ( Docs , Source ). modifier onlyGovernance ()","title":"onlyGovernance"},{"location":"apis/smart-contracts/VoterWhitelister/#md_onlyimmediategovernance","text":"Defined in GovernedBase ( Docs , Source ). modifier onlyImmediateGovernance ()","title":"onlyImmediateGovernance"},{"location":"apis/smart-contracts/VoterWhitelister/#md_voternotchilled","text":"Defined in VoterWhitelister ( Docs , Source ). modifier voterNotChilled ( address _voter ) Only data providers that have not been chilled can perform this action. Parameters Type Description _voter address Address of the data provider performing the action.","title":"voterNotChilled"},{"location":"apis/smart-contracts/VoterWhitelister/#variables","text":"","title":"Variables"},{"location":"apis/smart-contracts/VoterWhitelister/#va_chilleduntilrewardepoch","text":"Defined in VoterWhitelister ( Docs , Source ). mapping ( address => uint256 ) chilledUntilRewardEpoch In case of providing bad prices (e.g. collusion), the voter can be chilled for a few reward epochs. A voter can whitelist again from a returned reward epoch onwards.","title":"chilledUntilRewardEpoch"},{"location":"apis/smart-contracts/VoterWhitelister/#va_copymode","text":"Defined in VoterWhitelister ( Docs , Source ). bool copyMode","title":"copyMode"},{"location":"apis/smart-contracts/VoterWhitelister/#va_defaultmaxvotersforftso","text":"Defined in VoterWhitelister ( Docs , Source ). uint256 defaultMaxVotersForFtso Maximum number of voters in the whitelist for a new FTSO.","title":"defaultMaxVotersForFtso"},{"location":"apis/smart-contracts/VoterWhitelister/#va_ftsomanager","text":"Defined in VoterWhitelister ( Docs , Source ). contract IFtsoManager ftsoManager Address of the FtsoManager contract.","title":"ftsoManager"},{"location":"apis/smart-contracts/VoterWhitelister/#va_ftsoregistry","text":"Defined in VoterWhitelister ( Docs , Source ). contract IFtsoRegistry ftsoRegistry Address of the FtsoRegistry contract.","title":"ftsoRegistry"},{"location":"apis/smart-contracts/VoterWhitelister/#va_governancesettings","text":"Defined in GovernedBase ( Docs , Source ). contract IGovernanceSettings governanceSettings Governance Settings.","title":"governanceSettings"},{"location":"apis/smart-contracts/VoterWhitelister/#va_maxvotersforftso","text":"Defined in VoterWhitelister ( Docs , Source ). mapping ( uint256 => uint256 ) maxVotersForFtso Maximum number of voters in the whitelist for a specific FTSO. Adjustable separately for each index.","title":"maxVotersForFtso"},{"location":"apis/smart-contracts/VoterWhitelister/#va_oldvoterwhitelister","text":"Defined in VoterWhitelister ( Docs , Source ). contract IVoterWhitelister oldVoterWhitelister Previous VoterWhitelister contract, set at construction time. Necessary to allow copying the previous whitelist onto a new contract.","title":"oldVoterWhitelister"},{"location":"apis/smart-contracts/VoterWhitelister/#va_pricesubmitter","text":"Defined in VoterWhitelister ( Docs , Source ). contract IIPriceSubmitter priceSubmitter Address of the PriceSubmitter contract set at construction time.","title":"priceSubmitter"},{"location":"apis/smart-contracts/VoterWhitelister/#va_productionmode","text":"Defined in GovernedBase ( Docs , Source ). bool productionMode When true, governance is enabled and cannot be disabled. See switchToProductionMode .","title":"productionMode"},{"location":"apis/smart-contracts/VoterWhitelister/#va_timelockedcalls","text":"Defined in GovernedBase ( Docs , Source ). mapping ( bytes4 => struct GovernedBase . TimelockedCall ) timelockedCalls List of pending timelocked governance calls.","title":"timelockedCalls"},{"location":"apis/smart-contracts/WNat/","text":"WNat # Source | Inherits from VPToken , IWNat Wrapped native token. This contract converts native tokens into WNAT (wrapped native) tokens and vice versa. WNAT tokens are a one-to-one ERC20 representation of native tokens, which are minted and burned as needed by this contract. The wrapped versions of the native FLR and SGB tokens are called WFLR and WSGB respectively. Besides the standard ERC20 operations, this contract supports FTSO delegation and governance vote delegation . Code attribution: WETH9. Events # Approval # Defined in IERC20 ( Source ). event Approval ( address owner , address spender , uint256 value ) Emitted when the allowance of a spender for an owner is set by a call to approve . value is the new allowance . CreatedTotalSupplyCache # Defined in CheckPointable ( Docs , Source ). event CreatedTotalSupplyCache ( uint256 _blockNumber ) Emitted when a total supply cache entry is created. Allows history cleaners to track total supply cache cleanup opportunities off-chain. Deposit # Defined in WNat ( Docs , Source ). event Deposit ( address dst , uint256 amount ) Emitted when tokens have been wrapped. Parameters Type Description dst address The account that received the wrapped tokens. amount uint256 The amount that was wrapped. GovernanceCallTimelocked # Defined in GovernedBase ( Docs , Source ). event GovernanceCallTimelocked ( bytes4 selector , uint256 allowedAfterTimestamp , bytes encodedCall ) Emitted when a new governance call has been recorded and is now waiting for the time lock to expire. GovernanceInitialised # Defined in GovernedBase ( Docs , Source ). event GovernanceInitialised ( address initialGovernance ) Emitted when the governance address is initialized. This address will be used until production mode is entered (see GovernedProductionModeEntered ). At that point the governance address is taken from GovernanceSettings . GovernedProductionModeEntered # Defined in GovernedBase ( Docs , Source ). event GovernedProductionModeEntered ( address governanceSettings ) Emitted when governance is enabled and the governance address cannot be changed anymore (only through a network fork). TimelockedGovernanceCallCanceled # Defined in GovernedBase ( Docs , Source ). event TimelockedGovernanceCallCanceled ( bytes4 selector , uint256 timestamp ) Emitted when a timelocked governance call is canceled before execution. TimelockedGovernanceCallExecuted # Defined in GovernedBase ( Docs , Source ). event TimelockedGovernanceCallExecuted ( bytes4 selector , uint256 timestamp ) Emitted when a timelocked governance call is executed. Transfer # Defined in IERC20 ( Source ). event Transfer ( address from , address to , uint256 value ) Emitted when value tokens are moved from one account ( from ) to another ( to ). Note that value may be zero. VotePowerContractChanged # Defined in VPToken ( Docs , Source ). event VotePowerContractChanged ( uint256 _contractType , address _oldContractAddress , address _newContractAddress ) Emitted when one of the vote power contracts is changed. It is used to track the history of VPToken -> VPContract / GovernanceVotePower associations (e.g. by external cleaners). Parameters Type Description _contractType uint256 0 = Read VPContract , 1 = Write VPContract , 2 = Governance vote power. _oldContractAddress address Contract address before change. _newContractAddress address Contract address after change. Withdrawal # Defined in WNat ( Docs , Source ). event Withdrawal ( address src , uint256 amount ) Emitted when tokens have been unwrapped. Parameters Type Description src address The account that received the unwrapped tokens. amount uint256 The amount that was unwrapped. Functions # allowance # Defined in IERC20 ( Source ). function allowance ( address owner , address spender ) external view returns ( uint256 ); Returns the remaining number of tokens that spender will be allowed to spend on behalf of owner through transferFrom . This is zero by default. This value changes when approve or transferFrom are called. approve # Defined in IERC20 ( Source ). function approve ( address spender , uint256 amount ) external returns ( bool ); Sets amount as the allowance of spender over the caller's tokens. Returns a boolean value indicating whether the operation succeeded. IMPORTANT: Beware that changing an allowance with this method brings the risk that someone may use both the old and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 Emits an Approval event. balanceHistoryCleanup # Defined in CheckPointable ( Docs , Source ). function balanceHistoryCleanup ( address _owner , uint256 _count ) external returns ( uint256 ); Delete balance checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _owner address balance owner account address _count uint256 maximum number of checkpoints to delete Returns Type Description [0] uint256 the number of checkpoints deleted balanceOf # Defined in IERC20 ( Source ). function balanceOf ( address account ) external view returns ( uint256 ); Returns the amount of tokens owned by account . balanceOfAt # Defined in VPToken ( Docs , Source ). function balanceOfAt ( address _owner , uint256 _blockNumber ) public view returns ( uint256 ); Queries the token balance of _owner at a specific _blockNumber . Parameters Type Description _owner address The address from which the balance will be retrieved. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 batchDelegate # Defined in VPToken ( Docs , Source ). function batchDelegate ( address [] _delegatees , uint256 [] _bips ) external ; Undelegate all percentage delegations from the sender and then delegate corresponding _bips percentage of voting power from the sender to each member of the _delegatees array. Parameters Type Description _delegatees address[] The addresses of the new recipients. _bips uint256[] The percentages of voting power to be delegated expressed in basis points (1/100 of one percent). The sum of all _bips values must be at most 10000 (100%). batchVotePowerOfAt # Defined in VPToken ( Docs , Source ). function batchVotePowerOfAt ( address [] _owners , uint256 _blockNumber ) external view returns ( uint256 []); Return the vote power for several addresses. Parameters Type Description _owners address[] The list of addresses to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256[] Array of vote power for each queried address. cancelGovernanceCall # Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector. cleanupBlockNumber # Defined in VPToken ( Docs , Source ). function cleanupBlockNumber ( ) external view returns ( uint256 ); Get the current cleanup block number set with setCleanupBlockNumber . Returns Type Description [0] uint256 The currently set cleanup block number. constructor # Defined in WNat ( Docs , Source ). constructor ( address _governance , string _name , string _symbol ) public ; Construct an ERC20 token. decimals # Defined in VPToken ( Docs , Source ). function decimals ( ) public view returns ( uint8 ); Returns the number of decimals used to get its user representation. For example, if decimals equals 2, a balance of 505 tokens should be displayed to a user as 5.05 (505 / 10 2 ). Tokens usually opt for a value of 18, imitating the relationship between Ether and wei. This is the default value returned by this function, unless it's overridden. NOTE: This information is only used for display purposes: it in no way affects any of the arithmetic of the contract, including balanceOf and transfer . Should be compatible with ERC20 method. delegate # Defined in VPToken ( Docs , Source ). function delegate ( address _to , uint256 _bips ) external ; Delegate voting power to account _to from msg.sender , by percentage. Parameters Type Description _to address The address of the recipient. _bips uint256 The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: every call resets the delegation value (and a value of 0 revokes all previous delegations). delegateExplicit # Defined in VPToken ( Docs , Source ). function delegateExplicit ( address _to , uint256 _amount ) external ; Explicitly delegate _amount voting power to account _to from msg.sender . Compare with delegate which delegates by percentage. Parameters Type Description _to address The address of the recipient. _amount uint256 An explicit vote power amount to be delegated. Not cumulative: every call resets the delegation value (and a value of 0 revokes all previous delegations). delegatesOf # Defined in VPToken ( Docs , Source ). function delegatesOf ( address _owner ) external view returns ( address [] _delegateAddresses , uint256 [] _bips , uint256 _count , uint256 _delegationMode ); Get the list of addresses to which _who is delegating, and their percentages. Parameters Type Description _owner address Returns Type Description _delegateAddresses address[] Positional array of addresses being delegated to. _bips uint256[] Positional array of delegation percents specified in basis points (1/100 of 1 percent). Each one matches the address in the same position in the _delegateAddresses array. _count uint256 The number of delegates. _delegationMode uint256 Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit). delegatesOfAt # Defined in VPToken ( Docs , Source ). function delegatesOfAt ( address _owner , uint256 _blockNumber ) external view returns ( address [] _delegateAddresses , uint256 [] _bips , uint256 _count , uint256 _delegationMode ); Get the list of addresses to which _who is delegating, and their percentages, at the given block. Parameters Type Description _owner address _blockNumber uint256 The block number to query. Returns Type Description _delegateAddresses address[] Positional array of addresses being delegated to. _bips uint256[] Positional array of delegation percents specified in basis points (1/100 of 1 percent). Each one matches the address in the same position in the _delegateAddresses array. _count uint256 The number of delegates. _delegationMode uint256 Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit). delegationModeOf # Defined in VPToken ( Docs , Source ). function delegationModeOf ( address _who ) external view returns ( uint256 ); Get the delegation mode for account '_who'. This mode determines whether vote power is allocated by percentage or by explicit amount. Once the delegation mode is set, it can never be changed, even if all delegations are removed. Parameters Type Description _who address The address to get delegation mode. Returns Type Description [0] uint256 Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit). deposit # Defined in WNat ( Docs , Source ). function deposit ( ) public payable ; Deposits native tokens and mints the same amount of WNAT tokens, which are added to the msg.sender 's balance. This operation is commonly known as \"wrapping\". Emits a Deposit event. depositTo # Defined in WNat ( Docs , Source ). function depositTo ( address _recipient ) external payable ; Deposits native tokens and mints the same amount of WNAT tokens, which are added to _recipient 's balance. This operation is commonly known as \"wrapping\". This is equivalent to using deposit followed by transfer . Emits a Deposit event. Parameters Type Description _recipient address The address to receive the minted WNAT . executeGovernanceCall # Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored). governance # Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address. governanceVotePower # Defined in VPToken ( Docs , Source ). function governanceVotePower ( ) external view returns ( contract IGovernanceVotePower ); When set, allows token owners to participate in governance voting and delegate governance vote power. name # Defined in VPToken ( Docs , Source ). function name ( ) public view returns ( string ); Returns the name of the token. Should be compatible with ERC20 method. readVotePowerContract # Defined in VPToken ( Docs , Source ). function readVotePowerContract ( ) external view returns ( contract IVPContractEvents ); Returns VPContract event interface used for read-only operations (view methods). The only non-view method that might be called on it is revokeDelegationAt . readVotePowerContract is almost always equal to writeVotePowerContract except during an upgrade from one VPContract to a new version (which should happen rarely or never and will be announced beforehand). Do not call any methods on VPContract directly. State changing methods are forbidden from direct calls. All methods are exposed via VPToken . This is the reason that this method returns IVPContractEvents . Use it only for listening to events and revoking. receive # Defined in WNat ( Docs , Source ). receive ( ) external payable ; A proxy for the deposit method. revokeDelegationAt # Defined in VPToken ( Docs , Source ). function revokeDelegationAt ( address _who , uint256 _blockNumber ) public ; Revoke all delegation from sender to _who at given block. Only affects the reads via votePowerOfAtCached in the block _blockNumber . Block _blockNumber must be in the past. This method should be used only to prevent rogue delegate voting in the current voting block. To stop delegating use delegate / delegateExplicit with value of 0 or undelegateAll / undelegateAllExplicit . Parameters Type Description _who address Address of the delegatee. _blockNumber uint256 The block number at which to revoke delegation.. setCleanerContract # Defined in VPToken ( Docs , Source ). function setCleanerContract ( address _cleanerContract ) external ; Set the contract that is allowed to call history cleaning methods. Parameters Type Description _cleanerContract address Address of the cleanup contract. Usually this will be an instance of CleanupBlockNumberManager . setCleanupBlockNumber # Defined in VPToken ( Docs , Source ). function setCleanupBlockNumber ( uint256 _blockNumber ) external ; Set the cleanup block number. Historic data for the blocks before cleanupBlockNumber can be erased. History before that block should never be used since it can be inconsistent. In particular, cleanup block number must be lower than the current vote power block. Parameters Type Description _blockNumber uint256 The new cleanup block number. setCleanupBlockNumberManager # Defined in VPToken ( Docs , Source ). function setCleanupBlockNumberManager ( address _cleanupBlockNumberManager ) external ; Set the contract that is allowed to set cleanupBlockNumber . Usually this will be an instance of CleanupBlockNumberManager . setGovernanceVotePower # Defined in VPToken ( Docs , Source ). function setGovernanceVotePower ( contract IIGovernanceVotePower _governanceVotePower ) external ; Sets new governance vote power contract that allows token owners to participate in governance voting and delegate governance vote power. setReadVpContract # Defined in VPToken ( Docs , Source ). function setReadVpContract ( contract IIVPContract _vpContract ) external ; Call from governance to set read VpContract on token, e.g. vpToken. setReadVpContract (new VPContract (vpToken)). Read VPContract must be set before any of the VPToken delegation or vote power reading methods are called, otherwise they will revert. NOTE : If readVpContract differs from writeVpContract all reads will be \"frozen\" and will not reflect changes (not even revokes; they may or may not reflect balance transfers). Parameters Type Description _vpContract contract IIVPContract Read vote power contract to be used by this token. setWriteVpContract # Defined in VPToken ( Docs , Source ). function setWriteVpContract ( contract IIVPContract _vpContract ) external ; Call from governance to set write VpContract on token, e.g. vpToken. setWriteVpContract (new VPContract (vpToken)). Write VPContract must be set before any of the VPToken delegation modifying methods are called, otherwise they will revert. Parameters Type Description _vpContract contract IIVPContract Write vote power contract to be used by this token. switchToProductionMode # Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered . symbol # Defined in VPToken ( Docs , Source ). function symbol ( ) public view returns ( string ); Returns the symbol of the token, usually a shorter version of the name . Should be compatible with ERC20 method. totalSupply # Defined in IERC20 ( Source ). function totalSupply ( ) external view returns ( uint256 ); Returns the amount of tokens in existence. totalSupplyAt # Defined in VPToken ( Docs , Source ). function totalSupplyAt ( uint256 _blockNumber ) public view returns ( uint256 ); Total amount of tokens at a specific _blockNumber . Parameters Type Description _blockNumber uint256 The block number when the _totalSupply is queried Returns Type Description [0] uint256 totalSupplyCacheCleanup # Defined in CheckPointable ( Docs , Source ). function totalSupplyCacheCleanup ( uint256 _blockNumber ) external returns ( uint256 ); Delete total supply cache entry that expired (i.e. is before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _blockNumber uint256 the block number for which total supply value was cached Returns Type Description [0] uint256 the number of cache entries deleted (always 0 or 1) totalSupplyHistoryCleanup # Defined in CheckPointable ( Docs , Source ). function totalSupplyHistoryCleanup ( uint256 _count ) external returns ( uint256 ); Delete total supply checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _count uint256 maximum number of checkpoints to delete Returns Type Description [0] uint256 the number of checkpoints deleted totalVotePower # Defined in VPToken ( Docs , Source ). function totalVotePower ( ) external view returns ( uint256 ); Get the current total vote power. Returns Type Description [0] uint256 The current total vote power (sum of all accounts' vote power). totalVotePowerAt # Defined in VPToken ( Docs , Source ). function totalVotePowerAt ( uint256 _blockNumber ) external view returns ( uint256 ); Get the total vote power at block _blockNumber . Parameters Type Description _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The total vote power at the queried block (sum of all accounts' vote powers). totalVotePowerAtCached # Defined in VPToken ( Docs , Source ). function totalVotePowerAtCached ( uint256 _blockNumber ) public returns ( uint256 ); Get the total vote power at block _blockNumber using cache. It tries to read the cached value and if it is not found, reads the actual value and stores it in the cache. Can only be used if _blockNumber is in the past, otherwise reverts. Parameters Type Description _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The total vote power at the queried block (sum of all accounts' vote powers). transfer # Defined in IERC20 ( Source ). function transfer ( address recipient , uint256 amount ) external returns ( bool ); Moves amount tokens from the caller's account to recipient . Returns a boolean value indicating whether the operation succeeded. Emits a Transfer event. transferFrom # Defined in IERC20 ( Source ). function transferFrom ( address sender , address recipient , uint256 amount ) external returns ( bool ); Moves amount tokens from sender to recipient using the allowance mechanism. amount is then deducted from the caller's allowance . Returns a boolean value indicating whether the operation succeeded. Emits a Transfer event. undelegateAll # Defined in VPToken ( Docs , Source ). function undelegateAll ( ) external ; Undelegate all voting power of msg.sender . This effectively revokes all previous delegations. Can only be used with percentage delegation. Does not reset delegation mode back to NOT SET. undelegateAllExplicit # Defined in VPToken ( Docs , Source ). function undelegateAllExplicit ( address [] _delegateAddresses ) external returns ( uint256 _remainingDelegation ); Undelegate all explicit vote power by amount of msg.sender . Can only be used with explicit delegation. Does not reset delegation mode back to NOT SET. Parameters Type Description _delegateAddresses address[] Explicit delegation does not store delegatees' addresses, so the caller must supply them. Returns Type Description _remainingDelegation uint256 The amount still delegated (in case the list of delegates was incomplete). undelegatedVotePowerOf # Defined in VPToken ( Docs , Source ). function undelegatedVotePowerOf ( address _owner ) external view returns ( uint256 ); Compute the current undelegated vote power of the _owner account. Parameters Type Description _owner address The address to query. Returns Type Description [0] uint256 The unallocated vote power of _owner . undelegatedVotePowerOfAt # Defined in VPToken ( Docs , Source ). function undelegatedVotePowerOfAt ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Get the undelegated vote power of the _owner account at a given block number. Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The unallocated vote power of _owner . votePowerFromTo # Defined in VPToken ( Docs , Source ). function votePowerFromTo ( address _from , address _to ) external view returns ( uint256 ); Get current delegated vote power from delegator _from to delegatee _to . Parameters Type Description _from address Address of delegator. _to address Address of delegatee. Returns Type Description [0] uint256 votePower The delegated vote power. votePowerFromToAt # Defined in VPToken ( Docs , Source ). function votePowerFromToAt ( address _from , address _to , uint256 _blockNumber ) external view returns ( uint256 ); Get delegated vote power from delegator _from to delegatee _to at _blockNumber . Parameters Type Description _from address Address of delegator. _to address Address of delegatee. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The delegated vote power. votePowerOf # Defined in VPToken ( Docs , Source ). function votePowerOf ( address _owner ) external view returns ( uint256 ); Get the current vote power of _owner . Parameters Type Description _owner address The address to query. Returns Type Description [0] uint256 Current vote power of _owner . votePowerOfAt # Defined in VPToken ( Docs , Source ). function votePowerOfAt ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Get the vote power of _owner at block _blockNumber Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 Vote power of _owner at block number _blockNumber . votePowerOfAtCached # Defined in VPToken ( Docs , Source ). function votePowerOfAtCached ( address _owner , uint256 _blockNumber ) public returns ( uint256 ); Get the vote power of _owner at block _blockNumber using cache. It tries to read the cached value and if it is not found, reads the actual value and stores it in the cache. Can only be used if _blockNumber is in the past, otherwise reverts. Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 Vote power of _owner at _blockNumber . votePowerOfAtIgnoringRevocation # Defined in VPToken ( Docs , Source ). function votePowerOfAtIgnoringRevocation ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Get the vote power of _owner at block _blockNumber , ignoring revocation information (and cache). Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 Vote power of _owner at block number _blockNumber . Result doesn't change if vote power is revoked. withdraw # Defined in WNat ( Docs , Source ). function withdraw ( uint256 _amount ) external ; Burns _amount of WNAT tokens from msg.sender 's WNAT balance and transfers the same amount of native tokens to msg.sender . This operation is commonly known as \"unwrapping\". Reverts if _amount is higher than msg.sender 's WNAT balance. Emits a Withdrawal event. Parameters Type Description _amount uint256 The amount to withdraw. withdrawFrom # Defined in WNat ( Docs , Source ). function withdrawFrom ( address _owner , uint256 _amount ) external ; Burns _amount of WNAT tokens from _owner 's WNAT balance and transfers the same amount of native tokens to msg.sender . This operation is commonly known as \"unwrapping\". msg.sender must have been authorized to withdraw from _owner 's account through ERC-20's approve mechanism. Reverts if _amount is higher than _owners 's WNAT balance or than msg.sender 's allowance over _owner 's tokens. Emits a Withdrawal event. Parameters Type Description _owner address The address containing the tokens to withdraw. _amount uint256 The amount to withdraw. writeVotePowerContract # Defined in VPToken ( Docs , Source ). function writeVotePowerContract ( ) external view returns ( contract IVPContractEvents ); Returns VPContract event interface used for state-changing operations (non-view methods). The only non-view method that might be called on it is revokeDelegationAt . writeVotePowerContract is almost always equal to readVotePowerContract , except during upgrade from one VPContract to a new version (which should happen rarely or never and will be announced beforehand). In the case of an upgrade, writeVotePowerContract is replaced first to establish delegations. After some period (e.g., after a reward epoch ends), readVotePowerContract is set equal to it. Do not call any methods on VPContract directly. State changing methods are forbidden from direct calls. All are exposed via VPToken . This is the reason that this method returns IVPContractEvents Use it only for listening to events, delegating, and revoking.","title":"WNat"},{"location":"apis/smart-contracts/WNat/#ct_wnat","text":"Source | Inherits from VPToken , IWNat Wrapped native token. This contract converts native tokens into WNAT (wrapped native) tokens and vice versa. WNAT tokens are a one-to-one ERC20 representation of native tokens, which are minted and burned as needed by this contract. The wrapped versions of the native FLR and SGB tokens are called WFLR and WSGB respectively. Besides the standard ERC20 operations, this contract supports FTSO delegation and governance vote delegation . Code attribution: WETH9.","title":"WNat"},{"location":"apis/smart-contracts/WNat/#events","text":"","title":"Events"},{"location":"apis/smart-contracts/WNat/#ev_approval","text":"Defined in IERC20 ( Source ). event Approval ( address owner , address spender , uint256 value ) Emitted when the allowance of a spender for an owner is set by a call to approve . value is the new allowance .","title":"Approval"},{"location":"apis/smart-contracts/WNat/#ev_createdtotalsupplycache","text":"Defined in CheckPointable ( Docs , Source ). event CreatedTotalSupplyCache ( uint256 _blockNumber ) Emitted when a total supply cache entry is created. Allows history cleaners to track total supply cache cleanup opportunities off-chain.","title":"CreatedTotalSupplyCache"},{"location":"apis/smart-contracts/WNat/#ev_deposit","text":"Defined in WNat ( Docs , Source ). event Deposit ( address dst , uint256 amount ) Emitted when tokens have been wrapped. Parameters Type Description dst address The account that received the wrapped tokens. amount uint256 The amount that was wrapped.","title":"Deposit"},{"location":"apis/smart-contracts/WNat/#ev_governancecalltimelocked","text":"Defined in GovernedBase ( Docs , Source ). event GovernanceCallTimelocked ( bytes4 selector , uint256 allowedAfterTimestamp , bytes encodedCall ) Emitted when a new governance call has been recorded and is now waiting for the time lock to expire.","title":"GovernanceCallTimelocked"},{"location":"apis/smart-contracts/WNat/#ev_governanceinitialised","text":"Defined in GovernedBase ( Docs , Source ). event GovernanceInitialised ( address initialGovernance ) Emitted when the governance address is initialized. This address will be used until production mode is entered (see GovernedProductionModeEntered ). At that point the governance address is taken from GovernanceSettings .","title":"GovernanceInitialised"},{"location":"apis/smart-contracts/WNat/#ev_governedproductionmodeentered","text":"Defined in GovernedBase ( Docs , Source ). event GovernedProductionModeEntered ( address governanceSettings ) Emitted when governance is enabled and the governance address cannot be changed anymore (only through a network fork).","title":"GovernedProductionModeEntered"},{"location":"apis/smart-contracts/WNat/#ev_timelockedgovernancecallcanceled","text":"Defined in GovernedBase ( Docs , Source ). event TimelockedGovernanceCallCanceled ( bytes4 selector , uint256 timestamp ) Emitted when a timelocked governance call is canceled before execution.","title":"TimelockedGovernanceCallCanceled"},{"location":"apis/smart-contracts/WNat/#ev_timelockedgovernancecallexecuted","text":"Defined in GovernedBase ( Docs , Source ). event TimelockedGovernanceCallExecuted ( bytes4 selector , uint256 timestamp ) Emitted when a timelocked governance call is executed.","title":"TimelockedGovernanceCallExecuted"},{"location":"apis/smart-contracts/WNat/#ev_transfer","text":"Defined in IERC20 ( Source ). event Transfer ( address from , address to , uint256 value ) Emitted when value tokens are moved from one account ( from ) to another ( to ). Note that value may be zero.","title":"Transfer"},{"location":"apis/smart-contracts/WNat/#ev_votepowercontractchanged","text":"Defined in VPToken ( Docs , Source ). event VotePowerContractChanged ( uint256 _contractType , address _oldContractAddress , address _newContractAddress ) Emitted when one of the vote power contracts is changed. It is used to track the history of VPToken -> VPContract / GovernanceVotePower associations (e.g. by external cleaners). Parameters Type Description _contractType uint256 0 = Read VPContract , 1 = Write VPContract , 2 = Governance vote power. _oldContractAddress address Contract address before change. _newContractAddress address Contract address after change.","title":"VotePowerContractChanged"},{"location":"apis/smart-contracts/WNat/#ev_withdrawal","text":"Defined in WNat ( Docs , Source ). event Withdrawal ( address src , uint256 amount ) Emitted when tokens have been unwrapped. Parameters Type Description src address The account that received the unwrapped tokens. amount uint256 The amount that was unwrapped.","title":"Withdrawal"},{"location":"apis/smart-contracts/WNat/#functions","text":"","title":"Functions"},{"location":"apis/smart-contracts/WNat/#fn_allowance_dd62ed3e","text":"Defined in IERC20 ( Source ). function allowance ( address owner , address spender ) external view returns ( uint256 ); Returns the remaining number of tokens that spender will be allowed to spend on behalf of owner through transferFrom . This is zero by default. This value changes when approve or transferFrom are called.","title":"allowance"},{"location":"apis/smart-contracts/WNat/#fn_approve_095ea7b3","text":"Defined in IERC20 ( Source ). function approve ( address spender , uint256 amount ) external returns ( bool ); Sets amount as the allowance of spender over the caller's tokens. Returns a boolean value indicating whether the operation succeeded. IMPORTANT: Beware that changing an allowance with this method brings the risk that someone may use both the old and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 Emits an Approval event.","title":"approve"},{"location":"apis/smart-contracts/WNat/#fn_balancehistorycleanup_f0e292c9","text":"Defined in CheckPointable ( Docs , Source ). function balanceHistoryCleanup ( address _owner , uint256 _count ) external returns ( uint256 ); Delete balance checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _owner address balance owner account address _count uint256 maximum number of checkpoints to delete Returns Type Description [0] uint256 the number of checkpoints deleted","title":"balanceHistoryCleanup"},{"location":"apis/smart-contracts/WNat/#fn_balanceof_70a08231","text":"Defined in IERC20 ( Source ). function balanceOf ( address account ) external view returns ( uint256 ); Returns the amount of tokens owned by account .","title":"balanceOf"},{"location":"apis/smart-contracts/WNat/#fn_balanceofat_4ee2cd7e","text":"Defined in VPToken ( Docs , Source ). function balanceOfAt ( address _owner , uint256 _blockNumber ) public view returns ( uint256 ); Queries the token balance of _owner at a specific _blockNumber . Parameters Type Description _owner address The address from which the balance will be retrieved. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256","title":"balanceOfAt"},{"location":"apis/smart-contracts/WNat/#fn_batchdelegate_dc4fcda7","text":"Defined in VPToken ( Docs , Source ). function batchDelegate ( address [] _delegatees , uint256 [] _bips ) external ; Undelegate all percentage delegations from the sender and then delegate corresponding _bips percentage of voting power from the sender to each member of the _delegatees array. Parameters Type Description _delegatees address[] The addresses of the new recipients. _bips uint256[] The percentages of voting power to be delegated expressed in basis points (1/100 of one percent). The sum of all _bips values must be at most 10000 (100%).","title":"batchDelegate"},{"location":"apis/smart-contracts/WNat/#fn_batchvotepowerofat_49e3c7e5","text":"Defined in VPToken ( Docs , Source ). function batchVotePowerOfAt ( address [] _owners , uint256 _blockNumber ) external view returns ( uint256 []); Return the vote power for several addresses. Parameters Type Description _owners address[] The list of addresses to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256[] Array of vote power for each queried address.","title":"batchVotePowerOfAt"},{"location":"apis/smart-contracts/WNat/#fn_cancelgovernancecall_67fc4029","text":"Defined in GovernedBase ( Docs , Source ). function cancelGovernanceCall ( bytes4 _selector ) external ; Cancel a timelocked governance call before it has been executed. Only governance can call this method. Parameters Type Description _selector bytes4 The method selector.","title":"cancelGovernanceCall"},{"location":"apis/smart-contracts/WNat/#fn_cleanupblocknumber_deea13e7","text":"Defined in VPToken ( Docs , Source ). function cleanupBlockNumber ( ) external view returns ( uint256 ); Get the current cleanup block number set with setCleanupBlockNumber . Returns Type Description [0] uint256 The currently set cleanup block number.","title":"cleanupBlockNumber"},{"location":"apis/smart-contracts/WNat/#fn_constructor_undefined","text":"Defined in WNat ( Docs , Source ). constructor ( address _governance , string _name , string _symbol ) public ; Construct an ERC20 token.","title":"constructor"},{"location":"apis/smart-contracts/WNat/#fn_decimals_313ce567","text":"Defined in VPToken ( Docs , Source ). function decimals ( ) public view returns ( uint8 ); Returns the number of decimals used to get its user representation. For example, if decimals equals 2, a balance of 505 tokens should be displayed to a user as 5.05 (505 / 10 2 ). Tokens usually opt for a value of 18, imitating the relationship between Ether and wei. This is the default value returned by this function, unless it's overridden. NOTE: This information is only used for display purposes: it in no way affects any of the arithmetic of the contract, including balanceOf and transfer . Should be compatible with ERC20 method.","title":"decimals"},{"location":"apis/smart-contracts/WNat/#fn_delegate_026e402b","text":"Defined in VPToken ( Docs , Source ). function delegate ( address _to , uint256 _bips ) external ; Delegate voting power to account _to from msg.sender , by percentage. Parameters Type Description _to address The address of the recipient. _bips uint256 The percentage of voting power to be delegated expressed in basis points (1/100 of one percent). Not cumulative: every call resets the delegation value (and a value of 0 revokes all previous delegations).","title":"delegate"},{"location":"apis/smart-contracts/WNat/#fn_delegateexplicit_d06dc3ad","text":"Defined in VPToken ( Docs , Source ). function delegateExplicit ( address _to , uint256 _amount ) external ; Explicitly delegate _amount voting power to account _to from msg.sender . Compare with delegate which delegates by percentage. Parameters Type Description _to address The address of the recipient. _amount uint256 An explicit vote power amount to be delegated. Not cumulative: every call resets the delegation value (and a value of 0 revokes all previous delegations).","title":"delegateExplicit"},{"location":"apis/smart-contracts/WNat/#fn_delegatesof_7de5b8ed","text":"Defined in VPToken ( Docs , Source ). function delegatesOf ( address _owner ) external view returns ( address [] _delegateAddresses , uint256 [] _bips , uint256 _count , uint256 _delegationMode ); Get the list of addresses to which _who is delegating, and their percentages. Parameters Type Description _owner address Returns Type Description _delegateAddresses address[] Positional array of addresses being delegated to. _bips uint256[] Positional array of delegation percents specified in basis points (1/100 of 1 percent). Each one matches the address in the same position in the _delegateAddresses array. _count uint256 The number of delegates. _delegationMode uint256 Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).","title":"delegatesOf"},{"location":"apis/smart-contracts/WNat/#fn_delegatesofat_ed475a79","text":"Defined in VPToken ( Docs , Source ). function delegatesOfAt ( address _owner , uint256 _blockNumber ) external view returns ( address [] _delegateAddresses , uint256 [] _bips , uint256 _count , uint256 _delegationMode ); Get the list of addresses to which _who is delegating, and their percentages, at the given block. Parameters Type Description _owner address _blockNumber uint256 The block number to query. Returns Type Description _delegateAddresses address[] Positional array of addresses being delegated to. _bips uint256[] Positional array of delegation percents specified in basis points (1/100 of 1 percent). Each one matches the address in the same position in the _delegateAddresses array. _count uint256 The number of delegates. _delegationMode uint256 Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).","title":"delegatesOfAt"},{"location":"apis/smart-contracts/WNat/#fn_delegationmodeof_f6837767","text":"Defined in VPToken ( Docs , Source ). function delegationModeOf ( address _who ) external view returns ( uint256 ); Get the delegation mode for account '_who'. This mode determines whether vote power is allocated by percentage or by explicit amount. Once the delegation mode is set, it can never be changed, even if all delegations are removed. Parameters Type Description _who address The address to get delegation mode. Returns Type Description [0] uint256 Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).","title":"delegationModeOf"},{"location":"apis/smart-contracts/WNat/#fn_deposit_d0e30db0","text":"Defined in WNat ( Docs , Source ). function deposit ( ) public payable ; Deposits native tokens and mints the same amount of WNAT tokens, which are added to the msg.sender 's balance. This operation is commonly known as \"wrapping\". Emits a Deposit event.","title":"deposit"},{"location":"apis/smart-contracts/WNat/#fn_depositto_b760faf9","text":"Defined in WNat ( Docs , Source ). function depositTo ( address _recipient ) external payable ; Deposits native tokens and mints the same amount of WNAT tokens, which are added to _recipient 's balance. This operation is commonly known as \"wrapping\". This is equivalent to using deposit followed by transfer . Emits a Deposit event. Parameters Type Description _recipient address The address to receive the minted WNAT .","title":"depositTo"},{"location":"apis/smart-contracts/WNat/#fn_executegovernancecall_5ff27079","text":"Defined in GovernedBase ( Docs , Source ). function executeGovernanceCall ( bytes4 _selector ) external ; Execute the timelocked governance calls once the timelock period expires. Only executor can call this method. Parameters Type Description _selector bytes4 The method selector (only one timelocked call per method is stored).","title":"executeGovernanceCall"},{"location":"apis/smart-contracts/WNat/#fn_governance_5aa6e675","text":"Defined in GovernedBase ( Docs , Source ). function governance ( ) public view returns ( address ); Returns the current effective governance address.","title":"governance"},{"location":"apis/smart-contracts/WNat/#fn_governancevotepower_8c2b8ae1","text":"Defined in VPToken ( Docs , Source ). function governanceVotePower ( ) external view returns ( contract IGovernanceVotePower ); When set, allows token owners to participate in governance voting and delegate governance vote power.","title":"governanceVotePower"},{"location":"apis/smart-contracts/WNat/#fn_name_06fdde03","text":"Defined in VPToken ( Docs , Source ). function name ( ) public view returns ( string ); Returns the name of the token. Should be compatible with ERC20 method.","title":"name"},{"location":"apis/smart-contracts/WNat/#fn_readvotepowercontract_9b3baa0e","text":"Defined in VPToken ( Docs , Source ). function readVotePowerContract ( ) external view returns ( contract IVPContractEvents ); Returns VPContract event interface used for read-only operations (view methods). The only non-view method that might be called on it is revokeDelegationAt . readVotePowerContract is almost always equal to writeVotePowerContract except during an upgrade from one VPContract to a new version (which should happen rarely or never and will be announced beforehand). Do not call any methods on VPContract directly. State changing methods are forbidden from direct calls. All methods are exposed via VPToken . This is the reason that this method returns IVPContractEvents . Use it only for listening to events and revoking.","title":"readVotePowerContract"},{"location":"apis/smart-contracts/WNat/#fn_receive_undefined","text":"Defined in WNat ( Docs , Source ). receive ( ) external payable ; A proxy for the deposit method.","title":"receive"},{"location":"apis/smart-contracts/WNat/#fn_revokedelegationat_bbd6fbf8","text":"Defined in VPToken ( Docs , Source ). function revokeDelegationAt ( address _who , uint256 _blockNumber ) public ; Revoke all delegation from sender to _who at given block. Only affects the reads via votePowerOfAtCached in the block _blockNumber . Block _blockNumber must be in the past. This method should be used only to prevent rogue delegate voting in the current voting block. To stop delegating use delegate / delegateExplicit with value of 0 or undelegateAll / undelegateAllExplicit . Parameters Type Description _who address Address of the delegatee. _blockNumber uint256 The block number at which to revoke delegation..","title":"revokeDelegationAt"},{"location":"apis/smart-contracts/WNat/#fn_setcleanercontract_f6a494af","text":"Defined in VPToken ( Docs , Source ). function setCleanerContract ( address _cleanerContract ) external ; Set the contract that is allowed to call history cleaning methods. Parameters Type Description _cleanerContract address Address of the cleanup contract. Usually this will be an instance of CleanupBlockNumberManager .","title":"setCleanerContract"},{"location":"apis/smart-contracts/WNat/#fn_setcleanupblocknumber_13de97f5","text":"Defined in VPToken ( Docs , Source ). function setCleanupBlockNumber ( uint256 _blockNumber ) external ; Set the cleanup block number. Historic data for the blocks before cleanupBlockNumber can be erased. History before that block should never be used since it can be inconsistent. In particular, cleanup block number must be lower than the current vote power block. Parameters Type Description _blockNumber uint256 The new cleanup block number.","title":"setCleanupBlockNumber"},{"location":"apis/smart-contracts/WNat/#fn_setcleanupblocknumbermanager_7f4fcaa9","text":"Defined in VPToken ( Docs , Source ). function setCleanupBlockNumberManager ( address _cleanupBlockNumberManager ) external ; Set the contract that is allowed to set cleanupBlockNumber . Usually this will be an instance of CleanupBlockNumberManager .","title":"setCleanupBlockNumberManager"},{"location":"apis/smart-contracts/WNat/#fn_setgovernancevotepower_9ca2231a","text":"Defined in VPToken ( Docs , Source ). function setGovernanceVotePower ( contract IIGovernanceVotePower _governanceVotePower ) external ; Sets new governance vote power contract that allows token owners to participate in governance voting and delegate governance vote power.","title":"setGovernanceVotePower"},{"location":"apis/smart-contracts/WNat/#fn_setreadvpcontract_31d12a16","text":"Defined in VPToken ( Docs , Source ). function setReadVpContract ( contract IIVPContract _vpContract ) external ; Call from governance to set read VpContract on token, e.g. vpToken. setReadVpContract (new VPContract (vpToken)). Read VPContract must be set before any of the VPToken delegation or vote power reading methods are called, otherwise they will revert. NOTE : If readVpContract differs from writeVpContract all reads will be \"frozen\" and will not reflect changes (not even revokes; they may or may not reflect balance transfers). Parameters Type Description _vpContract contract IIVPContract Read vote power contract to be used by this token.","title":"setReadVpContract"},{"location":"apis/smart-contracts/WNat/#fn_setwritevpcontract_755d10a4","text":"Defined in VPToken ( Docs , Source ). function setWriteVpContract ( contract IIVPContract _vpContract ) external ; Call from governance to set write VpContract on token, e.g. vpToken. setWriteVpContract (new VPContract (vpToken)). Write VPContract must be set before any of the VPToken delegation modifying methods are called, otherwise they will revert. Parameters Type Description _vpContract contract IIVPContract Write vote power contract to be used by this token.","title":"setWriteVpContract"},{"location":"apis/smart-contracts/WNat/#fn_switchtoproductionmode_f5a98383","text":"Defined in GovernedBase ( Docs , Source ). function switchToProductionMode ( ) external ; Enter the production mode after all the initial governance settings have been set. This enables timelocks and the governance can be obtained afterward by calling governanceSettings .getGovernanceAddress(). Emits GovernedProductionModeEntered .","title":"switchToProductionMode"},{"location":"apis/smart-contracts/WNat/#fn_symbol_95d89b41","text":"Defined in VPToken ( Docs , Source ). function symbol ( ) public view returns ( string ); Returns the symbol of the token, usually a shorter version of the name . Should be compatible with ERC20 method.","title":"symbol"},{"location":"apis/smart-contracts/WNat/#fn_totalsupply_18160ddd","text":"Defined in IERC20 ( Source ). function totalSupply ( ) external view returns ( uint256 ); Returns the amount of tokens in existence.","title":"totalSupply"},{"location":"apis/smart-contracts/WNat/#fn_totalsupplyat_981b24d0","text":"Defined in VPToken ( Docs , Source ). function totalSupplyAt ( uint256 _blockNumber ) public view returns ( uint256 ); Total amount of tokens at a specific _blockNumber . Parameters Type Description _blockNumber uint256 The block number when the _totalSupply is queried Returns Type Description [0] uint256","title":"totalSupplyAt"},{"location":"apis/smart-contracts/WNat/#fn_totalsupplycachecleanup_43ea370b","text":"Defined in CheckPointable ( Docs , Source ). function totalSupplyCacheCleanup ( uint256 _blockNumber ) external returns ( uint256 ); Delete total supply cache entry that expired (i.e. is before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _blockNumber uint256 the block number for which total supply value was cached Returns Type Description [0] uint256 the number of cache entries deleted (always 0 or 1)","title":"totalSupplyCacheCleanup"},{"location":"apis/smart-contracts/WNat/#fn_totalsupplyhistorycleanup_f62f8f3a","text":"Defined in CheckPointable ( Docs , Source ). function totalSupplyHistoryCleanup ( uint256 _count ) external returns ( uint256 ); Delete total supply checkpoints that expired (i.e. are before cleanupBlockNumber ). Method can only be called from the cleanerContract (which may be a proxy to external cleaners). Parameters Type Description _count uint256 maximum number of checkpoints to delete Returns Type Description [0] uint256 the number of checkpoints deleted","title":"totalSupplyHistoryCleanup"},{"location":"apis/smart-contracts/WNat/#fn_totalvotepower_f5f3d4f7","text":"Defined in VPToken ( Docs , Source ). function totalVotePower ( ) external view returns ( uint256 ); Get the current total vote power. Returns Type Description [0] uint256 The current total vote power (sum of all accounts' vote power).","title":"totalVotePower"},{"location":"apis/smart-contracts/WNat/#fn_totalvotepowerat_3e5aa26a","text":"Defined in VPToken ( Docs , Source ). function totalVotePowerAt ( uint256 _blockNumber ) external view returns ( uint256 ); Get the total vote power at block _blockNumber . Parameters Type Description _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The total vote power at the queried block (sum of all accounts' vote powers).","title":"totalVotePowerAt"},{"location":"apis/smart-contracts/WNat/#fn_totalvotepoweratcached_caeb942b","text":"Defined in VPToken ( Docs , Source ). function totalVotePowerAtCached ( uint256 _blockNumber ) public returns ( uint256 ); Get the total vote power at block _blockNumber using cache. It tries to read the cached value and if it is not found, reads the actual value and stores it in the cache. Can only be used if _blockNumber is in the past, otherwise reverts. Parameters Type Description _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The total vote power at the queried block (sum of all accounts' vote powers).","title":"totalVotePowerAtCached"},{"location":"apis/smart-contracts/WNat/#fn_transfer_a9059cbb","text":"Defined in IERC20 ( Source ). function transfer ( address recipient , uint256 amount ) external returns ( bool ); Moves amount tokens from the caller's account to recipient . Returns a boolean value indicating whether the operation succeeded. Emits a Transfer event.","title":"transfer"},{"location":"apis/smart-contracts/WNat/#fn_transferfrom_23b872dd","text":"Defined in IERC20 ( Source ). function transferFrom ( address sender , address recipient , uint256 amount ) external returns ( bool ); Moves amount tokens from sender to recipient using the allowance mechanism. amount is then deducted from the caller's allowance . Returns a boolean value indicating whether the operation succeeded. Emits a Transfer event.","title":"transferFrom"},{"location":"apis/smart-contracts/WNat/#fn_undelegateall_b302f393","text":"Defined in VPToken ( Docs , Source ). function undelegateAll ( ) external ; Undelegate all voting power of msg.sender . This effectively revokes all previous delegations. Can only be used with percentage delegation. Does not reset delegation mode back to NOT SET.","title":"undelegateAll"},{"location":"apis/smart-contracts/WNat/#fn_undelegateallexplicit_5d6d11eb","text":"Defined in VPToken ( Docs , Source ). function undelegateAllExplicit ( address [] _delegateAddresses ) external returns ( uint256 _remainingDelegation ); Undelegate all explicit vote power by amount of msg.sender . Can only be used with explicit delegation. Does not reset delegation mode back to NOT SET. Parameters Type Description _delegateAddresses address[] Explicit delegation does not store delegatees' addresses, so the caller must supply them. Returns Type Description _remainingDelegation uint256 The amount still delegated (in case the list of delegates was incomplete).","title":"undelegateAllExplicit"},{"location":"apis/smart-contracts/WNat/#fn_undelegatedvotepowerof_d6aa0b77","text":"Defined in VPToken ( Docs , Source ). function undelegatedVotePowerOf ( address _owner ) external view returns ( uint256 ); Compute the current undelegated vote power of the _owner account. Parameters Type Description _owner address The address to query. Returns Type Description [0] uint256 The unallocated vote power of _owner .","title":"undelegatedVotePowerOf"},{"location":"apis/smart-contracts/WNat/#fn_undelegatedvotepowerofat_83035a82","text":"Defined in VPToken ( Docs , Source ). function undelegatedVotePowerOfAt ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Get the undelegated vote power of the _owner account at a given block number. Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The unallocated vote power of _owner .","title":"undelegatedVotePowerOfAt"},{"location":"apis/smart-contracts/WNat/#fn_votepowerfromto_be0ca747","text":"Defined in VPToken ( Docs , Source ). function votePowerFromTo ( address _from , address _to ) external view returns ( uint256 ); Get current delegated vote power from delegator _from to delegatee _to . Parameters Type Description _from address Address of delegator. _to address Address of delegatee. Returns Type Description [0] uint256 votePower The delegated vote power.","title":"votePowerFromTo"},{"location":"apis/smart-contracts/WNat/#fn_votepowerfromtoat_e64767aa","text":"Defined in VPToken ( Docs , Source ). function votePowerFromToAt ( address _from , address _to , uint256 _blockNumber ) external view returns ( uint256 ); Get delegated vote power from delegator _from to delegatee _to at _blockNumber . Parameters Type Description _from address Address of delegator. _to address Address of delegatee. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 The delegated vote power.","title":"votePowerFromToAt"},{"location":"apis/smart-contracts/WNat/#fn_votepowerof_142d1018","text":"Defined in VPToken ( Docs , Source ). function votePowerOf ( address _owner ) external view returns ( uint256 ); Get the current vote power of _owner . Parameters Type Description _owner address The address to query. Returns Type Description [0] uint256 Current vote power of _owner .","title":"votePowerOf"},{"location":"apis/smart-contracts/WNat/#fn_votepowerofat_92bfe6d8","text":"Defined in VPToken ( Docs , Source ). function votePowerOfAt ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Get the vote power of _owner at block _blockNumber Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 Vote power of _owner at block number _blockNumber .","title":"votePowerOfAt"},{"location":"apis/smart-contracts/WNat/#fn_votepowerofatcached_e587497e","text":"Defined in VPToken ( Docs , Source ). function votePowerOfAtCached ( address _owner , uint256 _blockNumber ) public returns ( uint256 ); Get the vote power of _owner at block _blockNumber using cache. It tries to read the cached value and if it is not found, reads the actual value and stores it in the cache. Can only be used if _blockNumber is in the past, otherwise reverts. Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 Vote power of _owner at _blockNumber .","title":"votePowerOfAtCached"},{"location":"apis/smart-contracts/WNat/#fn_votepowerofatignoringrevocation_04bb4e43","text":"Defined in VPToken ( Docs , Source ). function votePowerOfAtIgnoringRevocation ( address _owner , uint256 _blockNumber ) external view returns ( uint256 ); Get the vote power of _owner at block _blockNumber , ignoring revocation information (and cache). Parameters Type Description _owner address The address to query. _blockNumber uint256 The block number to query. Returns Type Description [0] uint256 Vote power of _owner at block number _blockNumber . Result doesn't change if vote power is revoked.","title":"votePowerOfAtIgnoringRevocation"},{"location":"apis/smart-contracts/WNat/#fn_withdraw_2e1a7d4d","text":"Defined in WNat ( Docs , Source ). function withdraw ( uint256 _amount ) external ; Burns _amount of WNAT tokens from msg.sender 's WNAT balance and transfers the same amount of native tokens to msg.sender . This operation is commonly known as \"unwrapping\". Reverts if _amount is higher than msg.sender 's WNAT balance. Emits a Withdrawal event. Parameters Type Description _amount uint256 The amount to withdraw.","title":"withdraw"},{"location":"apis/smart-contracts/WNat/#fn_withdrawfrom_9470b0bd","text":"Defined in WNat ( Docs , Source ). function withdrawFrom ( address _owner , uint256 _amount ) external ; Burns _amount of WNAT tokens from _owner 's WNAT balance and transfers the same amount of native tokens to msg.sender . This operation is commonly known as \"unwrapping\". msg.sender must have been authorized to withdraw from _owner 's account through ERC-20's approve mechanism. Reverts if _amount is higher than _owners 's WNAT balance or than msg.sender 's allowance over _owner 's tokens. Emits a Withdrawal event. Parameters Type Description _owner address The address containing the tokens to withdraw. _amount uint256 The amount to withdraw.","title":"withdrawFrom"},{"location":"apis/smart-contracts/WNat/#fn_writevotepowercontract_1fec092a","text":"Defined in VPToken ( Docs , Source ). function writeVotePowerContract ( ) external view returns ( contract IVPContractEvents ); Returns VPContract event interface used for state-changing operations (non-view methods). The only non-view method that might be called on it is revokeDelegationAt . writeVotePowerContract is almost always equal to readVotePowerContract , except during upgrade from one VPContract to a new version (which should happen rarely or never and will be announced beforehand). In the case of an upgrade, writeVotePowerContract is replaced first to establish delegations. After some period (e.g., after a reward epoch ends), readVotePowerContract is set equal to it. Do not call any methods on VPContract directly. State changing methods are forbidden from direct calls. All are exposed via VPToken . This is the reason that this method returns IVPContractEvents Use it only for listening to events, delegating, and revoking.","title":"writeVotePowerContract"},{"location":"dev/","text":"Developer Docs # Quick links Network Configuration Flare Contracts Addresses How to run a node All Flare networks are a fork of the Avalanche project, which runs the Ethereum Virtual Machine . Therefore, all Ethereum contracts and tools work on Flare, Songbird and Coston. All Flare networks are layer-1 networks, and run independently of both Avalanche and Ethereum. You can interact with the Flare networks using wallets , block explorers and the most common blockchain development environments . As an example, all Flare networks support NFTs and many have already been created on Songbird. The block explorer also supports displaying NFTs. Once you have set up your development environment , you can start with the Accessing the Network tutorials. Open-Source Repositories # These are Flare's main source repositories, both on GitHub and GitLab . Validator node Smart contracts Topics # Getting Started Tutorials Reference Guides External Learning Resources Tools and Projects","title":"Developer Docs"},{"location":"dev/#developer-docs","text":"Quick links Network Configuration Flare Contracts Addresses How to run a node All Flare networks are a fork of the Avalanche project, which runs the Ethereum Virtual Machine . Therefore, all Ethereum contracts and tools work on Flare, Songbird and Coston. All Flare networks are layer-1 networks, and run independently of both Avalanche and Ethereum. You can interact with the Flare networks using wallets , block explorers and the most common blockchain development environments . As an example, all Flare networks support NFTs and many have already been created on Songbird. The block explorer also supports displaying NFTs. Once you have set up your development environment , you can start with the Accessing the Network tutorials.","title":"Developer Docs"},{"location":"dev/#open-source-repositories","text":"These are Flare's main source repositories, both on GitHub and GitLab . Validator node Smart contracts","title":"Open-Source Repositories"},{"location":"dev/#topics","text":"Getting Started Tutorials Reference Guides External Learning Resources Tools and Projects","title":"Topics"},{"location":"dev/external-resources/","text":"External Learning Resources # Curated list of resources you can use to extend your knowledge of the Flare network. Tutorials # Filip Koprivec's Flare Tutorials on Medium Videos # Tim Rowley's Explainer Videos on YouTube FTSO (Flare Time Series Oracle) | Learn how to Query Prices on Flare","title":"External Learning Resources"},{"location":"dev/external-resources/#external-learning-resources","text":"Curated list of resources you can use to extend your knowledge of the Flare network.","title":"External Learning Resources"},{"location":"dev/external-resources/#tutorials","text":"Filip Koprivec's Flare Tutorials on Medium","title":"Tutorials"},{"location":"dev/external-resources/#videos","text":"Tim Rowley's Explainer Videos on YouTube FTSO (Flare Time Series Oracle) | Learn how to Query Prices on Flare","title":"Videos"},{"location":"dev/tools/","text":"Tools and Projects # The following tools and projects already support the Flare network. Indexing and Querying # Blockchains typically store the history of all transactions but not the latest, consolidated state of individual accounts. The companies below provide fast access to this information Covalent SubQuery Monitoring Tools # These tools report information about Flare networks: Flare Builders FlareMetrics Validators, presented by Towo Labs Node Providers # Validator nodes are online servers running a blockchain's client software. They ensure that stored data is consistent and provide access to this data for applications. Applications are encouraged to deploy their own nodes for enhanced reliability. The companies below offer nodes-as-a-service, greatly simplifying deployment and operational costs. Flare API Portal Blockdaemon Ankr Storage # Storing large amounts of data on-chain is typically very expensive. These are some decentralized storage alternatives. Filecoin IPFS Crust Network Pinata Lighthouse Arweave Wallets # Please see the Wallet user guides for a list of wallets currently supporting the Flare network.","title":"Tools and Projects"},{"location":"dev/tools/#tools-and-projects","text":"The following tools and projects already support the Flare network.","title":"Tools and Projects"},{"location":"dev/tools/#indexing-and-querying","text":"Blockchains typically store the history of all transactions but not the latest, consolidated state of individual accounts. The companies below provide fast access to this information Covalent SubQuery","title":"Indexing and Querying"},{"location":"dev/tools/#monitoring-tools","text":"These tools report information about Flare networks: Flare Builders FlareMetrics Validators, presented by Towo Labs","title":"Monitoring Tools"},{"location":"dev/tools/#node-providers","text":"Validator nodes are online servers running a blockchain's client software. They ensure that stored data is consistent and provide access to this data for applications. Applications are encouraged to deploy their own nodes for enhanced reliability. The companies below offer nodes-as-a-service, greatly simplifying deployment and operational costs. Flare API Portal Blockdaemon Ankr","title":"Node Providers"},{"location":"dev/tools/#storage","text":"Storing large amounts of data on-chain is typically very expensive. These are some decentralized storage alternatives. Filecoin IPFS Crust Network Pinata Lighthouse Arweave","title":"Storage"},{"location":"dev/tools/#wallets","text":"Please see the Wallet user guides for a list of wallets currently supporting the Flare network.","title":"Wallets"},{"location":"dev/getting-started/","text":"Getting Started # The following guides provide information to quickly start developing on the Flare networks. Guides # Setting Up Your Environment Retrieving Contract Addresses","title":"Getting Started"},{"location":"dev/getting-started/#getting-started","text":"The following guides provide information to quickly start developing on the Flare networks.","title":"Getting Started"},{"location":"dev/getting-started/#guides","text":"Setting Up Your Environment Retrieving Contract Addresses","title":"Guides"},{"location":"dev/getting-started/contract-addresses/","text":"Retrieving Contract Addresses # Attention Developers should never rely on contract addresses gathered from off-chain sources like direct messages, social media, or even websites, as these addresses could easily lead to malicious contracts. For this reason, this documentation does not provide any contract address except for the single entry point described below. The only secure way to retrieve contract addresses is from the blockchain itself . As a convenience, though, Flare's smart contract repository contains the latest deployment address for all Flare's smart contracts. These addresses can be used to speed up development, but should not be used in production. To emphasize: Applications are strongly encouraged to retrieve any contract address they need directly from the blockchain and not have addresses hard-coded into the source code, except for the single entry point given in this page. Retrieval from Blockchain # All of Flare's smart contract addresses can be retrieved from the FlareContractRegistry contract. This is the only contract address given in this documentation. FlareContractRegistry 0xaD67FE66660Fb8dFE9d6b1b4240d8650e30F6019 This contract is available at the same address in all Flare networks: Flare, Songbird, Coston and Coston2. Copy the above address into the Block Explorer to see the available contract's methods. You can retrieve the current address on the blockchain of any Flare smart contract from its name by using these methods, for example: function getContractAddressByName ( string calldata _name ) external view returns ( address ); function getContractAddressesByName ( string [] calldata _names ) external view returns ( address [] memory ); The name search is case-sensitive , so you should use the proper capitalization. For example: WNat FtsoRewardManager PriceSubmitter Applications can also retrieve all smart contract names and addresses at once using: function getAllContracts ( ) external view returns ( string [] memory _names , address [] memory _addresses ); Retrieve current list Retrieval from Source Code # The Flare Smart Contracts repository contains an autogenerated JSON file listing the latest deployed addresses of all Flare contracts on each network. You can find this file in the deployment/deploys folder, and parse it to retrieve the addresses of any Flare contract. Attention As stated at the beginning, applications should NOT have Flare contract addresses in their source code. Instead, applications are strongly encouraged to retrieve any contract address they need directly from the blockchain as described above . Branch JSON file Flare flare_network_deployed_code flare.json Songbird songbird_network_deployed_code songbird.json Coston coston_network_deployed_code coston.json Coston2 coston2_network_deployed_code coston2.json const button = document.getElementById(\"contract-list-button\"); const list = document.getElementById(\"contract-list-results\"); button.addEventListener(\"click\", (e) => { e.preventDefault(); button.style.display = \"none\"; list.innerHTML = \"Retrieving...\"; import(\"/assets/javascripts/ethers-6.3.esm.min.js\").then(ethers => { const provider = new ethers.JsonRpcProvider(\"https://flare-api.flare.network/ext/C/rpc\"); const flareContractRegistry = new ethers.Contract( \"0xaD67FE66660Fb8dFE9d6b1b4240d8650e30F6019\", [\"function getAllContracts() external view returns(string[] memory, address[] memory)\"], provider); const res = flareContractRegistry.getAllContracts().then(res => { list.innerHTML = \"Current smart contract list:\"; var ul=document.createElement('ul'); for (var i = 0; i < res[0].length; ++i) { var li = document.createElement('li'); li.innerHTML = `${res[0][i]}`; ul.appendChild(li); } list.appendChild(ul); }); }); });","title":"Retrieving Contract Addresses"},{"location":"dev/getting-started/contract-addresses/#retrieving-contract-addresses","text":"Attention Developers should never rely on contract addresses gathered from off-chain sources like direct messages, social media, or even websites, as these addresses could easily lead to malicious contracts. For this reason, this documentation does not provide any contract address except for the single entry point described below. The only secure way to retrieve contract addresses is from the blockchain itself . As a convenience, though, Flare's smart contract repository contains the latest deployment address for all Flare's smart contracts. These addresses can be used to speed up development, but should not be used in production. To emphasize: Applications are strongly encouraged to retrieve any contract address they need directly from the blockchain and not have addresses hard-coded into the source code, except for the single entry point given in this page.","title":"Retrieving Contract Addresses"},{"location":"dev/getting-started/contract-addresses/#retrieval-from-blockchain","text":"All of Flare's smart contract addresses can be retrieved from the FlareContractRegistry contract. This is the only contract address given in this documentation. FlareContractRegistry 0xaD67FE66660Fb8dFE9d6b1b4240d8650e30F6019 This contract is available at the same address in all Flare networks: Flare, Songbird, Coston and Coston2. Copy the above address into the Block Explorer to see the available contract's methods. You can retrieve the current address on the blockchain of any Flare smart contract from its name by using these methods, for example: function getContractAddressByName ( string calldata _name ) external view returns ( address ); function getContractAddressesByName ( string [] calldata _names ) external view returns ( address [] memory ); The name search is case-sensitive , so you should use the proper capitalization. For example: WNat FtsoRewardManager PriceSubmitter Applications can also retrieve all smart contract names and addresses at once using: function getAllContracts ( ) external view returns ( string [] memory _names , address [] memory _addresses ); Retrieve current list","title":"Retrieval from Blockchain"},{"location":"dev/getting-started/contract-addresses/#retrieval-from-source-code","text":"The Flare Smart Contracts repository contains an autogenerated JSON file listing the latest deployed addresses of all Flare contracts on each network. You can find this file in the deployment/deploys folder, and parse it to retrieve the addresses of any Flare contract. Attention As stated at the beginning, applications should NOT have Flare contract addresses in their source code. Instead, applications are strongly encouraged to retrieve any contract address they need directly from the blockchain as described above . Branch JSON file Flare flare_network_deployed_code flare.json Songbird songbird_network_deployed_code songbird.json Coston coston_network_deployed_code coston.json Coston2 coston2_network_deployed_code coston2.json const button = document.getElementById(\"contract-list-button\"); const list = document.getElementById(\"contract-list-results\"); button.addEventListener(\"click\", (e) => { e.preventDefault(); button.style.display = \"none\"; list.innerHTML = \"Retrieving...\"; import(\"/assets/javascripts/ethers-6.3.esm.min.js\").then(ethers => { const provider = new ethers.JsonRpcProvider(\"https://flare-api.flare.network/ext/C/rpc\"); const flareContractRegistry = new ethers.Contract( \"0xaD67FE66660Fb8dFE9d6b1b4240d8650e30F6019\", [\"function getAllContracts() external view returns(string[] memory, address[] memory)\"], provider); const res = flareContractRegistry.getAllContracts().then(res => { list.innerHTML = \"Current smart contract list:\"; var ul=document.createElement('ul'); for (var i = 0; i < res[0].length; ++i) { var li = document.createElement('li'); li.innerHTML = `${res[0][i]}`; ul.appendChild(li); } list.appendChild(ul); }); }); });","title":"Retrieval from Source Code"},{"location":"dev/getting-started/setup/","text":"Setting Up Your Environment # The following guides provide information to quickly set up a smart contract development environment. Guides # Using Remix Using Hardhat Using Truffle Using Foundry","title":"Setting Up Your Environment"},{"location":"dev/getting-started/setup/#setting-up-your-environment","text":"The following guides provide information to quickly set up a smart contract development environment.","title":"Setting Up Your Environment"},{"location":"dev/getting-started/setup/#guides","text":"Using Remix Using Hardhat Using Truffle Using Foundry","title":"Guides"},{"location":"dev/getting-started/setup/foundry/","text":"Setting Up Your Environment Using Foundry # Foundry is a fast, portable and modular testing and deployment tool for developing EVM smart contracts. Tests are written in Solidity to keep the workflow consistent with smart contract development and testing before deployments. Foundry itself is written in Rust. This article, partially based on the Foundry documentation , shows how to set up Foundry and use it to build and deploy smart contracts on Flare. Guide # 1. Set up the Environment # Follow the instructions for your operating system in the Foundry's Installation guide . 2. Create a Foundry Project # Foundry can quick-start your development by providing a sample project: forge init hello_foundry This creates a new directory hello_foundry from the default template which should look something like this: Foundry project structure. 3. Build the Contract # To build the Counter.sol contract in the sample project run: cd hello_foundry forge build When done, it should print Compiler run successful . You will notice that two new directories have been created, out and cache : Foundry project after build. The out directory contains your contract artifact, such as the ABI, while the cache is used by forge to only recompile what is necessary. 4. Test the Contract # In the test folder you should find a ready-made test file that verifies the contract works as expected. To run tests with Foundry, you just need to run: forge test When finished, it should print something similar to Test result: ok. 2 passed; 0 failed; finished in 24.43ms . Info Learn more about Advanced Testing using Foundry . 5. Deploy the Contract # Forge can deploy only one contract at a time to a given network. To do so, you must provide the URL of the RPC node to access the network, and the private key of the account that will deploy the contract. The URL can be stored in an environment variable named FOUNDRY_ETH_RPC_URL) so you do not need to supply it every time. Important You are going to deploy the contract on the Coston 2 network . Make sure you have enough C2FLR in the account that will deploy the contract to pay the gas fees! You can add C2FLR to any account using the Coston 2 Faucet . The general Foundry command to deploy a contract is: forge create --rpc-url \\ --private-key \\ : Since Solidity files may contain multiple contracts, the : parameter specifies which contract to deploy from the source file. Learn more about Deploying and Verifying Smart Contracts using Foundry . To deploy the sample Counter contract to Flare's Coston 2 Network, run: forge create --rpc-url https://coston2-api.flare.network/ext/C/rpc \\ --private-key d8936f6eae35c73a14ea7c1aabb8d068e16889a7f516c8abc482ba4e1489f4cd \\ src/Counter.sol:Counter Using the private key for your account. Execution should look similar to this: Foundry project deployment. You can check the status of the contract by copy and pasting the Deployed to: address into the Coston 2 Block Explorer . Info Learn more about Deploying and Verifying Smart Contracts using Foundry !","title":"Using Foundry"},{"location":"dev/getting-started/setup/foundry/#setting-up-your-environment-using-foundry","text":"Foundry is a fast, portable and modular testing and deployment tool for developing EVM smart contracts. Tests are written in Solidity to keep the workflow consistent with smart contract development and testing before deployments. Foundry itself is written in Rust. This article, partially based on the Foundry documentation , shows how to set up Foundry and use it to build and deploy smart contracts on Flare.","title":"Setting Up Your Environment Using Foundry"},{"location":"dev/getting-started/setup/foundry/#guide","text":"","title":"Guide"},{"location":"dev/getting-started/setup/foundry/#1-set-up-the-environment","text":"Follow the instructions for your operating system in the Foundry's Installation guide .","title":"1. Set up the Environment"},{"location":"dev/getting-started/setup/foundry/#2-create-a-foundry-project","text":"Foundry can quick-start your development by providing a sample project: forge init hello_foundry This creates a new directory hello_foundry from the default template which should look something like this: Foundry project structure.","title":"2. Create a Foundry Project"},{"location":"dev/getting-started/setup/foundry/#3-build-the-contract","text":"To build the Counter.sol contract in the sample project run: cd hello_foundry forge build When done, it should print Compiler run successful . You will notice that two new directories have been created, out and cache : Foundry project after build. The out directory contains your contract artifact, such as the ABI, while the cache is used by forge to only recompile what is necessary.","title":"3. Build the Contract"},{"location":"dev/getting-started/setup/foundry/#4-test-the-contract","text":"In the test folder you should find a ready-made test file that verifies the contract works as expected. To run tests with Foundry, you just need to run: forge test When finished, it should print something similar to Test result: ok. 2 passed; 0 failed; finished in 24.43ms . Info Learn more about Advanced Testing using Foundry .","title":"4. Test the Contract"},{"location":"dev/getting-started/setup/foundry/#5-deploy-the-contract","text":"Forge can deploy only one contract at a time to a given network. To do so, you must provide the URL of the RPC node to access the network, and the private key of the account that will deploy the contract. The URL can be stored in an environment variable named FOUNDRY_ETH_RPC_URL) so you do not need to supply it every time. Important You are going to deploy the contract on the Coston 2 network . Make sure you have enough C2FLR in the account that will deploy the contract to pay the gas fees! You can add C2FLR to any account using the Coston 2 Faucet . The general Foundry command to deploy a contract is: forge create --rpc-url \\ --private-key \\ : Since Solidity files may contain multiple contracts, the : parameter specifies which contract to deploy from the source file. Learn more about Deploying and Verifying Smart Contracts using Foundry . To deploy the sample Counter contract to Flare's Coston 2 Network, run: forge create --rpc-url https://coston2-api.flare.network/ext/C/rpc \\ --private-key d8936f6eae35c73a14ea7c1aabb8d068e16889a7f516c8abc482ba4e1489f4cd \\ src/Counter.sol:Counter Using the private key for your account. Execution should look similar to this: Foundry project deployment. You can check the status of the contract by copy and pasting the Deployed to: address into the Coston 2 Block Explorer . Info Learn more about Deploying and Verifying Smart Contracts using Foundry !","title":"5. Deploy the Contract"},{"location":"dev/getting-started/setup/hardhat/","text":"Setting Up Your Environment Using Hardhat # Hardhat is an environment developers use to test, compile, deploy and debug dapps based on any blockchain compatible Ethereum's EVM . Hardhat is a flexible and extensible task runner that helps you manage and automate the recurring tasks inherent to developing smart contracts and dapps. This article, partially based on the Hardhat documentation shows you how to set up Hardhat and use it to build, test and deploy smart contracts on Flare. Guide # 1. Set up the Environment # Install the following dependencies: NodeJSv12+ LTS and npm/Yarn Package Installer . Tip Check the Official Guide by Hardhat if you have issues installing this package. Once the above dependencies are installed, create an npm empty project by running the following commands in a terminal: mkdir flare-tutorial cd flare-tutorial npm init Press Enter on each of the prompts. Finally, add Hardhat and a few dependencies to the project, since you will use them in this tutorial. npm install --save-dev \\ hardhat \\ @nomicfoundation/hardhat-toolbox \\ @nomiclabs/hardhat-ethers \\ dotenv 2. Create a Hardhat Project # Hardhat can quick-start your development by providing a sample project. Just run: npx hardhat You should see the following prompt: Hardhat project creation prompt. Choose the Create a JavaScript project with the Up and Down keys, and Press Enter . Then press Y for rest of the prompts. When done, it should print Project created . If you take a look in the contracts folder, you should find a sample source file called Lock.sol . It is a Solidity smart contract implementing a simple digital lock, where users can only withdraw funds after a given period of time: // SPDX-License-Identifier: UNLICENSED pragma solidity ^ 0.8.9 ; // Uncomment this line to use console.log // import \"hardhat/console.sol\"; contract Lock { uint public unlockTime ; address payable public owner ; event Withdrawal ( uint amount , uint when ); constructor ( uint _unlockTime ) payable { require ( block.timestamp < _unlockTime , \"Unlock time should be in the future\" ); unlockTime = _unlockTime ; owner = payable ( msg.sender ); } function withdraw () public { // Uncomment this line, and the import of \"hardhat/console.sol\", to print a log in your terminal // console.log(\"Unlock time is %o and block timestamp is %o\", unlockTime, block.timestamp); require ( block.timestamp >= unlockTime , \"You can't withdraw yet\" ); require ( msg.sender == owner , \"You aren't the owner\" ); emit Withdrawal ( address ( this ). balance , block.timestamp ); owner . transfer ( address ( this ). balance ); } } 3. Compile the Contracts # To compile the sample project, simply run: npx hardhat compile Upon successful compilation it will print Compiled 1 Solidity file successfully . 4. Configure the Project # In order to be deployed on any of the Flare networks , the project needs to be configured. Edit the hardhat.config.js file and replace its contents with the following: require ( 'dotenv' ). config (); require ( \"@nomicfoundation/hardhat-toolbox\" ); require ( '@nomiclabs/hardhat-ethers' ); /** @type import('hardhat/config').HardhatUserConfig */ module . exports = { solidity : \"0.8.17\" , networks : { hardhat : { }, coston : { url : \"https://coston-api.flare.network/ext/bc/C/rpc\" , accounts : [ process . env . PRIVATE_KEY ], chainId : 16 }, songbird : { url : \"https://songbird-api.flare.network/ext/bc/C/rpc\" , accounts : [ process . env . PRIVATE_KEY ], chainId : 19 }, coston2 : { url : \"https://coston2-api.flare.network/ext/C/rpc\" , accounts : [ process . env . PRIVATE_KEY ], chainId : 114 , }, flare : { url : \"https://flare-api.flare.network/ext/C/rpc\" , accounts : [ process . env . PRIVATE_KEY ], chainId : 14 , } }, }; Then, create a file called .env at the root of you project (where the hardhat.config.js file resides) to store the private key for the account to use for testing. .env files are useful to store local information which should not be committed into the source repository. In this tutorial, you need to store your test account's private key in this format: PRIVATE_KEY = \"0x0000000000000000000000000000000000000000000000000000000000000000\" That is, 64 hexadecimal characters after the 0x . Caution Make sure you never upload your .env file to a remote repository. For this reason, the .gitignore file that Hardhat created for you already ignores .env files. 5. Test the Contract # In the test folder you should find a ready-made test file that verifies the contract works as expected. To run tests with Hardhat, you just need to run: npx hardhat test You should get: Lock contract test results. 6. Deploy the Contract # Finally, you will deploy the contract to Flare's test network, Coston2 , using a Hardhat script from the scripts folder. Run this command in the root of the project: npx hardhat run scripts/deploy.js --network coston2 You should get an output similar to: Lock with 1 ETH and unlock timestamp 1705592309 deployed to 0xdC7781FA9fA7e2d0313cd0229a5080B4e30663a5 The last part is the address where the contract has been deployed. You can check the status of the contract by copy and pasting this address in the Block Explorer .","title":"Using Hardhat"},{"location":"dev/getting-started/setup/hardhat/#setting-up-your-environment-using-hardhat","text":"Hardhat is an environment developers use to test, compile, deploy and debug dapps based on any blockchain compatible Ethereum's EVM . Hardhat is a flexible and extensible task runner that helps you manage and automate the recurring tasks inherent to developing smart contracts and dapps. This article, partially based on the Hardhat documentation shows you how to set up Hardhat and use it to build, test and deploy smart contracts on Flare.","title":"Setting Up Your Environment Using Hardhat"},{"location":"dev/getting-started/setup/hardhat/#guide","text":"","title":"Guide"},{"location":"dev/getting-started/setup/hardhat/#1-set-up-the-environment","text":"Install the following dependencies: NodeJSv12+ LTS and npm/Yarn Package Installer . Tip Check the Official Guide by Hardhat if you have issues installing this package. Once the above dependencies are installed, create an npm empty project by running the following commands in a terminal: mkdir flare-tutorial cd flare-tutorial npm init Press Enter on each of the prompts. Finally, add Hardhat and a few dependencies to the project, since you will use them in this tutorial. npm install --save-dev \\ hardhat \\ @nomicfoundation/hardhat-toolbox \\ @nomiclabs/hardhat-ethers \\ dotenv","title":"1. Set up the Environment"},{"location":"dev/getting-started/setup/hardhat/#2-create-a-hardhat-project","text":"Hardhat can quick-start your development by providing a sample project. Just run: npx hardhat You should see the following prompt: Hardhat project creation prompt. Choose the Create a JavaScript project with the Up and Down keys, and Press Enter . Then press Y for rest of the prompts. When done, it should print Project created . If you take a look in the contracts folder, you should find a sample source file called Lock.sol . It is a Solidity smart contract implementing a simple digital lock, where users can only withdraw funds after a given period of time: // SPDX-License-Identifier: UNLICENSED pragma solidity ^ 0.8.9 ; // Uncomment this line to use console.log // import \"hardhat/console.sol\"; contract Lock { uint public unlockTime ; address payable public owner ; event Withdrawal ( uint amount , uint when ); constructor ( uint _unlockTime ) payable { require ( block.timestamp < _unlockTime , \"Unlock time should be in the future\" ); unlockTime = _unlockTime ; owner = payable ( msg.sender ); } function withdraw () public { // Uncomment this line, and the import of \"hardhat/console.sol\", to print a log in your terminal // console.log(\"Unlock time is %o and block timestamp is %o\", unlockTime, block.timestamp); require ( block.timestamp >= unlockTime , \"You can't withdraw yet\" ); require ( msg.sender == owner , \"You aren't the owner\" ); emit Withdrawal ( address ( this ). balance , block.timestamp ); owner . transfer ( address ( this ). balance ); } }","title":"2. Create a Hardhat Project"},{"location":"dev/getting-started/setup/hardhat/#3-compile-the-contracts","text":"To compile the sample project, simply run: npx hardhat compile Upon successful compilation it will print Compiled 1 Solidity file successfully .","title":"3. Compile the Contracts"},{"location":"dev/getting-started/setup/hardhat/#4-configure-the-project","text":"In order to be deployed on any of the Flare networks , the project needs to be configured. Edit the hardhat.config.js file and replace its contents with the following: require ( 'dotenv' ). config (); require ( \"@nomicfoundation/hardhat-toolbox\" ); require ( '@nomiclabs/hardhat-ethers' ); /** @type import('hardhat/config').HardhatUserConfig */ module . exports = { solidity : \"0.8.17\" , networks : { hardhat : { }, coston : { url : \"https://coston-api.flare.network/ext/bc/C/rpc\" , accounts : [ process . env . PRIVATE_KEY ], chainId : 16 }, songbird : { url : \"https://songbird-api.flare.network/ext/bc/C/rpc\" , accounts : [ process . env . PRIVATE_KEY ], chainId : 19 }, coston2 : { url : \"https://coston2-api.flare.network/ext/C/rpc\" , accounts : [ process . env . PRIVATE_KEY ], chainId : 114 , }, flare : { url : \"https://flare-api.flare.network/ext/C/rpc\" , accounts : [ process . env . PRIVATE_KEY ], chainId : 14 , } }, }; Then, create a file called .env at the root of you project (where the hardhat.config.js file resides) to store the private key for the account to use for testing. .env files are useful to store local information which should not be committed into the source repository. In this tutorial, you need to store your test account's private key in this format: PRIVATE_KEY = \"0x0000000000000000000000000000000000000000000000000000000000000000\" That is, 64 hexadecimal characters after the 0x . Caution Make sure you never upload your .env file to a remote repository. For this reason, the .gitignore file that Hardhat created for you already ignores .env files.","title":"4. Configure the Project"},{"location":"dev/getting-started/setup/hardhat/#5-test-the-contract","text":"In the test folder you should find a ready-made test file that verifies the contract works as expected. To run tests with Hardhat, you just need to run: npx hardhat test You should get: Lock contract test results.","title":"5. Test the Contract"},{"location":"dev/getting-started/setup/hardhat/#6-deploy-the-contract","text":"Finally, you will deploy the contract to Flare's test network, Coston2 , using a Hardhat script from the scripts folder. Run this command in the root of the project: npx hardhat run scripts/deploy.js --network coston2 You should get an output similar to: Lock with 1 ETH and unlock timestamp 1705592309 deployed to 0xdC7781FA9fA7e2d0313cd0229a5080B4e30663a5 The last part is the address where the contract has been deployed. You can check the status of the contract by copy and pasting this address in the Block Explorer .","title":"6. Deploy the Contract"},{"location":"dev/getting-started/setup/remix/","text":"Setting Up Your Environment Using Remix # The Remix IDE is a powerful, open-source tool that helps you write Solidity smart contracts straight from the browser, without requiring any download, account creation, or login. This article shows you how to deploy a Hello World contract to the Flare blockchain using the Remix IDE and the MetaMask wallet. Guide # 1. Create a New File # Visit the Remix IDE and click the New File button. Name it HelloWorld.sol . Drag and drop it to the contracts folder. New file in the Remix IDE. 2. Write Your Contract # Copy and paste the smart contract code provided below into the newly created HelloWorld.sol file. // SPDX-License-Identifier: MIT // Specifies the version of Solidity, using semantic versioning. pragma solidity 0.8.17 ; // Defines a contract named `HelloWorld` contract HelloWorld { // Declares a state variable `message` of type `string`. string public message ; // Constructors are used to initialize the contract's data. constructor ( string memory initMessage ) { // Accepts a string argument `initMessage`. message = initMessage ; } // A public function that accepts a string argument. function update ( string memory newMessage ) public { message = newMessage ; } } 3. Compile Your Contract # Go to the Solidity Compiler tab (on the left), and select compiler version 0.8.17 . Now, click the Compile HelloWorld.sol button. After successful compilation, it will show a Green tick mark on the Compiler tab button. Compilation successful. 4. Deploying on Flare Testnet # You will now deploy the smart contract on the Coston2 network , Flare's test network. When a smart contract is deployed on Flare's main network, it not only costs money (such as gas fees), but it also becomes immutable and cannot be modified. Therefore, deploying your smart contracts first on the test network is highly recommended. Important Before jumping onto Remix Deployment: Make sure that you have added and selected the Coston2 test network to your MetaMask Wallet. The MetaMask Wallet guide shows how to do it. Use the values for Coston2 that you will find in the Network Configurations page. Ensure that you have enough Coston2 native tokens $C2FLR to pay for gas. Visit the Coston2 Faucet to request some $C2FLR . Go to the Deploy & Run Transactions tab (the last one) and select Injected Provider - Metamask from the ENVIRONMENT dropdown. Accept the connection request received in MetaMask if necessary. Environment selection on Remix. Click the Deploy button and confirm the CONTRACT DEPLOYMENT transaction in MetaMask. Contract deployment transaction. Note The process to deploy your contract on the Flare main network is the same as above. You only have to select Flare Network on MetaMask and use $FLR tokens. 5. Interact with the Contract # You can now interact with the contract to verify that it is working as intended. In the Deployed Contracts section at the bottom of the left column, expand the HELLOWORLD contract to see its methods and data: update method. message public variable. Type a message in the box next to the update button and click the button. Confirm the deployment transaction in MetaMask. Check that the contract has been updated by clicking the message button and verifying you get back the message you typed before. Interact with the contract","title":"Using Remix"},{"location":"dev/getting-started/setup/remix/#setting-up-your-environment-using-remix","text":"The Remix IDE is a powerful, open-source tool that helps you write Solidity smart contracts straight from the browser, without requiring any download, account creation, or login. This article shows you how to deploy a Hello World contract to the Flare blockchain using the Remix IDE and the MetaMask wallet.","title":"Setting Up Your Environment Using Remix"},{"location":"dev/getting-started/setup/remix/#guide","text":"","title":"Guide"},{"location":"dev/getting-started/setup/remix/#1-create-a-new-file","text":"Visit the Remix IDE and click the New File button. Name it HelloWorld.sol . Drag and drop it to the contracts folder. New file in the Remix IDE.","title":"1. Create a New File"},{"location":"dev/getting-started/setup/remix/#2-write-your-contract","text":"Copy and paste the smart contract code provided below into the newly created HelloWorld.sol file. // SPDX-License-Identifier: MIT // Specifies the version of Solidity, using semantic versioning. pragma solidity 0.8.17 ; // Defines a contract named `HelloWorld` contract HelloWorld { // Declares a state variable `message` of type `string`. string public message ; // Constructors are used to initialize the contract's data. constructor ( string memory initMessage ) { // Accepts a string argument `initMessage`. message = initMessage ; } // A public function that accepts a string argument. function update ( string memory newMessage ) public { message = newMessage ; } }","title":"2. Write Your Contract"},{"location":"dev/getting-started/setup/remix/#3-compile-your-contract","text":"Go to the Solidity Compiler tab (on the left), and select compiler version 0.8.17 . Now, click the Compile HelloWorld.sol button. After successful compilation, it will show a Green tick mark on the Compiler tab button. Compilation successful.","title":"3. Compile Your Contract"},{"location":"dev/getting-started/setup/remix/#4-deploying-on-flare-testnet","text":"You will now deploy the smart contract on the Coston2 network , Flare's test network. When a smart contract is deployed on Flare's main network, it not only costs money (such as gas fees), but it also becomes immutable and cannot be modified. Therefore, deploying your smart contracts first on the test network is highly recommended. Important Before jumping onto Remix Deployment: Make sure that you have added and selected the Coston2 test network to your MetaMask Wallet. The MetaMask Wallet guide shows how to do it. Use the values for Coston2 that you will find in the Network Configurations page. Ensure that you have enough Coston2 native tokens $C2FLR to pay for gas. Visit the Coston2 Faucet to request some $C2FLR . Go to the Deploy & Run Transactions tab (the last one) and select Injected Provider - Metamask from the ENVIRONMENT dropdown. Accept the connection request received in MetaMask if necessary. Environment selection on Remix. Click the Deploy button and confirm the CONTRACT DEPLOYMENT transaction in MetaMask. Contract deployment transaction. Note The process to deploy your contract on the Flare main network is the same as above. You only have to select Flare Network on MetaMask and use $FLR tokens.","title":"4. Deploying on Flare Testnet"},{"location":"dev/getting-started/setup/remix/#5-interact-with-the-contract","text":"You can now interact with the contract to verify that it is working as intended. In the Deployed Contracts section at the bottom of the left column, expand the HELLOWORLD contract to see its methods and data: update method. message public variable. Type a message in the box next to the update button and click the button. Confirm the deployment transaction in MetaMask. Check that the contract has been updated by clicking the message button and verifying you get back the message you typed before. Interact with the contract","title":"5. Interact with the Contract"},{"location":"dev/getting-started/setup/truffle/","text":"Setting Up Your Environment Using Truffle # Truffle is a blockchain development environment, which you can use to create and test smart contracts by leveraging the Ethereum Virtual Machine (EVM), aiming to make life as a developer easier. This article shows you how to set up Truffle and use it to build and deploy a smart contract on the Flare network. Guide # 1. Set up the Environment # Install the following dependencies: NodeJSv12+ LTS and npm/Yarn Package Installer . Once the above dependencies are installed, install Truffle: npm install -g truffle To verify that Truffle is installed properly, type truffle version into the terminal. 2. Create a Truffle Project # In this article you will use one of Truffle's boilerplate projects which you can find on the Truffle Boxes page . MetaCoin box is an example of a completed coin-like contract. Create a new directory for this Truffle project by running: mkdir flare-truffle-tutorial cd flare-truffle-tutorial Then install the MetaCoin box: truffle unbox metacoin Once this operation is complete, you should have a project structure with the following items: Truffle Project structure. Finally, install the following dependencies which will be needed to deploy contracts: npm i @truffle/hdwallet-provider dotenv 3. Compile the Contract # In the contracts folder you should find two sample source files called MetaCoin.sol and ConvertLib.sol . To compile them, simply run: truffle compile Upon successful compilation, you should see the following output: Truffle compilation output. 4. Test the Contract # In the test folder you should find examples for testing your smart contracts in both JavaScript and Solidity that verify the contracts work as expected. To run tests: truffle test When successful, the output should look like this: Truffle test output. 5. Configure the Project # In order to be deployed on any of the Flare networks , the project needs to be configured. Edit the truffle-config.js file and replace its contents with the following: const HDWalletProvider = require ( '@truffle/hdwallet-provider' ); require ( 'dotenv' ). config (); const fs = require ( 'fs' ); module . exports = { networks : { development : { host : \"127.0.0.1\" , // Localhost (default: none) port : 8545 , // Standard Ethereum port (default: none) network_id : \"*\" , // Any network (default: none) }, flare : { provider : () => new HDWalletProvider ( process . env . PRIVATE_KEY , `https://flare-api.flare.network/ext/C/rpc` ), network_id : 14 , timeoutBlocks : 200 , skipDryRun : true }, coston2 : { provider : () => new HDWalletProvider ( process . env . PRIVATE_KEY , `https://coston2-api.flare.network/ext/C/rpc` ), network_id : 114 , timeoutBlocks : 200 , skipDryRun : true }, }, // Set default mocha options here, use special reporters etc. mocha : { // timeout: 100000 }, // Configure your compilers compilers : { solc : { version : \"0.8.13\" , // Fetch exact version from solc-bin } } }; Then, create a file called .env at the root of you project (where the truffle-config.js file resides) to store the private key for the account to use for testing. PRIVATE_KEY = \"d8936f6eae35c73a14ea7c1aabb8d068e16889a7f516c8abc482ba4e1489f4cd\" .env files are useful to store local information which should not be committed into the source repository. Caution Make sure you never upload your .env file to a remote repository. For this reason, the .gitignore file that Truffle created for you already ignores .env files. 6. Deploy the Contract # Important You are going to deploy the contract on the Coston 2 network . Make sure you have enough C2FLR in the account that will deploy the contract to pay the gas fees! You can add C2FLR to any account using the Coston 2 Faucet . Run this command in the root folder of the project: truffle migrate --network coston2 You should get an output similar to: Truffle deployment output. You can check the status of the contract by copy and pasting the contract address: in the Block Explorer .","title":"Using Truffle"},{"location":"dev/getting-started/setup/truffle/#setting-up-your-environment-using-truffle","text":"Truffle is a blockchain development environment, which you can use to create and test smart contracts by leveraging the Ethereum Virtual Machine (EVM), aiming to make life as a developer easier. This article shows you how to set up Truffle and use it to build and deploy a smart contract on the Flare network.","title":"Setting Up Your Environment Using Truffle"},{"location":"dev/getting-started/setup/truffle/#guide","text":"","title":"Guide"},{"location":"dev/getting-started/setup/truffle/#1-set-up-the-environment","text":"Install the following dependencies: NodeJSv12+ LTS and npm/Yarn Package Installer . Once the above dependencies are installed, install Truffle: npm install -g truffle To verify that Truffle is installed properly, type truffle version into the terminal.","title":"1. Set up the Environment"},{"location":"dev/getting-started/setup/truffle/#2-create-a-truffle-project","text":"In this article you will use one of Truffle's boilerplate projects which you can find on the Truffle Boxes page . MetaCoin box is an example of a completed coin-like contract. Create a new directory for this Truffle project by running: mkdir flare-truffle-tutorial cd flare-truffle-tutorial Then install the MetaCoin box: truffle unbox metacoin Once this operation is complete, you should have a project structure with the following items: Truffle Project structure. Finally, install the following dependencies which will be needed to deploy contracts: npm i @truffle/hdwallet-provider dotenv","title":"2. Create a Truffle Project"},{"location":"dev/getting-started/setup/truffle/#3-compile-the-contract","text":"In the contracts folder you should find two sample source files called MetaCoin.sol and ConvertLib.sol . To compile them, simply run: truffle compile Upon successful compilation, you should see the following output: Truffle compilation output.","title":"3. Compile the Contract"},{"location":"dev/getting-started/setup/truffle/#4-test-the-contract","text":"In the test folder you should find examples for testing your smart contracts in both JavaScript and Solidity that verify the contracts work as expected. To run tests: truffle test When successful, the output should look like this: Truffle test output.","title":"4. Test the Contract"},{"location":"dev/getting-started/setup/truffle/#5-configure-the-project","text":"In order to be deployed on any of the Flare networks , the project needs to be configured. Edit the truffle-config.js file and replace its contents with the following: const HDWalletProvider = require ( '@truffle/hdwallet-provider' ); require ( 'dotenv' ). config (); const fs = require ( 'fs' ); module . exports = { networks : { development : { host : \"127.0.0.1\" , // Localhost (default: none) port : 8545 , // Standard Ethereum port (default: none) network_id : \"*\" , // Any network (default: none) }, flare : { provider : () => new HDWalletProvider ( process . env . PRIVATE_KEY , `https://flare-api.flare.network/ext/C/rpc` ), network_id : 14 , timeoutBlocks : 200 , skipDryRun : true }, coston2 : { provider : () => new HDWalletProvider ( process . env . PRIVATE_KEY , `https://coston2-api.flare.network/ext/C/rpc` ), network_id : 114 , timeoutBlocks : 200 , skipDryRun : true }, }, // Set default mocha options here, use special reporters etc. mocha : { // timeout: 100000 }, // Configure your compilers compilers : { solc : { version : \"0.8.13\" , // Fetch exact version from solc-bin } } }; Then, create a file called .env at the root of you project (where the truffle-config.js file resides) to store the private key for the account to use for testing. PRIVATE_KEY = \"d8936f6eae35c73a14ea7c1aabb8d068e16889a7f516c8abc482ba4e1489f4cd\" .env files are useful to store local information which should not be committed into the source repository. Caution Make sure you never upload your .env file to a remote repository. For this reason, the .gitignore file that Truffle created for you already ignores .env files.","title":"5. Configure the Project"},{"location":"dev/getting-started/setup/truffle/#6-deploy-the-contract","text":"Important You are going to deploy the contract on the Coston 2 network . Make sure you have enough C2FLR in the account that will deploy the contract to pay the gas fees! You can add C2FLR to any account using the Coston 2 Faucet . Run this command in the root folder of the project: truffle migrate --network coston2 You should get an output similar to: Truffle deployment output. You can check the status of the contract by copy and pasting the contract address: in the Block Explorer .","title":"6. Deploy the Contract"},{"location":"dev/reference/","text":"Reference Guides # The following guides provide in-depth information about the Flare networks and the different smart contracts APIs. Guides # Network Configuration Automatic Claiming Block Explorers and Indexers The FlareDrop Personal Delegation Accounts Wallets","title":"Reference Guides"},{"location":"dev/reference/#reference-guides","text":"The following guides provide in-depth information about the Flare networks and the different smart contracts APIs.","title":"Reference Guides"},{"location":"dev/reference/#guides","text":"Network Configuration Automatic Claiming Block Explorers and Indexers The FlareDrop Personal Delegation Accounts Wallets","title":"Guides"},{"location":"dev/reference/automatic-claiming/","text":"Automatic Claiming # Users who do not want to claim rewards themselves can enlist executors to claim on their behalf. Executors can then initiate the claiming process, and rewards are sent directly to the user's account. Introduction # Building an executor requires two parts: An executor bot that periodically claims on behalf of the users. An app that allows users to select the executor, such as the Flare Portal , which is free to use. This page contains the following information: The Required Contracts section briefly lists the smart contracts related to executor operation. The User Operations section shows how to perform the operations required in a user-facing application, such as setting an executor. The Executor Operations section shows how to perform the operations required by an executor bot, such as registering as an executor. The User and Executor Reports section shows how to access information useful for performing user and executor functions. Required Contracts # Setting up automatic claiming requires interacting with these contracts: ClaimSetupManager (CSM). FTSORewardManager (FTSO). To find the addresses of these contracts, see the Contract Addresses page. User Operations # This section shows how to perform operations required to enable autoclaiming. The main step is to set the executor that will perform the claiming for the user who has accrued rewards. Then other operations are explained, such as changing the executor and disabling automatic claiming. Setting Claim Executors # There are two ways to set up automatic claiming: Manual and Registered . Manual Claiming # With Manual Claiming , rewards are claimed on-chain, but any agreement between users and executors happens off-chain. Fees are not paid automatically. To set one or more executors to claim rewards for a user: Set a specific executor by calling CSM.setClaimExecutors() and providing the executor's address. This method must be called from the user's account, since they are the only ones that can authorize claiming on their behalf. This function removes all previously set executors and replaces them with the new set. Registered Claiming # With Registered Claiming , a purpose-built ClaimSetupManager contract handles the on-chain agreement between users and executors, greatly simplifying the process. To set one or more registered executors to claim rewards for a user: Get a list of executors and their fees by calling CSM.getRegisteredExecutors() . To find the fee of a specific executor, call CSM.getExecutorCurrentFeeValue() . This fee is deducted from the user\u2019s reward after each claim and sent to the executor. You can show this information to the user and let them select which executor to use. Set the selected executors by calling CSM.setClaimExecutors() as shown for Manual Claiming . However, when setting registered executors, the call must include a value equal to the executor\u2019s fee (in FLR), which is sent to the executor as an enrollment fee. If more than one executor is set, the value must equal the sum of all the executor's fees. Changing Registered Executors # To change registered executors, call CSM.setClaimExecutors() with the new list of executors. This new list overwrites the current list. Disabling Automatic Claiming # To disable automatic claiming, remove all executors by sending an empty array of executors with CSM.setClaimExecutors() . Executor Operations # This section shows how to perform operations required in an executor-facing application, for example, becoming an executor. While the main step for manual executors is only claiming rewards, the main steps for registered executors are registering, setting a fee, and claiming rewards. Other operations like changing the fee, unregistering as an executor, and learning which addresses to claim for are also explained. Becoming an Executor # There are two ways to become an executor: Manual and Registered . Manual Executor # Setting an executor manually means doing so off-chain. Therefore, there is no operation required for executors, besides communicating to the users the address of the executor they need to use. Registered Executor # The ClaimSetupManager contract contains a list of self-registered executors that users can use to discover executors and their service fees, avoiding the need for off-chain operations as in manual claiming. To automatically receive fees for claiming, an executor address must register, set the fee for claiming rewards, and pay the registration fee. Register an executor by calling CSM.registerExecutor(uint256 feeValue) , where feeValue is the fee in wei that the executor requires to perform this service. The fee value must be at least CSM.minFeeValueWei , currently 0.1 FLR, and no greater than CSM.maxFeeValueWei , currently 100 FLR. This transaction must include a registration fee equal to CSM.registerExecutorFeeValueWei , currently 1000 FLR, which is burned. Claiming Rewards # How to Claim # Executors can now only claim FTSO delegation rewards on behalf of users. As other rewards become available, they will also be claimable by executors without any user intervention. Manual and registered executors use the same function, the only difference being that unregistered executors do not receive a fee automatically. To claim FTSO rewards for all of a user's unclaimed epochs, call FTSO.autoClaim(address[] rewardOwners, uint256 rewardEpoch) . This method can be used to claim for multiple users, since rewardOwners is an array. The rewardEpoch is the most current one that the executor wants to claim for, typically the one before the current epoch. If a user has more unclaimed epochs from the past, the function claims for all of them. The claimed amount gets the executor fee subtracted and is automatically wrapped, so it is sent to the user as $WFLR . What to Expect in Fees # The executor gets paid a fee for each user for which he claims the FTSO delegation reward. However, he only gets paid one fee per user regardless of whether he claims for one or more epochs. The fee is paid in native $FLR tokens. If the claimed reward for a user is lower than the executor fee, the transaction is reverted. To see which users have enough rewards to complete and which would revert, call FTSO.autoClaim with a specific user address. Changing the Fee # Registered executors can change the fee they charge for the successful execution of claims. To change the fee, call CSM.updateExecutorFeeValue() . The new fee value will be in effect after CSM.feeValueUpdateOffset reward epochs have elapsed (currently 3 epochs), where the first epoch is the one that is currently active. This function returns the reward epoch number when the setting will become effective. Unregistering an Executor # Registered executors can unregister by calling CSM.unregisterExecutor() and they will be removed from the list of executors. To help the users adjust to the change, executors will retain the current fee and continue claiming for the next 3 reward epochs ( feeValueUpdateOffset ). An executor's best practice is to notify users when unregistering. Updating the User List # Executors should keep a list of users to claim for, there is no mechanism to retrieve this list from the chain. There are two ways to keep this list updated: Listen to the CSM.ClaimExecutorsChanged event which is emitted every time a user sets its executors. This method is suitable for registered executors which might be selected at any time. If the executor is only interested in a closed list of users, e.g., the ones that enlisted on an application, it can call CSM.isClaimExecutor(address user, address executor) for each user to verify the executor's address is properly configured. User and Executor Reports # This section shows how to access information that can help you perform both user and executor functions. Executor Fees # Get the current fee for each executor on the Registered Executors list by calling CSM.getExecutorCurrentFeeValue(address executor) . For upcoming fee changes, call CSM.getExecutorScheduledFeeValueChanges(address executor) . Executors by User # A user can set more than one executor. To see a list of current executors for a user, call CSM.claimExecutors(address user) , which returns an array of executor addresses. It is a best practice for users to check this report periodically (at least every 90 days) to make sure their selected executors have not unregistered without notice. Executor Status # To check if an executor is registered, call CSM.getExecutorInfo(address executor) . It returns whether an executor is registered and its fee.","title":"Automatic Claiming"},{"location":"dev/reference/automatic-claiming/#automatic-claiming","text":"Users who do not want to claim rewards themselves can enlist executors to claim on their behalf. Executors can then initiate the claiming process, and rewards are sent directly to the user's account.","title":"Automatic Claiming"},{"location":"dev/reference/automatic-claiming/#introduction","text":"Building an executor requires two parts: An executor bot that periodically claims on behalf of the users. An app that allows users to select the executor, such as the Flare Portal , which is free to use. This page contains the following information: The Required Contracts section briefly lists the smart contracts related to executor operation. The User Operations section shows how to perform the operations required in a user-facing application, such as setting an executor. The Executor Operations section shows how to perform the operations required by an executor bot, such as registering as an executor. The User and Executor Reports section shows how to access information useful for performing user and executor functions.","title":"Introduction"},{"location":"dev/reference/automatic-claiming/#required-contracts","text":"Setting up automatic claiming requires interacting with these contracts: ClaimSetupManager (CSM). FTSORewardManager (FTSO). To find the addresses of these contracts, see the Contract Addresses page.","title":"Required Contracts"},{"location":"dev/reference/automatic-claiming/#user-operations","text":"This section shows how to perform operations required to enable autoclaiming. The main step is to set the executor that will perform the claiming for the user who has accrued rewards. Then other operations are explained, such as changing the executor and disabling automatic claiming.","title":"User Operations"},{"location":"dev/reference/automatic-claiming/#setting-claim-executors","text":"There are two ways to set up automatic claiming: Manual and Registered .","title":"Setting Claim Executors"},{"location":"dev/reference/automatic-claiming/#manual-claiming","text":"With Manual Claiming , rewards are claimed on-chain, but any agreement between users and executors happens off-chain. Fees are not paid automatically. To set one or more executors to claim rewards for a user: Set a specific executor by calling CSM.setClaimExecutors() and providing the executor's address. This method must be called from the user's account, since they are the only ones that can authorize claiming on their behalf. This function removes all previously set executors and replaces them with the new set.","title":"Manual Claiming"},{"location":"dev/reference/automatic-claiming/#registered-claiming","text":"With Registered Claiming , a purpose-built ClaimSetupManager contract handles the on-chain agreement between users and executors, greatly simplifying the process. To set one or more registered executors to claim rewards for a user: Get a list of executors and their fees by calling CSM.getRegisteredExecutors() . To find the fee of a specific executor, call CSM.getExecutorCurrentFeeValue() . This fee is deducted from the user\u2019s reward after each claim and sent to the executor. You can show this information to the user and let them select which executor to use. Set the selected executors by calling CSM.setClaimExecutors() as shown for Manual Claiming . However, when setting registered executors, the call must include a value equal to the executor\u2019s fee (in FLR), which is sent to the executor as an enrollment fee. If more than one executor is set, the value must equal the sum of all the executor's fees.","title":"Registered Claiming"},{"location":"dev/reference/automatic-claiming/#changing-registered-executors","text":"To change registered executors, call CSM.setClaimExecutors() with the new list of executors. This new list overwrites the current list.","title":"Changing Registered Executors"},{"location":"dev/reference/automatic-claiming/#disabling-automatic-claiming","text":"To disable automatic claiming, remove all executors by sending an empty array of executors with CSM.setClaimExecutors() .","title":"Disabling Automatic Claiming"},{"location":"dev/reference/automatic-claiming/#executor-operations","text":"This section shows how to perform operations required in an executor-facing application, for example, becoming an executor. While the main step for manual executors is only claiming rewards, the main steps for registered executors are registering, setting a fee, and claiming rewards. Other operations like changing the fee, unregistering as an executor, and learning which addresses to claim for are also explained.","title":"Executor Operations"},{"location":"dev/reference/automatic-claiming/#becoming-an-executor","text":"There are two ways to become an executor: Manual and Registered .","title":"Becoming an Executor"},{"location":"dev/reference/automatic-claiming/#manual-executor","text":"Setting an executor manually means doing so off-chain. Therefore, there is no operation required for executors, besides communicating to the users the address of the executor they need to use.","title":"Manual Executor"},{"location":"dev/reference/automatic-claiming/#registered-executor","text":"The ClaimSetupManager contract contains a list of self-registered executors that users can use to discover executors and their service fees, avoiding the need for off-chain operations as in manual claiming. To automatically receive fees for claiming, an executor address must register, set the fee for claiming rewards, and pay the registration fee. Register an executor by calling CSM.registerExecutor(uint256 feeValue) , where feeValue is the fee in wei that the executor requires to perform this service. The fee value must be at least CSM.minFeeValueWei , currently 0.1 FLR, and no greater than CSM.maxFeeValueWei , currently 100 FLR. This transaction must include a registration fee equal to CSM.registerExecutorFeeValueWei , currently 1000 FLR, which is burned.","title":"Registered Executor"},{"location":"dev/reference/automatic-claiming/#claiming-rewards","text":"","title":"Claiming Rewards"},{"location":"dev/reference/automatic-claiming/#how-to-claim","text":"Executors can now only claim FTSO delegation rewards on behalf of users. As other rewards become available, they will also be claimable by executors without any user intervention. Manual and registered executors use the same function, the only difference being that unregistered executors do not receive a fee automatically. To claim FTSO rewards for all of a user's unclaimed epochs, call FTSO.autoClaim(address[] rewardOwners, uint256 rewardEpoch) . This method can be used to claim for multiple users, since rewardOwners is an array. The rewardEpoch is the most current one that the executor wants to claim for, typically the one before the current epoch. If a user has more unclaimed epochs from the past, the function claims for all of them. The claimed amount gets the executor fee subtracted and is automatically wrapped, so it is sent to the user as $WFLR .","title":"How to Claim"},{"location":"dev/reference/automatic-claiming/#what-to-expect-in-fees","text":"The executor gets paid a fee for each user for which he claims the FTSO delegation reward. However, he only gets paid one fee per user regardless of whether he claims for one or more epochs. The fee is paid in native $FLR tokens. If the claimed reward for a user is lower than the executor fee, the transaction is reverted. To see which users have enough rewards to complete and which would revert, call FTSO.autoClaim with a specific user address.","title":"What to Expect in Fees"},{"location":"dev/reference/automatic-claiming/#changing-the-fee","text":"Registered executors can change the fee they charge for the successful execution of claims. To change the fee, call CSM.updateExecutorFeeValue() . The new fee value will be in effect after CSM.feeValueUpdateOffset reward epochs have elapsed (currently 3 epochs), where the first epoch is the one that is currently active. This function returns the reward epoch number when the setting will become effective.","title":"Changing the Fee"},{"location":"dev/reference/automatic-claiming/#unregistering-an-executor","text":"Registered executors can unregister by calling CSM.unregisterExecutor() and they will be removed from the list of executors. To help the users adjust to the change, executors will retain the current fee and continue claiming for the next 3 reward epochs ( feeValueUpdateOffset ). An executor's best practice is to notify users when unregistering.","title":"Unregistering an Executor"},{"location":"dev/reference/automatic-claiming/#updating-the-user-list","text":"Executors should keep a list of users to claim for, there is no mechanism to retrieve this list from the chain. There are two ways to keep this list updated: Listen to the CSM.ClaimExecutorsChanged event which is emitted every time a user sets its executors. This method is suitable for registered executors which might be selected at any time. If the executor is only interested in a closed list of users, e.g., the ones that enlisted on an application, it can call CSM.isClaimExecutor(address user, address executor) for each user to verify the executor's address is properly configured.","title":"Updating the User List"},{"location":"dev/reference/automatic-claiming/#user-and-executor-reports","text":"This section shows how to access information that can help you perform both user and executor functions.","title":"User and Executor Reports"},{"location":"dev/reference/automatic-claiming/#executor-fees","text":"Get the current fee for each executor on the Registered Executors list by calling CSM.getExecutorCurrentFeeValue(address executor) . For upcoming fee changes, call CSM.getExecutorScheduledFeeValueChanges(address executor) .","title":"Executor Fees"},{"location":"dev/reference/automatic-claiming/#executors-by-user","text":"A user can set more than one executor. To see a list of current executors for a user, call CSM.claimExecutors(address user) , which returns an array of executor addresses. It is a best practice for users to check this report periodically (at least every 90 days) to make sure their selected executors have not unregistered without notice.","title":"Executors by User"},{"location":"dev/reference/automatic-claiming/#executor-status","text":"To check if an executor is registered, call CSM.getExecutorInfo(address executor) . It returns whether an executor is registered and its fee.","title":"Executor Status"},{"location":"dev/reference/explorers-and-indexers/","text":"Block Explorers and Indexers # Flare provides a block explorer for each of the networks in its ecosystem. All explorers are a fork of Blockscout , adapted to the Flare networks ( Blockscout Docs ). API documentation for each network's explorer: Flare Songbird Coston Coston2 API access to the Coston Explorer is enabled for noncommercial use only. Related User Guides # Block Explorers","title":"Block Explorers and Indexers"},{"location":"dev/reference/explorers-and-indexers/#block-explorers-and-indexers","text":"Flare provides a block explorer for each of the networks in its ecosystem. All explorers are a fork of Blockscout , adapted to the Flare networks ( Blockscout Docs ). API documentation for each network's explorer: Flare Songbird Coston Coston2 API access to the Coston Explorer is enabled for noncommercial use only.","title":"Block Explorers and Indexers"},{"location":"dev/reference/explorers-and-indexers/#related-user-guides","text":"Block Explorers","title":"Related User Guides"},{"location":"dev/reference/network-config/","text":"Network Configuration # Flare Networks # These are the values required to configure the different Flare networks : Flare Songbird Coston Coston2 Flare Chain ID 14 Asset Ticker FLR RPC endpoint https://flare-api.flare.network/ext/C/rpc Rosetta API https://flare-rosetta-api.flare.network/ Block Explorer https://flare-explorer.flare.network Bootstraping nodes https://flare.flare.network http://mainnet.flare.bdnodes.net http://flare-bootstrap-1.staking.production.figment.io http://flare.senseinode.com http://flare-mainnet.staked.cloud Sample query You can check that you are accessing the RPC endpoint correctly with this sample query: curl -s -m 10 --request POST 'https://flare-api.flare.network/ext/C/rpc' \\ -H 'Content-Type: application/json' \\ -d '{ \"jsonrpc\":\"2.0\", \"method\":\"eth_blockNumber\", \"params\":[], \"id\":1 }' It should return the current chain height in a message similar to: { \"jsonrpc\" : \"2.0\" , \"id\" : 1 , \"result\" : \"0x103384\" } Songbird Chain ID 19 Asset Ticker SGB RPC endpoint https://songbird-api.flare.network/ext/C/rpc Block Explorer https://songbird-explorer.flare.network Bootstraping nodes https://songbird.flare.network Sample query You can check that you are accessing the RPC endpoint correctly with this sample query: curl -s -m 10 --request POST 'https://songbird-api.flare.network/ext/C/rpc' \\ -H 'Content-Type: application/json' \\ -d '{ \"jsonrpc\":\"2.0\", \"method\":\"eth_blockNumber\", \"params\":[], \"id\":1 }' It should return the current chain height in a message similar to: { \"jsonrpc\" : \"2.0\" , \"id\" : 1 , \"result\" : \"0x103384\" } Coston Chain ID 16 Asset Ticker CFLR RPC endpoint https://coston-api.flare.network/ext/C/rpc Block Explorer https://coston-explorer.flare.network Bootstraping nodes https://coston.flare.network Test Faucet https://faucet.towolabs.com Sample query You can check that you are accessing the RPC endpoint correctly with this sample query: curl -s -m 10 --request POST 'https://coston-api.flare.network/ext/C/rpc' \\ -H 'Content-Type: application/json' \\ -d '{ \"jsonrpc\":\"2.0\", \"method\":\"eth_blockNumber\", \"params\":[], \"id\":1 }' It should return the current chain height in a message similar to: { \"jsonrpc\" : \"2.0\" , \"id\" : 1 , \"result\" : \"0x103384\" } Coston2 Chain ID 114 Asset Ticker C2FLR RPC endpoint https://coston2-api.flare.network/ext/C/rpc Block Explorer https://coston2-explorer.flare.network Bootstraping nodes https://coston2.flare.network Test Faucet https://coston2-faucet.towolabs.com Sample query You can check that you are accessing the RPC endpoint correctly with this sample query: curl -s -m 10 --request POST 'https://coston2-api.flare.network/ext/C/rpc' \\ -H 'Content-Type: application/json' \\ -d '{ \"jsonrpc\":\"2.0\", \"method\":\"eth_blockNumber\", \"params\":[], \"id\":1 }' It should return the current chain height in a message similar to: { \"jsonrpc\" : \"2.0\" , \"id\" : 1 , \"result\" : \"0x103384\" } All public RPC endpoints are experimental and rate-limited to avoid spamming attacks. For a production-grade option check out Flare's API Portal Connected Networks # Along with the endpoints listed above to interact with its own networks, Flare offers public RPC nodes for a series of other blockchain networks, to bootstrap development of connected services like attestation providers . All public RPC endpoints are experimental and rate-limited to avoid spamming attacks. For a production-grade option check out Flare's API Portal Bitcoin BNB-BSC Litecoin Dogecoin XRPL Algorand Ethereum RPC endpoint https://bitcoin-api.flare.network Sample query curl -s -X POST -m 10 -H \"Content-type: application/json\" \\ -d '{\"jsonrpc\": \"1.0\", \"id\":\"hc\", \"method\": \"getblockchaininfo\", \"params\":[]}' \\ -u public:d681co1pe2l3wcj9adrm2orlk0j5r5gr3wghgxt58tvge594co0k1ciljxq9glei \\ https://bitcoin-api.flare.network | jq RPC endpoint https://bnb-bsc-api.flare.network/ Sample query curl -s -X POST -m 10 -H \"Content-Type: application/json\" \\ -d '{\"jsonrpc\": \"2.0\", \"id\":67, \"method\":\"eth_blockNumber\", \"params\":[]}' \\ https://bnb-bsc-api.flare.network | jq RPC endpoint https://litecoin-api.flare.network Sample query curl -s -X POST -m 10 -H \"Content-type: application/json\" \\ -d '{\"jsonrpc\": \"1.0\", \"id\":\"hc\", \"method\": \"getblockchaininfo\", \"params\":[]}' \\ -u public:ntvzi4i1yne499t7vcdjqhhp92m3jvm0bb6dkpr406gkndvuns9sg6th3jd393uc \\ https://litecoin-api.flare.network | jq RPC endpoint https://dogecoin-api.flare.network Sample query curl -s -X POST -m 10 -H \"Content-type: application/json\" \\ -d '{\"jsonrpc\": \"1.0\", \"id\":\"hc\", \"method\": \"getblockchaininfo\", \"params\":[]}' \\ -u public:6r1e5z3w9g6qruvkzkqvz8w67yqrq5js2cmyl2f1cncbp7gpp7tqixqskuub5v70 \\ https://dogecoin-api.flare.network | jq RPC endpoint https://xrpl-api.flare.network Sample query curl -s -X POST -m 10 -H \"Content-type: application/json\" \\ -d '{\"method\": \"server_info\", \"params\":[{\"api_version\": 1}]}' \\ https://xrpl-api.flare.network | jq RPC endpoint https://algorand-api.flare.network Sample query curl -s -m 10 \\ -H \"X-Algo-API-Token: zl748k3wddvld8cvn64utnslbf7otorkijp84se0f58pmuu0shgm27gttpcjpmuq\" \\ https://algorand-api.flare.network/v2/status | jq RPC endpoint https://ethereum-api.flare.network/ Sample query curl -s -X POST -m 10 -H \"Content-Type: application/json\" \\ -d '{\"jsonrpc\": \"2.0\", \"id\":67, \"method\":\"eth_blockNumber\", \"params\":[]}' \\ https://ethereum-api.flare.network | jq","title":"Network Configuration"},{"location":"dev/reference/network-config/#network-configuration","text":"","title":"Network Configuration"},{"location":"dev/reference/network-config/#flare-networks","text":"These are the values required to configure the different Flare networks : Flare Songbird Coston Coston2 Flare Chain ID 14 Asset Ticker FLR RPC endpoint https://flare-api.flare.network/ext/C/rpc Rosetta API https://flare-rosetta-api.flare.network/ Block Explorer https://flare-explorer.flare.network Bootstraping nodes https://flare.flare.network http://mainnet.flare.bdnodes.net http://flare-bootstrap-1.staking.production.figment.io http://flare.senseinode.com http://flare-mainnet.staked.cloud Sample query You can check that you are accessing the RPC endpoint correctly with this sample query: curl -s -m 10 --request POST 'https://flare-api.flare.network/ext/C/rpc' \\ -H 'Content-Type: application/json' \\ -d '{ \"jsonrpc\":\"2.0\", \"method\":\"eth_blockNumber\", \"params\":[], \"id\":1 }' It should return the current chain height in a message similar to: { \"jsonrpc\" : \"2.0\" , \"id\" : 1 , \"result\" : \"0x103384\" } Songbird Chain ID 19 Asset Ticker SGB RPC endpoint https://songbird-api.flare.network/ext/C/rpc Block Explorer https://songbird-explorer.flare.network Bootstraping nodes https://songbird.flare.network Sample query You can check that you are accessing the RPC endpoint correctly with this sample query: curl -s -m 10 --request POST 'https://songbird-api.flare.network/ext/C/rpc' \\ -H 'Content-Type: application/json' \\ -d '{ \"jsonrpc\":\"2.0\", \"method\":\"eth_blockNumber\", \"params\":[], \"id\":1 }' It should return the current chain height in a message similar to: { \"jsonrpc\" : \"2.0\" , \"id\" : 1 , \"result\" : \"0x103384\" } Coston Chain ID 16 Asset Ticker CFLR RPC endpoint https://coston-api.flare.network/ext/C/rpc Block Explorer https://coston-explorer.flare.network Bootstraping nodes https://coston.flare.network Test Faucet https://faucet.towolabs.com Sample query You can check that you are accessing the RPC endpoint correctly with this sample query: curl -s -m 10 --request POST 'https://coston-api.flare.network/ext/C/rpc' \\ -H 'Content-Type: application/json' \\ -d '{ \"jsonrpc\":\"2.0\", \"method\":\"eth_blockNumber\", \"params\":[], \"id\":1 }' It should return the current chain height in a message similar to: { \"jsonrpc\" : \"2.0\" , \"id\" : 1 , \"result\" : \"0x103384\" } Coston2 Chain ID 114 Asset Ticker C2FLR RPC endpoint https://coston2-api.flare.network/ext/C/rpc Block Explorer https://coston2-explorer.flare.network Bootstraping nodes https://coston2.flare.network Test Faucet https://coston2-faucet.towolabs.com Sample query You can check that you are accessing the RPC endpoint correctly with this sample query: curl -s -m 10 --request POST 'https://coston2-api.flare.network/ext/C/rpc' \\ -H 'Content-Type: application/json' \\ -d '{ \"jsonrpc\":\"2.0\", \"method\":\"eth_blockNumber\", \"params\":[], \"id\":1 }' It should return the current chain height in a message similar to: { \"jsonrpc\" : \"2.0\" , \"id\" : 1 , \"result\" : \"0x103384\" } All public RPC endpoints are experimental and rate-limited to avoid spamming attacks. For a production-grade option check out Flare's API Portal","title":"Flare Networks"},{"location":"dev/reference/network-config/#connected-networks","text":"Along with the endpoints listed above to interact with its own networks, Flare offers public RPC nodes for a series of other blockchain networks, to bootstrap development of connected services like attestation providers . All public RPC endpoints are experimental and rate-limited to avoid spamming attacks. For a production-grade option check out Flare's API Portal Bitcoin BNB-BSC Litecoin Dogecoin XRPL Algorand Ethereum RPC endpoint https://bitcoin-api.flare.network Sample query curl -s -X POST -m 10 -H \"Content-type: application/json\" \\ -d '{\"jsonrpc\": \"1.0\", \"id\":\"hc\", \"method\": \"getblockchaininfo\", \"params\":[]}' \\ -u public:d681co1pe2l3wcj9adrm2orlk0j5r5gr3wghgxt58tvge594co0k1ciljxq9glei \\ https://bitcoin-api.flare.network | jq RPC endpoint https://bnb-bsc-api.flare.network/ Sample query curl -s -X POST -m 10 -H \"Content-Type: application/json\" \\ -d '{\"jsonrpc\": \"2.0\", \"id\":67, \"method\":\"eth_blockNumber\", \"params\":[]}' \\ https://bnb-bsc-api.flare.network | jq RPC endpoint https://litecoin-api.flare.network Sample query curl -s -X POST -m 10 -H \"Content-type: application/json\" \\ -d '{\"jsonrpc\": \"1.0\", \"id\":\"hc\", \"method\": \"getblockchaininfo\", \"params\":[]}' \\ -u public:ntvzi4i1yne499t7vcdjqhhp92m3jvm0bb6dkpr406gkndvuns9sg6th3jd393uc \\ https://litecoin-api.flare.network | jq RPC endpoint https://dogecoin-api.flare.network Sample query curl -s -X POST -m 10 -H \"Content-type: application/json\" \\ -d '{\"jsonrpc\": \"1.0\", \"id\":\"hc\", \"method\": \"getblockchaininfo\", \"params\":[]}' \\ -u public:6r1e5z3w9g6qruvkzkqvz8w67yqrq5js2cmyl2f1cncbp7gpp7tqixqskuub5v70 \\ https://dogecoin-api.flare.network | jq RPC endpoint https://xrpl-api.flare.network Sample query curl -s -X POST -m 10 -H \"Content-type: application/json\" \\ -d '{\"method\": \"server_info\", \"params\":[{\"api_version\": 1}]}' \\ https://xrpl-api.flare.network | jq RPC endpoint https://algorand-api.flare.network Sample query curl -s -m 10 \\ -H \"X-Algo-API-Token: zl748k3wddvld8cvn64utnslbf7otorkijp84se0f58pmuu0shgm27gttpcjpmuq\" \\ https://algorand-api.flare.network/v2/status | jq RPC endpoint https://ethereum-api.flare.network/ Sample query curl -s -X POST -m 10 -H \"Content-Type: application/json\" \\ -d '{\"jsonrpc\": \"2.0\", \"id\":67, \"method\":\"eth_blockNumber\", \"params\":[]}' \\ https://ethereum-api.flare.network | jq","title":"Connected Networks"},{"location":"dev/reference/personal-delegation-account/","text":"Personal Delegation Accounts # Personal Delegation Accounts (PDAs) temporarily store rewards, such as FTSO delegation rewards, that users do not want to claim to their main accounts as explained in the Concept page . This page explains how to manage PDA functionality in applications. Required contracts # Working with the PDAs requires interacting with these contracts: ClaimSetupManager (CSM). FTSORewardManager (FTSO). To find the addresses of these contracts read the Contract Addresses page. Enabling a PDA # CSM.enableDelegationAccount() returns the address of the PDA associated with the caller's address, creating the PDA in the process if it didn't exist. A single PDA can be associated with each address and it cannot be destroyed once created, only disabled (see below). There exist no private keys to the PDA account so it cannot sign any transactions. All interaction with the PDA happens through the CSM contract, and is usually triggered by the user's main account. Note that this means that a PDA cannot have its own PDA, since no calls to the CSM can be made from the PDA account. Once a PDA is created, certain functions like FTSO.autoClaim() automatically send claimed rewards to the PDA account instead of the main account. See Delegation and Rewards below. Disabling a PDA # To disable the use of a PDA, call CSM.disableDelegationAccount() . Any $WFLR tokens that are on the PDA address are transferred back to the user's main account. When users disable their PDA, FTSO.autoClaim() claims only the rewards for their main account and to their main account. CSM.disableDelegationAccount() disables the PDA contract but does not destroy it: its address is still returned by CSM.getDelegationAccountData() , but the enabled boolean will be false . Checking PDA State # To check if a user's PDA is enabled, call CSM.getDelegationAccountData() . It returns both the PDA address and its state: Condition Address State PDA is enabled PDA address true PDA is disabled PDA address false PDA has never been created 0x000...000 false Never rely solely on the returned address being non-zero to check if an account has a PDA. Delegation and Rewards # A PDA is a regular account for which there are no private keys and which must be managed through the CSM contract instead. Conveniently, the method signatures to delegate on the CSM are the same as on the WNat contract where delegation is usually performed, for instance CSM.batchDelegate() . FTSO reward claiming, though, is still performed through the FTSORewardManager , for example using claimReward(address recipient, ...) where recipient allows sending to any address, including a PDA. For information on how to delegate and claim FTSO rewards, see Delegation and Rewards . In addition to the methods used for regular accounts, FTSO.autoClaim() automatically claims for both the main account and the PDA, to the PDA or the main account depending on whether the PDA is enabled or not. If users disable their PDA, autoClaim() claims rewards for only their main account and to only their main account. Note The autoClaim() method is unrelated to Automatic Claiming performed by executors. Governance Voting # Flare network users have a right to vote on proposals that can change the behavior of the network or add new features. The number of votes an address has is equal to the amount of wrapped Flare tokens ( $WFLR ) that the address holds. PDA addresses cannot vote directly, but their owners can transfer all their votes to another address (e.g., the owner's address) by calling CSM.delegateGovernance(address recipient) . The recipient of the votes can then vote with its own votes as well as with the votes received from other addresses. Transferring Funds # Because a PDA is a regular account, anyone can send funds to it. However, FLR tokens transferred to a PDA are automatically converted to $WFLR , making them convenient for delegation. Only the owner of the main account and its PDA can transfer funds from the PDA and only to its main account. To transfer tokens, the owner calls CSM.withdraw() and states the amount to withdraw. Since it has no private keys, any token other than $FLR or $WFLR transferred to the PDA cannot be moved out by conventional means. Instead, CSM.transferExternalToken() must be used to transfer them to another account. This is useful, for example, to recover airdropped tokens accidentally sent to the PDA. Note CSM.transferExternalToken() only works on ERC-20 tokens or token contracts that support the transfer function. Wallet or Dapp Integration # To support personal delegation accounts, a wallet or dapp at a minimum should show its status, including: Checking the user's PDA address and whether it is enabled. Showing the amount of $WFLR on the user's PDA. Additional integration could support the following actions: Enabling and disabling the PDA. Allowing the delegation of funds from a PDA to FTSO price providers. Delegating votes for governance voting. Claiming rewards to the PDA. Withdrawing funds from users' PDAs to their main accounts. Withdrawing custom ERC-20 tokens to the users' main accounts. See the Flare Portal for an example of such integration.","title":"Personal Delegation Accounts"},{"location":"dev/reference/personal-delegation-account/#personal-delegation-accounts","text":"Personal Delegation Accounts (PDAs) temporarily store rewards, such as FTSO delegation rewards, that users do not want to claim to their main accounts as explained in the Concept page . This page explains how to manage PDA functionality in applications.","title":"Personal Delegation Accounts"},{"location":"dev/reference/personal-delegation-account/#required-contracts","text":"Working with the PDAs requires interacting with these contracts: ClaimSetupManager (CSM). FTSORewardManager (FTSO). To find the addresses of these contracts read the Contract Addresses page.","title":"Required contracts"},{"location":"dev/reference/personal-delegation-account/#enabling-a-pda","text":"CSM.enableDelegationAccount() returns the address of the PDA associated with the caller's address, creating the PDA in the process if it didn't exist. A single PDA can be associated with each address and it cannot be destroyed once created, only disabled (see below). There exist no private keys to the PDA account so it cannot sign any transactions. All interaction with the PDA happens through the CSM contract, and is usually triggered by the user's main account. Note that this means that a PDA cannot have its own PDA, since no calls to the CSM can be made from the PDA account. Once a PDA is created, certain functions like FTSO.autoClaim() automatically send claimed rewards to the PDA account instead of the main account. See Delegation and Rewards below.","title":"Enabling a PDA"},{"location":"dev/reference/personal-delegation-account/#disabling-a-pda","text":"To disable the use of a PDA, call CSM.disableDelegationAccount() . Any $WFLR tokens that are on the PDA address are transferred back to the user's main account. When users disable their PDA, FTSO.autoClaim() claims only the rewards for their main account and to their main account. CSM.disableDelegationAccount() disables the PDA contract but does not destroy it: its address is still returned by CSM.getDelegationAccountData() , but the enabled boolean will be false .","title":"Disabling a PDA"},{"location":"dev/reference/personal-delegation-account/#checking-pda-state","text":"To check if a user's PDA is enabled, call CSM.getDelegationAccountData() . It returns both the PDA address and its state: Condition Address State PDA is enabled PDA address true PDA is disabled PDA address false PDA has never been created 0x000...000 false Never rely solely on the returned address being non-zero to check if an account has a PDA.","title":"Checking PDA State"},{"location":"dev/reference/personal-delegation-account/#delegation-and-rewards","text":"A PDA is a regular account for which there are no private keys and which must be managed through the CSM contract instead. Conveniently, the method signatures to delegate on the CSM are the same as on the WNat contract where delegation is usually performed, for instance CSM.batchDelegate() . FTSO reward claiming, though, is still performed through the FTSORewardManager , for example using claimReward(address recipient, ...) where recipient allows sending to any address, including a PDA. For information on how to delegate and claim FTSO rewards, see Delegation and Rewards . In addition to the methods used for regular accounts, FTSO.autoClaim() automatically claims for both the main account and the PDA, to the PDA or the main account depending on whether the PDA is enabled or not. If users disable their PDA, autoClaim() claims rewards for only their main account and to only their main account. Note The autoClaim() method is unrelated to Automatic Claiming performed by executors.","title":"Delegation and Rewards"},{"location":"dev/reference/personal-delegation-account/#governance-voting","text":"Flare network users have a right to vote on proposals that can change the behavior of the network or add new features. The number of votes an address has is equal to the amount of wrapped Flare tokens ( $WFLR ) that the address holds. PDA addresses cannot vote directly, but their owners can transfer all their votes to another address (e.g., the owner's address) by calling CSM.delegateGovernance(address recipient) . The recipient of the votes can then vote with its own votes as well as with the votes received from other addresses.","title":"Governance Voting"},{"location":"dev/reference/personal-delegation-account/#transferring-funds","text":"Because a PDA is a regular account, anyone can send funds to it. However, FLR tokens transferred to a PDA are automatically converted to $WFLR , making them convenient for delegation. Only the owner of the main account and its PDA can transfer funds from the PDA and only to its main account. To transfer tokens, the owner calls CSM.withdraw() and states the amount to withdraw. Since it has no private keys, any token other than $FLR or $WFLR transferred to the PDA cannot be moved out by conventional means. Instead, CSM.transferExternalToken() must be used to transfer them to another account. This is useful, for example, to recover airdropped tokens accidentally sent to the PDA. Note CSM.transferExternalToken() only works on ERC-20 tokens or token contracts that support the transfer function.","title":"Transferring Funds"},{"location":"dev/reference/personal-delegation-account/#wallet-or-dapp-integration","text":"To support personal delegation accounts, a wallet or dapp at a minimum should show its status, including: Checking the user's PDA address and whether it is enabled. Showing the amount of $WFLR on the user's PDA. Additional integration could support the following actions: Enabling and disabling the PDA. Allowing the delegation of funds from a PDA to FTSO price providers. Delegating votes for governance voting. Claiming rewards to the PDA. Withdrawing funds from users' PDAs to their main accounts. Withdrawing custom ERC-20 tokens to the users' main accounts. See the Flare Portal for an example of such integration.","title":"Wallet or Dapp Integration"},{"location":"dev/reference/the-flaredrop/","text":"The FlareDrop # The FlareDrop , previously called the Delegation Incentive Pool in the FIP.01 , is a distribution method for the 24.25B remaining $FLR tokens after the original airdrop . This page explains how to manage FlareDrop functionality in applications. Required Contracts # Working with the FlareDrop requires interacting with these contracts: DistributionToDelegators (Dist). Manages all claims. ClaimSetupManager (CSM). Needed to configure autoclaiming. To find their addresses, read the Contract Addresses page. Operations # Basic Claiming # The Dist.claim method allows claiming the FlareDrop one account at a time. function claim ( address _rewardOwner , address _recipient , uint256 _month , bool _wrap ) external returns ( uint256 _rewardAmount ); It transfers the FlareDrop rewards accrued by account _rewardOwner during the specified _month to the specified _recipient . _wrap controls whether the reward is transferred in native $FLR tokens or wrapped in $WFLR tokens. You can use Dist.getCurrentMonth() to find out the current month (starting at 0), or Dist.getClaimableMonths() to get the interval of months which are currently available for claiming. Use Dist.getClaimableAmount() or Dist.getClaimableAmountOf() to find out if a given address has pending rewards on any given month. Dist.claim() returns the amount of claimed rewards. Two modes of operation are supported: Self-claiming and claiming on behalf of another account. Self-Claiming : When msg.sender matches _rewardOwner , the caller is claiming its own rewards. In this case _recipient can be any address. Claiming on behalf of another account : When msg.sender does not match _rewardOwner , the caller must be a claim executor , claiming on behalf of _rewardOwner . If _msg.sender is not in the authorized list of executors for _rewardOwner , the call will revert. Authorized executors must be set beforehand by _rewardOwner using CSM.setClaimExecutors() . The _recipient must either be _rewardOwner , its PDA , or any of the authorized recipients previously set by _rewardOwner using CSM.setAllowedClaimRecipients() . The call will revert otherwise. Batched Claiming # The Dist.autoClaim() method allows claiming the FlareDrop for an arbitrary amount of accounts in a single call, with convenient default values. function autoClaim ( address [] calldata _rewardOwners , uint256 _month ) external ; It claims the rewards accrued by all the accounts in the _rewardOwners array during the specified _month . If an account does not have an enabled PDA , the rewards are sent to the same account. However, if an account does have an enabled PDA, the rewards are sent to the PDA account. Any rewards accrued by the PDA account are also claimed and sent to the PDA. Rewards claimed with this method are always wrapped. If the executor is a registered executor with a nonzero fee, the fee is automatically deducted from each claimed reward and sent to the executor account (unwrapped). If rewards are claimed for both an address and its PDA, the fee is deducted only once. The call reverts if: msg.sender is not in the authorized list of executors for any of the _rewardOwners . The total claimed rewards for any of the _rewardOwners is not high enough to cover the executor's fee.","title":"The FlareDrop"},{"location":"dev/reference/the-flaredrop/#the-flaredrop","text":"The FlareDrop , previously called the Delegation Incentive Pool in the FIP.01 , is a distribution method for the 24.25B remaining $FLR tokens after the original airdrop . This page explains how to manage FlareDrop functionality in applications.","title":"The FlareDrop"},{"location":"dev/reference/the-flaredrop/#required-contracts","text":"Working with the FlareDrop requires interacting with these contracts: DistributionToDelegators (Dist). Manages all claims. ClaimSetupManager (CSM). Needed to configure autoclaiming. To find their addresses, read the Contract Addresses page.","title":"Required Contracts"},{"location":"dev/reference/the-flaredrop/#operations","text":"","title":"Operations"},{"location":"dev/reference/the-flaredrop/#basic-claiming","text":"The Dist.claim method allows claiming the FlareDrop one account at a time. function claim ( address _rewardOwner , address _recipient , uint256 _month , bool _wrap ) external returns ( uint256 _rewardAmount ); It transfers the FlareDrop rewards accrued by account _rewardOwner during the specified _month to the specified _recipient . _wrap controls whether the reward is transferred in native $FLR tokens or wrapped in $WFLR tokens. You can use Dist.getCurrentMonth() to find out the current month (starting at 0), or Dist.getClaimableMonths() to get the interval of months which are currently available for claiming. Use Dist.getClaimableAmount() or Dist.getClaimableAmountOf() to find out if a given address has pending rewards on any given month. Dist.claim() returns the amount of claimed rewards. Two modes of operation are supported: Self-claiming and claiming on behalf of another account. Self-Claiming : When msg.sender matches _rewardOwner , the caller is claiming its own rewards. In this case _recipient can be any address. Claiming on behalf of another account : When msg.sender does not match _rewardOwner , the caller must be a claim executor , claiming on behalf of _rewardOwner . If _msg.sender is not in the authorized list of executors for _rewardOwner , the call will revert. Authorized executors must be set beforehand by _rewardOwner using CSM.setClaimExecutors() . The _recipient must either be _rewardOwner , its PDA , or any of the authorized recipients previously set by _rewardOwner using CSM.setAllowedClaimRecipients() . The call will revert otherwise.","title":"Basic Claiming"},{"location":"dev/reference/the-flaredrop/#batched-claiming","text":"The Dist.autoClaim() method allows claiming the FlareDrop for an arbitrary amount of accounts in a single call, with convenient default values. function autoClaim ( address [] calldata _rewardOwners , uint256 _month ) external ; It claims the rewards accrued by all the accounts in the _rewardOwners array during the specified _month . If an account does not have an enabled PDA , the rewards are sent to the same account. However, if an account does have an enabled PDA, the rewards are sent to the PDA account. Any rewards accrued by the PDA account are also claimed and sent to the PDA. Rewards claimed with this method are always wrapped. If the executor is a registered executor with a nonzero fee, the fee is automatically deducted from each claimed reward and sent to the executor account (unwrapped). If rewards are claimed for both an address and its PDA, the fee is deducted only once. The call reverts if: msg.sender is not in the authorized list of executors for any of the _rewardOwners . The total claimed rewards for any of the _rewardOwners is not high enough to cover the executor's fee.","title":"Batched Claiming"},{"location":"dev/reference/wallets/","text":"Wallets # Information for wallet developers wanting to integrate with the Flare networks. First off, find all basic network information like Chain ID or public RPC endpoints in the Network Configuration page. This page then provides a few more pointers specific to wallet development. Block Explorers and Indexers # For all its networks, Flare offers public block explorers that double down as indexers. Learn about them in the Block Explorers section. Flare's Personal Delegation Accounts # See the Integration with a Personal Delegation Account page. Address Derivation Paths for HD Wallets # Address derivation and format validation on Flare are the same as on Ethereum. In particular, Flare uses the same coin type as Ethereum, this is, 60. The BIP-44 paths are therefore m/44\u2019/60\u2019/x\u2019/0/0 (hardened) and m/44\u2019/60\u2019/0\u2019/0/x . The same path is used on both the C-chain and the P-chain .","title":"Wallets"},{"location":"dev/reference/wallets/#wallets","text":"Information for wallet developers wanting to integrate with the Flare networks. First off, find all basic network information like Chain ID or public RPC endpoints in the Network Configuration page. This page then provides a few more pointers specific to wallet development.","title":"Wallets"},{"location":"dev/reference/wallets/#block-explorers-and-indexers","text":"For all its networks, Flare offers public block explorers that double down as indexers. Learn about them in the Block Explorers section.","title":"Block Explorers and Indexers"},{"location":"dev/reference/wallets/#flares-personal-delegation-accounts","text":"See the Integration with a Personal Delegation Account page.","title":"Flare's Personal Delegation Accounts"},{"location":"dev/reference/wallets/#address-derivation-paths-for-hd-wallets","text":"Address derivation and format validation on Flare are the same as on Ethereum. In particular, Flare uses the same coin type as Ethereum, this is, 60. The BIP-44 paths are therefore m/44\u2019/60\u2019/x\u2019/0/0 (hardened) and m/44\u2019/60\u2019/0\u2019/0/x . The same path is used on both the C-chain and the P-chain .","title":"Address Derivation Paths for HD Wallets"},{"location":"dev/tutorials/","text":"Tutorials # The Flare developer tutorials are divided into the following topics. Topics # Accessing the Network FTSO","title":"Tutorials"},{"location":"dev/tutorials/#tutorials","text":"The Flare developer tutorials are divided into the following topics.","title":"Tutorials"},{"location":"dev/tutorials/#topics","text":"Accessing the Network FTSO","title":"Topics"},{"location":"dev/tutorials/ftso/","text":"FTSO Tutorials # These code samples and explanations show how to use the FTSO system . Tutorials # Getting FTSO Data Feeds","title":"FTSO Tutorials"},{"location":"dev/tutorials/ftso/#ftso-tutorials","text":"These code samples and explanations show how to use the FTSO system .","title":"FTSO Tutorials"},{"location":"dev/tutorials/ftso/#tutorials","text":"Getting FTSO Data Feeds","title":"Tutorials"},{"location":"dev/tutorials/ftso/getting-data-feeds/","text":"Getting FTSO Data Feeds # This tutorial shows the simplest way to use the FTSO system to retrieve a specific data feed, like the price of Bitcoin. The tutorial shows: How to use the Flare periphery packages to simplify working with the Flare API. How to retrieve the latest price for a given asset from the FTSO system. Code # Choose your preferred programming language and ensure you have a working development environment . For easy navigation, numbered comments in the source code link to the tutorial sections below. Solidity JavaScript GettingDataFeeds.sol 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 // SPDX-License-Identifier: MIT pragma solidity ^ 0.8.0 ; // 1. Import dependencies import \"@flarenetwork/flare-periphery-contracts/flare/util-contracts/userInterfaces/IFlareContractRegistry.sol\" ; import \"@flarenetwork/flare-periphery-contracts/flare/ftso/userInterfaces/IFtsoRegistry.sol\" ; contract GettingDataFeeds { address private constant FLARE_CONTRACT_REGISTRY = 0xaD67FE66660Fb8dFE9d6b1b4240d8650e30F6019 ; function getTokenPriceWei ( string memory _symbol ) public view returns ( uint256 _price , uint256 _timestamp , uint256 _decimals ) { // 2. Access the Contract Registry IFlareContractRegistry contractRegistry = IFlareContractRegistry ( FLARE_CONTRACT_REGISTRY ); // 3. Retrieve the FTSO Registry IFtsoRegistry ftsoRegistry = IFtsoRegistry ( contractRegistry . getContractAddressByName ( 'FtsoRegistry' )); // 4. Get latest price ( _price , _timestamp , _decimals ) = ftsoRegistry . getCurrentPriceWithDecimals ( _symbol ); } } Source code license Building with Hardhat Create a new folder and move into it. Follow any of the setup guides to create a new project. For example: npm init npm install hardhat @nomicfoundation/hardhat-toolbox npx hardhat Add Flare's Periphery Package as a dependency with: npm install @flarenetwork/flare-periphery-contracts Copy the code above into a new file called GettingDataFeeds.sol in the contracts folder. Compile with npx hardhat compile . GettingDataFeeds.js 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 const FLARE_PACKAGE = \"@flarenetwork/flare-periphery-contract-artifacts\" ; const FLARE_RPC = \"https://flare-api.flare.network/ext/C/rpc\" ; async function GettingDataFeeds_run ( _symbol ) { console . log ( `Retrieving current price of ${ _symbol } ...` ); // 1. Import dependencies var ethers , flare ; if ( typeof window === \"undefined\" ) { // Node.js ethers = await import ( \"ethers\" ); flare = await import ( FLARE_PACKAGE ); } else { // Browser ethers = await import ( \"https://esm.run/ethers@6.3\" ); flare = await import ( `https://esm.run/ ${ FLARE_PACKAGE } ` ); } // Node to submit queries to. const provider = new ethers . JsonRpcProvider ( FLARE_RPC ); // 2. Access the Contract Registry const flareContractRegistry = new ethers . Contract ( \"0xaD67FE66660Fb8dFE9d6b1b4240d8650e30F6019\" , flare . nameToAbi ( \"FlareContractRegistry\" , \"flare\" ). data , provider ); // 3. Retrieve the FTSO Registry const ftsoRegistryAddr = await flareContractRegistry . getContractAddressByName ( \"FtsoRegistry\" ); const ftsoRegistry = new ethers . Contract ( ftsoRegistryAddr , flare . nameToAbi ( \"FtsoRegistry\" , \"flare\" ). data , provider ); // 4. Get latest price const [ _price , _timestamp , _decimals ] = await ftsoRegistry [ \"getCurrentPriceWithDecimals(string)\" ]( _symbol ); console . log ( ` ${ Number ( _price ) / Math . pow ( 10 , Number ( _decimals )) } USD` ); console . log ( `Calculated at ${ new Date ( Number ( _timestamp ) * 1000 ) } ` ); } GettingDataFeeds_run ( \"BTC\" ); Source code license async function GettingDataFeeds_runner() { console.old_log = console.log; if (!document.getElementById('GettingDataFeeds-run-me-button').hasAttribute('open')) { console.log = console.old_log; return; } console.old_log = console.log; output = document.getElementById('GettingDataFeeds-output').getElementsByTagName('code')[0]; output.innerHTML = \"\"; console.log = function(message) { output.innerHTML += (typeof message == 'object' ? JSON.stringify(message, null, 2) : message) + \"\\n\"; }; await GettingDataFeeds_run('BTC'); console.log = console.old_log; } Run with Node.js This tutorial has been tested with npm v9.5 and Node.js v18.16 . Create a new folder and move into it. Copy & paste the code above into a new file called GettingDataFeeds.js . Install dependencies with: npm init npm install ethers @flarenetwork/flare-periphery-contract-artifacts Run the program with: node GettingDataFeeds.js Run in browser const FLARE_PACKAGE = \"@flarenetwork/flare-periphery-contract-artifacts\"; const FLARE_RPC = \"https://flare-api.flare.network/ext/C/rpc\"; async function GettingDataFeeds_run(_symbol) { console.log(`Retrieving current price of ${_symbol}...`); // 1. Import dependencies var ethers, flare; if (typeof window === \"undefined\") { // Node.js ethers = await import(\"ethers\"); flare = await import(FLARE_PACKAGE); } else { // Browser ethers = await import(\"https://esm.run/ethers@6.3\"); flare = await import(`https://esm.run/${FLARE_PACKAGE}`); } // Node to submit queries to. const provider = new ethers.JsonRpcProvider(FLARE_RPC); // 2. Access the Contract Registry const flareContractRegistry = new ethers.Contract( \"0xaD67FE66660Fb8dFE9d6b1b4240d8650e30F6019\", flare.nameToAbi(\"FlareContractRegistry\", \"flare\").data, provider); // 3. Retrieve the FTSO Registry const ftsoRegistryAddr = await flareContractRegistry.getContractAddressByName(\"FtsoRegistry\"); const ftsoRegistry = new ethers.Contract( ftsoRegistryAddr, flare.nameToAbi(\"FtsoRegistry\", \"flare\").data, provider); // 4. Get latest price const [_price, _timestamp, _decimals] = await ftsoRegistry[\"getCurrentPriceWithDecimals(string)\"](_symbol); console.log(`${Number(_price) / Math.pow(10, Number(_decimals))} USD`); console.log(`Calculated at ${new Date(Number(_timestamp) * 1000)}`); } Tutorial # 1. Import Dependencies # The tutorial uses the following dependencies: The Flare Periphery Package for Solidity and the Flare Periphery Artifacts Package for JavaScript, which provide the API for all Flare smart contracts. If you use JavaScript, the ethers package is also needed to work with smart contracts. Solidity JavaScript 6 7 import \"@flarenetwork/flare-periphery-contracts/flare/util-contracts/userInterfaces/IFlareContractRegistry.sol\" ; import \"@flarenetwork/flare-periphery-contracts/flare/ftso/userInterfaces/IFtsoRegistry.sol\" ; 8 9 10 11 12 13 14 15 16 17 var ethers , flare ; if ( typeof window === \"undefined\" ) { // Node.js ethers = await import ( \"ethers\" ); flare = await import ( FLARE_PACKAGE ); } else { // Browser ethers = await import ( \"https://esm.run/ethers@6.3\" ); flare = await import ( `https://esm.run/ ${ FLARE_PACKAGE } ` ); } The Periphery Packages simplify working with the Flare smart contracts significantly. If you remove this dependency, you must manually provide the signatures for all the methods you want to use. 2. Access the Contract Registry # The FlareContractRegistry contains the current addresses for all Flare smart contracts, and it is the only recommended way to retrieve them. Its address is the same on all of Flare's networks , and it is the only Flare address that needs to be hard-coded into any program. Solidity JavaScript 20 21 IFlareContractRegistry contractRegistry = IFlareContractRegistry ( FLARE_CONTRACT_REGISTRY ); 23 24 25 26 const flareContractRegistry = new ethers . Contract ( \"0xaD67FE66660Fb8dFE9d6b1b4240d8650e30F6019\" , flare . nameToAbi ( \"FlareContractRegistry\" , \"flare\" ). data , provider ); 3. Retrieve the FTSO Registry # Prices for all assets tracked by the FTSO system are recovered through the FtsoRegistry contract. Use the getContractAddressByName() method from the FlareContractRegistry to retrieve the address of the FtsoRegistry . Solidity JavaScript 24 25 IFtsoRegistry ftsoRegistry = IFtsoRegistry ( contractRegistry . getContractAddressByName ( 'FtsoRegistry' )); 29 30 31 32 33 34 const ftsoRegistryAddr = await flareContractRegistry . getContractAddressByName ( \"FtsoRegistry\" ); const ftsoRegistry = new ethers . Contract ( ftsoRegistryAddr , flare . nameToAbi ( \"FtsoRegistry\" , \"flare\" ). data , provider ); This address can be retrieved in the initialization phase of your program and used afterward. There is no need to fetch it every time it must be used. 4. Get Latest Price # Finally, the asset's price is fetched from the FtsoRegistry using getCurrentPriceWithDecimals . Solidity JavaScript 28 29 ( _price , _timestamp , _decimals ) = ftsoRegistry . getCurrentPriceWithDecimals ( _symbol ); 37 38 39 40 41 const [ _price , _timestamp , _decimals ] = await ftsoRegistry [ \"getCurrentPriceWithDecimals(string)\" ]( _symbol ); console . log ( ` ${ Number ( _price ) / Math . pow ( 10 , Number ( _decimals )) } USD` ); console . log ( `Calculated at ${ new Date ( Number ( _timestamp ) * 1000 ) } ` ); The only parameter of this method is the symbol for the asset being queried, like \"FLR\" or \"BTC\" . You can use getSupportedSymbols() to retrieve the list of all supported symbols. Given that Solidity does not support numbers with decimals, this method returns the requested price as an integer and the number of decimal places by which the comma must be shifted. For example, if it returns 1234 for the price and 2 for the decimals, the actual price of the asset in USD is 12.34 . It also returns the time when the price was calculated by the FTSO system as a UNIX timestamp . You can use an online tool like EpochConverter to turn the timestamp into a human-readable form, or use Date as in the JavaScript example. JavaScript note on overloaded methods The call to the getCurrentPriceWithDecimals method is a bit cumbersome in JavaScript: 37 38 const [ _price , _timestamp , _decimals ] = await ftsoRegistry [ \"getCurrentPriceWithDecimals(string)\" ]( _symbol ); The call needs to be like this because this method is overloaded. getCurrentPriceWithDecimals has two versions: one accepting a string for the symbol and another one accepting an integer for the asset's index in the FTSO system. Therefore, the call needs to disambiguate both versions. The vast majority of methods are not overloaded and allow a more natural call format. For example: await ftsoRegistry . getSupportedSymbols (); Conclusion # This tutorial served as the Hello World program for the FTSO system . It has shown: How to use the Flare Periphery Package, both from Solidity and from JavaScript . How to retrieve the latest price for a given asset from the FTSO system.","title":"Getting FTSO Data Feeds"},{"location":"dev/tutorials/ftso/getting-data-feeds/#getting-ftso-data-feeds","text":"This tutorial shows the simplest way to use the FTSO system to retrieve a specific data feed, like the price of Bitcoin. The tutorial shows: How to use the Flare periphery packages to simplify working with the Flare API. How to retrieve the latest price for a given asset from the FTSO system.","title":"Getting FTSO Data Feeds"},{"location":"dev/tutorials/ftso/getting-data-feeds/#code","text":"Choose your preferred programming language and ensure you have a working development environment . For easy navigation, numbered comments in the source code link to the tutorial sections below. Solidity JavaScript GettingDataFeeds.sol 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 // SPDX-License-Identifier: MIT pragma solidity ^ 0.8.0 ; // 1. Import dependencies import \"@flarenetwork/flare-periphery-contracts/flare/util-contracts/userInterfaces/IFlareContractRegistry.sol\" ; import \"@flarenetwork/flare-periphery-contracts/flare/ftso/userInterfaces/IFtsoRegistry.sol\" ; contract GettingDataFeeds { address private constant FLARE_CONTRACT_REGISTRY = 0xaD67FE66660Fb8dFE9d6b1b4240d8650e30F6019 ; function getTokenPriceWei ( string memory _symbol ) public view returns ( uint256 _price , uint256 _timestamp , uint256 _decimals ) { // 2. Access the Contract Registry IFlareContractRegistry contractRegistry = IFlareContractRegistry ( FLARE_CONTRACT_REGISTRY ); // 3. Retrieve the FTSO Registry IFtsoRegistry ftsoRegistry = IFtsoRegistry ( contractRegistry . getContractAddressByName ( 'FtsoRegistry' )); // 4. Get latest price ( _price , _timestamp , _decimals ) = ftsoRegistry . getCurrentPriceWithDecimals ( _symbol ); } } Source code license Building with Hardhat Create a new folder and move into it. Follow any of the setup guides to create a new project. For example: npm init npm install hardhat @nomicfoundation/hardhat-toolbox npx hardhat Add Flare's Periphery Package as a dependency with: npm install @flarenetwork/flare-periphery-contracts Copy the code above into a new file called GettingDataFeeds.sol in the contracts folder. Compile with npx hardhat compile . GettingDataFeeds.js 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 const FLARE_PACKAGE = \"@flarenetwork/flare-periphery-contract-artifacts\" ; const FLARE_RPC = \"https://flare-api.flare.network/ext/C/rpc\" ; async function GettingDataFeeds_run ( _symbol ) { console . log ( `Retrieving current price of ${ _symbol } ...` ); // 1. Import dependencies var ethers , flare ; if ( typeof window === \"undefined\" ) { // Node.js ethers = await import ( \"ethers\" ); flare = await import ( FLARE_PACKAGE ); } else { // Browser ethers = await import ( \"https://esm.run/ethers@6.3\" ); flare = await import ( `https://esm.run/ ${ FLARE_PACKAGE } ` ); } // Node to submit queries to. const provider = new ethers . JsonRpcProvider ( FLARE_RPC ); // 2. Access the Contract Registry const flareContractRegistry = new ethers . Contract ( \"0xaD67FE66660Fb8dFE9d6b1b4240d8650e30F6019\" , flare . nameToAbi ( \"FlareContractRegistry\" , \"flare\" ). data , provider ); // 3. Retrieve the FTSO Registry const ftsoRegistryAddr = await flareContractRegistry . getContractAddressByName ( \"FtsoRegistry\" ); const ftsoRegistry = new ethers . Contract ( ftsoRegistryAddr , flare . nameToAbi ( \"FtsoRegistry\" , \"flare\" ). data , provider ); // 4. Get latest price const [ _price , _timestamp , _decimals ] = await ftsoRegistry [ \"getCurrentPriceWithDecimals(string)\" ]( _symbol ); console . log ( ` ${ Number ( _price ) / Math . pow ( 10 , Number ( _decimals )) } USD` ); console . log ( `Calculated at ${ new Date ( Number ( _timestamp ) * 1000 ) } ` ); } GettingDataFeeds_run ( \"BTC\" ); Source code license async function GettingDataFeeds_runner() { console.old_log = console.log; if (!document.getElementById('GettingDataFeeds-run-me-button').hasAttribute('open')) { console.log = console.old_log; return; } console.old_log = console.log; output = document.getElementById('GettingDataFeeds-output').getElementsByTagName('code')[0]; output.innerHTML = \"\"; console.log = function(message) { output.innerHTML += (typeof message == 'object' ? JSON.stringify(message, null, 2) : message) + \"\\n\"; }; await GettingDataFeeds_run('BTC'); console.log = console.old_log; } Run with Node.js This tutorial has been tested with npm v9.5 and Node.js v18.16 . Create a new folder and move into it. Copy & paste the code above into a new file called GettingDataFeeds.js . Install dependencies with: npm init npm install ethers @flarenetwork/flare-periphery-contract-artifacts Run the program with: node GettingDataFeeds.js Run in browser const FLARE_PACKAGE = \"@flarenetwork/flare-periphery-contract-artifacts\"; const FLARE_RPC = \"https://flare-api.flare.network/ext/C/rpc\"; async function GettingDataFeeds_run(_symbol) { console.log(`Retrieving current price of ${_symbol}...`); // 1. Import dependencies var ethers, flare; if (typeof window === \"undefined\") { // Node.js ethers = await import(\"ethers\"); flare = await import(FLARE_PACKAGE); } else { // Browser ethers = await import(\"https://esm.run/ethers@6.3\"); flare = await import(`https://esm.run/${FLARE_PACKAGE}`); } // Node to submit queries to. const provider = new ethers.JsonRpcProvider(FLARE_RPC); // 2. Access the Contract Registry const flareContractRegistry = new ethers.Contract( \"0xaD67FE66660Fb8dFE9d6b1b4240d8650e30F6019\", flare.nameToAbi(\"FlareContractRegistry\", \"flare\").data, provider); // 3. Retrieve the FTSO Registry const ftsoRegistryAddr = await flareContractRegistry.getContractAddressByName(\"FtsoRegistry\"); const ftsoRegistry = new ethers.Contract( ftsoRegistryAddr, flare.nameToAbi(\"FtsoRegistry\", \"flare\").data, provider); // 4. Get latest price const [_price, _timestamp, _decimals] = await ftsoRegistry[\"getCurrentPriceWithDecimals(string)\"](_symbol); console.log(`${Number(_price) / Math.pow(10, Number(_decimals))} USD`); console.log(`Calculated at ${new Date(Number(_timestamp) * 1000)}`); }","title":"Code"},{"location":"dev/tutorials/ftso/getting-data-feeds/#tutorial","text":"","title":"Tutorial"},{"location":"dev/tutorials/ftso/getting-data-feeds/#1-import-dependencies","text":"The tutorial uses the following dependencies: The Flare Periphery Package for Solidity and the Flare Periphery Artifacts Package for JavaScript, which provide the API for all Flare smart contracts. If you use JavaScript, the ethers package is also needed to work with smart contracts. Solidity JavaScript 6 7 import \"@flarenetwork/flare-periphery-contracts/flare/util-contracts/userInterfaces/IFlareContractRegistry.sol\" ; import \"@flarenetwork/flare-periphery-contracts/flare/ftso/userInterfaces/IFtsoRegistry.sol\" ; 8 9 10 11 12 13 14 15 16 17 var ethers , flare ; if ( typeof window === \"undefined\" ) { // Node.js ethers = await import ( \"ethers\" ); flare = await import ( FLARE_PACKAGE ); } else { // Browser ethers = await import ( \"https://esm.run/ethers@6.3\" ); flare = await import ( `https://esm.run/ ${ FLARE_PACKAGE } ` ); } The Periphery Packages simplify working with the Flare smart contracts significantly. If you remove this dependency, you must manually provide the signatures for all the methods you want to use.","title":"1. Import Dependencies"},{"location":"dev/tutorials/ftso/getting-data-feeds/#2-access-the-contract-registry","text":"The FlareContractRegistry contains the current addresses for all Flare smart contracts, and it is the only recommended way to retrieve them. Its address is the same on all of Flare's networks , and it is the only Flare address that needs to be hard-coded into any program. Solidity JavaScript 20 21 IFlareContractRegistry contractRegistry = IFlareContractRegistry ( FLARE_CONTRACT_REGISTRY ); 23 24 25 26 const flareContractRegistry = new ethers . Contract ( \"0xaD67FE66660Fb8dFE9d6b1b4240d8650e30F6019\" , flare . nameToAbi ( \"FlareContractRegistry\" , \"flare\" ). data , provider );","title":"2. Access the Contract Registry"},{"location":"dev/tutorials/ftso/getting-data-feeds/#3-retrieve-the-ftso-registry","text":"Prices for all assets tracked by the FTSO system are recovered through the FtsoRegistry contract. Use the getContractAddressByName() method from the FlareContractRegistry to retrieve the address of the FtsoRegistry . Solidity JavaScript 24 25 IFtsoRegistry ftsoRegistry = IFtsoRegistry ( contractRegistry . getContractAddressByName ( 'FtsoRegistry' )); 29 30 31 32 33 34 const ftsoRegistryAddr = await flareContractRegistry . getContractAddressByName ( \"FtsoRegistry\" ); const ftsoRegistry = new ethers . Contract ( ftsoRegistryAddr , flare . nameToAbi ( \"FtsoRegistry\" , \"flare\" ). data , provider ); This address can be retrieved in the initialization phase of your program and used afterward. There is no need to fetch it every time it must be used.","title":"3. Retrieve the FTSO Registry"},{"location":"dev/tutorials/ftso/getting-data-feeds/#4-get-latest-price","text":"Finally, the asset's price is fetched from the FtsoRegistry using getCurrentPriceWithDecimals . Solidity JavaScript 28 29 ( _price , _timestamp , _decimals ) = ftsoRegistry . getCurrentPriceWithDecimals ( _symbol ); 37 38 39 40 41 const [ _price , _timestamp , _decimals ] = await ftsoRegistry [ \"getCurrentPriceWithDecimals(string)\" ]( _symbol ); console . log ( ` ${ Number ( _price ) / Math . pow ( 10 , Number ( _decimals )) } USD` ); console . log ( `Calculated at ${ new Date ( Number ( _timestamp ) * 1000 ) } ` ); The only parameter of this method is the symbol for the asset being queried, like \"FLR\" or \"BTC\" . You can use getSupportedSymbols() to retrieve the list of all supported symbols. Given that Solidity does not support numbers with decimals, this method returns the requested price as an integer and the number of decimal places by which the comma must be shifted. For example, if it returns 1234 for the price and 2 for the decimals, the actual price of the asset in USD is 12.34 . It also returns the time when the price was calculated by the FTSO system as a UNIX timestamp . You can use an online tool like EpochConverter to turn the timestamp into a human-readable form, or use Date as in the JavaScript example. JavaScript note on overloaded methods The call to the getCurrentPriceWithDecimals method is a bit cumbersome in JavaScript: 37 38 const [ _price , _timestamp , _decimals ] = await ftsoRegistry [ \"getCurrentPriceWithDecimals(string)\" ]( _symbol ); The call needs to be like this because this method is overloaded. getCurrentPriceWithDecimals has two versions: one accepting a string for the symbol and another one accepting an integer for the asset's index in the FTSO system. Therefore, the call needs to disambiguate both versions. The vast majority of methods are not overloaded and allow a more natural call format. For example: await ftsoRegistry . getSupportedSymbols ();","title":"4. Get Latest Price"},{"location":"dev/tutorials/ftso/getting-data-feeds/#conclusion","text":"This tutorial served as the Hello World program for the FTSO system . It has shown: How to use the Flare Periphery Package, both from Solidity and from JavaScript . How to retrieve the latest price for a given asset from the FTSO system.","title":"Conclusion"},{"location":"dev/tutorials/network-access/","text":"Accessing the Network # The following tutorials deal with common problems encountered when accessing the Flare networks, like sending transactions or reading events. Tutorials # Checking Transaction Finalization Reliable Event Reading Obtaining a Transaction's Revert Reason","title":"Accessing the Network"},{"location":"dev/tutorials/network-access/#accessing-the-network","text":"The following tutorials deal with common problems encountered when accessing the Flare networks, like sending transactions or reading events.","title":"Accessing the Network"},{"location":"dev/tutorials/network-access/#tutorials","text":"Checking Transaction Finalization Reliable Event Reading Obtaining a Transaction's Revert Reason","title":"Tutorials"},{"location":"dev/tutorials/network-access/obtaining-revert-reason/","text":"Obtaining a Transaction's Revert Reason # Sometimes contract calls revert and throw a generic \"Transaction has been reverted\" exception which is not very helpful, since it does not contain the revert reason. In this case, simulating the call in the EVM without sending any transaction, using the .call() syntax, can provide the missing information, assuming the blockchain's state has not changed much between calls. The whole process is: Catch the exception, and check if the revert reason is part of the exception data. If not: Repeat the same contract call using .call() syntax and parse the revert reason. Note that the second step should be performed as soon as possible, to ensure that the chain has a similar state in both calls. The function below demonstrates this process. async function contractCall ( account , to , gas , gasPrice , fnToEncode , nonce ) { let tx = { from : account . address , to , gas , gasPrice , data : fnToEncode . encodeABI (), nonce }; let signedTx = await account . signTransaction ( tx ); try { return await web3 . eth . sendSignedTransaction ( signedTx . rawTransaction ); } catch ( e ) { if ( e . message . indexOf ( \"Transaction has been reverted by the EVM\" ) >= 0 ) { // This call should throw a new exception containing the revert reason await fnToEncode . call ({ from : account . address }); } // Otherwise, either revert reason was already part of the original error or // we failed to get any additional information. throw e ; } } Where account and fnToEncode are obtained, for example, as follows: let account = web3 . eth . accounts . privateKeyToAccount ( privateKey ); let fnToEncode = web3Contract . methods . someMethodOnContract ( param1 , param2 );","title":"Obtaining a Transaction's Revert Reason"},{"location":"dev/tutorials/network-access/obtaining-revert-reason/#obtaining-a-transactions-revert-reason","text":"Sometimes contract calls revert and throw a generic \"Transaction has been reverted\" exception which is not very helpful, since it does not contain the revert reason. In this case, simulating the call in the EVM without sending any transaction, using the .call() syntax, can provide the missing information, assuming the blockchain's state has not changed much between calls. The whole process is: Catch the exception, and check if the revert reason is part of the exception data. If not: Repeat the same contract call using .call() syntax and parse the revert reason. Note that the second step should be performed as soon as possible, to ensure that the chain has a similar state in both calls. The function below demonstrates this process. async function contractCall ( account , to , gas , gasPrice , fnToEncode , nonce ) { let tx = { from : account . address , to , gas , gasPrice , data : fnToEncode . encodeABI (), nonce }; let signedTx = await account . signTransaction ( tx ); try { return await web3 . eth . sendSignedTransaction ( signedTx . rawTransaction ); } catch ( e ) { if ( e . message . indexOf ( \"Transaction has been reverted by the EVM\" ) >= 0 ) { // This call should throw a new exception containing the revert reason await fnToEncode . call ({ from : account . address }); } // Otherwise, either revert reason was already part of the original error or // we failed to get any additional information. throw e ; } } Where account and fnToEncode are obtained, for example, as follows: let account = web3 . eth . accounts . privateKeyToAccount ( privateKey ); let fnToEncode = web3Contract . methods . someMethodOnContract ( param1 , param2 );","title":"Obtaining a Transaction's Revert Reason"},{"location":"dev/tutorials/network-access/reliable-event-reading/","text":"Reliable Event Reading # Subscription to events, for example using listeners, has proved to be unreliable, especially when high traffic exists on the network. To reliably read events it is recommended to use the getPastEvents function on web3 contracts. This function has parameters fromBlock and toBlock so the caller has to keep track of which blocks have already been requested. The number of blocks the user can request in a single RPC call depends on the configuration of the RPC node being used. In particular, if the node is run with the environment variable WEB3_API set to debug (a so-called \"full node\"), usually 100 blocks of events can be read in one call. On the other hand, if WEB3_API is set to enabled (a \"light node\") only 1 block of events can be read.","title":"Reliable Event Reading"},{"location":"dev/tutorials/network-access/reliable-event-reading/#reliable-event-reading","text":"Subscription to events, for example using listeners, has proved to be unreliable, especially when high traffic exists on the network. To reliably read events it is recommended to use the getPastEvents function on web3 contracts. This function has parameters fromBlock and toBlock so the caller has to keep track of which blocks have already been requested. The number of blocks the user can request in a single RPC call depends on the configuration of the RPC node being used. In particular, if the node is run with the environment variable WEB3_API set to debug (a so-called \"full node\"), usually 100 blocks of events can be read in one call. On the other hand, if WEB3_API is set to enabled (a \"light node\") only 1 block of events can be read.","title":"Reliable Event Reading"},{"location":"dev/tutorials/network-access/transaction-finalization/","text":"Checking Transaction Finalization # On Flare and Songbird, obtaining the receipt of a submitted transaction does not guarantee that the transaction is finalized. One has to wait until the sender's account nonce (the total number of sent transactions) increases. The following function shows how to send a signed transaction and wait for its finalization. The function polls the current nonce up to 8 times before giving up, using an exponential backoff. This means that the time spent between successive polls of the nonce is increased exponentially to avoid taxing the network too much. async function sendAndFinalize ( senderAddress , signedTx , delay = 1000 ) { let oldNonce = await web3 . eth . getTransactionCount ( senderAddress ); let receipt = await web3 . eth . sendSignedTransaction ( signedTx . rawTransaction ) let backoff = 1.5 ; let maxRetries = 8 ; while (( await web3 . eth . getTransactionCount ( senderAddress )) == oldNonce ) { await new Promise (( resolve ) => { setTimeout (()=>{ resolve ()}, delay )}) maxRetries -- ; if ( maxRetries == 0 ) { throw new Error ( \"Response timeout\" ); } delay = Math . floor ( delay * backoff ); } return receipt ; }","title":"Checking Transaction Finalization"},{"location":"dev/tutorials/network-access/transaction-finalization/#checking-transaction-finalization","text":"On Flare and Songbird, obtaining the receipt of a submitted transaction does not guarantee that the transaction is finalized. One has to wait until the sender's account nonce (the total number of sent transactions) increases. The following function shows how to send a signed transaction and wait for its finalization. The function polls the current nonce up to 8 times before giving up, using an exponential backoff. This means that the time spent between successive polls of the nonce is increased exponentially to avoid taxing the network too much. async function sendAndFinalize ( senderAddress , signedTx , delay = 1000 ) { let oldNonce = await web3 . eth . getTransactionCount ( senderAddress ); let receipt = await web3 . eth . sendSignedTransaction ( signedTx . rawTransaction ) let backoff = 1.5 ; let maxRetries = 8 ; while (( await web3 . eth . getTransactionCount ( senderAddress )) == oldNonce ) { await new Promise (( resolve ) => { setTimeout (()=>{ resolve ()}, delay )}) maxRetries -- ; if ( maxRetries == 0 ) { throw new Error ( \"Response timeout\" ); } delay = Math . floor ( delay * backoff ); } return receipt ; }","title":"Checking Transaction Finalization"},{"location":"exchange/","text":"Exchange Guides # This section contains information and bits of advice for Exchanges willing to support the Flare blockchain. The first thing you should know is that: Flare is used just like Ethereum! Even though the node code is different, Flare offers the same API as Ethereum so you can integrate with it in the same way. Deploy a Flare Observer node to access the network. Use the appropriate Chain ID . Use standard Ethereum libraries like web3.js if you want. Quick Information about Flare # Website address flare.network Brand assets Google Drive Rosetta API endpoint https://flare-rosetta-api.flare.network/ Node source code github.com/flare-foundation/flare Node installation documentation docs.flare.network/infra/observation/deploying Node requirements 8 CPU, 16 GB RAM, 2 TB disk space Maximum block rate 1 block/second. Token names FLARE , SONGBIRD Tickers FLR , SGB Tokens precision 18 decimal places Supported wallets docs.flare.network/user/wallets Network configuration information, including: Flare Networks Configuration Values RPC Nodes for Connected Chains Note The $FLR and $SGB tokens are not ERC-20 tokens: they are the native currency of Flare (the Main network ) and Songbird (The Canary network ) respectively. As such, these tokens are handled the same way $ETH is handled on the Ethereum blockchain. Select one of the topics below: Architecture of an Exchange Delegating on the User's Behalf Troubleshooting Guide","title":"Exchange Guides"},{"location":"exchange/#exchange-guides","text":"This section contains information and bits of advice for Exchanges willing to support the Flare blockchain. The first thing you should know is that: Flare is used just like Ethereum! Even though the node code is different, Flare offers the same API as Ethereum so you can integrate with it in the same way. Deploy a Flare Observer node to access the network. Use the appropriate Chain ID . Use standard Ethereum libraries like web3.js if you want.","title":"Exchange Guides"},{"location":"exchange/#quick-information-about-flare","text":"Website address flare.network Brand assets Google Drive Rosetta API endpoint https://flare-rosetta-api.flare.network/ Node source code github.com/flare-foundation/flare Node installation documentation docs.flare.network/infra/observation/deploying Node requirements 8 CPU, 16 GB RAM, 2 TB disk space Maximum block rate 1 block/second. Token names FLARE , SONGBIRD Tickers FLR , SGB Tokens precision 18 decimal places Supported wallets docs.flare.network/user/wallets Network configuration information, including: Flare Networks Configuration Values RPC Nodes for Connected Chains Note The $FLR and $SGB tokens are not ERC-20 tokens: they are the native currency of Flare (the Main network ) and Songbird (The Canary network ) respectively. As such, these tokens are handled the same way $ETH is handled on the Ethereum blockchain. Select one of the topics below: Architecture of an Exchange Delegating on the User's Behalf Troubleshooting Guide","title":"Quick Information about Flare"},{"location":"exchange/architecture/","text":"Architecture of an Exchange # What follows is the suggested architecture for a centralized Exchange. Even if your Exchange does not adopt this exact design, it defines the concepts that are used throughout the other pages in this section. General Structure # The suggested architecture uses a Central Exchange wallet with multiple User reception wallets controlled by the Exchange. General structure of an Exchange. Exchange's Central Wallet (Hot) # This account contains the Exchange's funds required to perform user operations: Users' deposits are ultimately routed here, and users' withdrawals are taken from here. The private keys to this account need to be on an online machine (the Exchange server ) so this is considered a hot wallet . For security reasons, it is recommended that the hot wallet only contains enough funds to perform daily operations, whereas the bulk of the funds are kept in the cold wallet . Exchange's Central Wallet (Cold) # The private keys to this account are kept in an offline machine so it is less vulnerable to attacks. Moreover, it is recommended that this is a multi-signature account so the approval of more than one administrator is required to move funds from it. Periodically (e.g., once a day) funds are transferred from or to the hot wallet so it can continue operating while the bulk of the funds are protected in the cold wallet. Users' Reception Wallets # When users sign up with the Exchange, a reception wallet is created for them in order to perform deposits. The reception wallets are usually empty: as soon as they receive funds these are transferred to the Exchange's hot wallet . The private keys to the reception wallets always remain under the Exchange's control; these wallets are offered to users as a convenience only. Users cannot perform any operation on these wallets other than deposits. User's Wallet # This is the origin of deposits made to the Exchange and the receiver of withdrawals made from the Exchange. It can be a wallet in control of the user (the user holds its private key), a custodial wallet or another Exchange, for example. Exchange Server # This is an online server, part of the Exchange's infrastructure, that receives withdrawal requests from users and monitors the reception wallets to detect incoming deposits. It holds the private keys to the hot wallet and to all the reception wallets so it can move funds from them in response to user's requests. Caution This server must be available 24/7 so it is a clear target for malicious actors. Balances DB # This database keeps track of every user's funds, since the actual tokens from all users are pooled together in the hot and cold wallets. The Exchange server updates this DB in response to user's deposits and withdrawals. Flare Observer Node # An observer node is a regular Flare node that does not partake in consensus but is still aware of the current state of the blockchain and allows submitting transactions. It is highly recommended that Exchanges deploy their own observer nodes to access the network, instead of relying on third-party services. Read the Deploying an Observer Node guide to learn how to do this. Detecting Deposits # The Exchange server must be continuously monitoring transfers into ALL reception wallets to detect incoming deposits. Here's a summary of the process: Depositing to an Exchange. The user deposits (transfers) funds to their assigned reception wallet . The transaction is detected by the Exchange server monitoring the wallets. The server can discover a new transaction as soon as it is submitted by subscribing to the pendingTransactions event. This allows showing the transaction as \"pending\" in the UI, but there is still a chance that it is reverted. To avoid problems, the Exchange should only act on transactions appearing on blocks old enough for the chance of them being reverted to be negligible. This can be done by subscribing to the newBlockHeaders event and examining the transactions in a previous block (for example, 5 blocks behind). The code below exemplifies this process ( See the web3.js documentation for the API details): // https://web3js.readthedocs.io const Web3 = require ( 'web3' ); // Use your own node URL // https://docs.flare.network/dev/reference/coston-testnet/ const web3 = new Web3 ( \"wss://coston-api.flare.network/ext/bc/C/ws\" ); // Use your receiving wallet address const receivingAddress = \"0x947c76694491d3fD67a73688003c4d36C8780A97\" ; web3 . eth . subscribe ( \"pendingTransactions\" ) . on ( \"data\" , async ( transactionHash ) => { // New transaction hash received. // Retrieve the actual transaction. let tx = await web3 . eth . getTransaction ( transactionHash ); // If it is directed to our address... if ( tx . to === receivingAddress ) { // Mark it as pending. console . log ( \"Transaction\" , tx . hash , \"is pending\" ); } }). on ( \"error\" , console . error ); web3 . eth . subscribe ( \"newBlockHeaders\" ) . on ( \"data\" , async ( blockHeader ) => { // New block has been produced. // Retrieve a block old enough to be considered confirmed. let block = await web3 . eth . getBlock ( blockHeader . number - 5 ); // Get all its transactions. block . transactions . forEach ( async ( transactionHash ) => { // Retrieve the actual transaction. let tx = await web3 . eth . getTransaction ( transactionHash ); // If it is directed to our address... if ( tx . to === receivingAddress ) { // Mark it as confirmed. console . log ( \"Transaction\" , tx . hash , \"is confirmed in block\" , block . number ); } }); }). on ( \"error\" , console . error ); Caution Note that all transactions from a block are retrieved simultaneously and this can easily trigger a rate limit on the node. A proper implementation should avoid this by serializing requests or managing the request rate manually . The server then checks the wallet address to find which user account it belongs to, and adds the received amount to the user's balance . The server announces a transaction to the network (through the Exchange's own observer node ) to move the received funds to the hot wallet . See a JavaScript example in the Ethereum documentation . Since you will be using your own node, you can skip the Alchemy part and directly use the web3 package as in the example above. The received funds are transferred to the hot wallet when the transaction is approved by the network. The reception wallets always remain empty. Performing Withdrawals # Users must request withdrawals directly to the Exchange server through its user interface . After checking that the user has the required balance, the funds are transferred from the Exchange's hot wallet directly to the user's wallet. Here's a summary of the process: Withdrawing from an Exchange. The user requests a withdrawal to the Exchange server . The request includes some kind of user ID, the requested amount and the destination wallet's address. The server checks that the user has the required balance to perform the withdrawal. The server announces a transaction to the network (through the Exchange's own observer node ) to move the requested funds from the hot wallet to the requested destination address. See a JavaScript example in the Ethereum documentation . Since you will be using your own node, you can skip the Alchemy part and directly use the web3 package as in the example above. Caution Please make sure you sign the transaction before submitting it, as shown in the example. Unsigned transactions are ignored by the network. The requested funds are transferred to the user's wallet when the transaction is approved by the network.","title":"Architecture of an Exchange"},{"location":"exchange/architecture/#architecture-of-an-exchange","text":"What follows is the suggested architecture for a centralized Exchange. Even if your Exchange does not adopt this exact design, it defines the concepts that are used throughout the other pages in this section.","title":"Architecture of an Exchange"},{"location":"exchange/architecture/#general-structure","text":"The suggested architecture uses a Central Exchange wallet with multiple User reception wallets controlled by the Exchange. General structure of an Exchange.","title":"General Structure"},{"location":"exchange/architecture/#exchanges-central-wallet-hot","text":"This account contains the Exchange's funds required to perform user operations: Users' deposits are ultimately routed here, and users' withdrawals are taken from here. The private keys to this account need to be on an online machine (the Exchange server ) so this is considered a hot wallet . For security reasons, it is recommended that the hot wallet only contains enough funds to perform daily operations, whereas the bulk of the funds are kept in the cold wallet .","title":"Exchange's Central Wallet (Hot)"},{"location":"exchange/architecture/#exchanges-central-wallet-cold","text":"The private keys to this account are kept in an offline machine so it is less vulnerable to attacks. Moreover, it is recommended that this is a multi-signature account so the approval of more than one administrator is required to move funds from it. Periodically (e.g., once a day) funds are transferred from or to the hot wallet so it can continue operating while the bulk of the funds are protected in the cold wallet.","title":"Exchange's Central Wallet (Cold)"},{"location":"exchange/architecture/#users-reception-wallets","text":"When users sign up with the Exchange, a reception wallet is created for them in order to perform deposits. The reception wallets are usually empty: as soon as they receive funds these are transferred to the Exchange's hot wallet . The private keys to the reception wallets always remain under the Exchange's control; these wallets are offered to users as a convenience only. Users cannot perform any operation on these wallets other than deposits.","title":"Users' Reception Wallets"},{"location":"exchange/architecture/#users-wallet","text":"This is the origin of deposits made to the Exchange and the receiver of withdrawals made from the Exchange. It can be a wallet in control of the user (the user holds its private key), a custodial wallet or another Exchange, for example.","title":"User's Wallet"},{"location":"exchange/architecture/#exchange-server","text":"This is an online server, part of the Exchange's infrastructure, that receives withdrawal requests from users and monitors the reception wallets to detect incoming deposits. It holds the private keys to the hot wallet and to all the reception wallets so it can move funds from them in response to user's requests. Caution This server must be available 24/7 so it is a clear target for malicious actors.","title":"Exchange Server"},{"location":"exchange/architecture/#balances-db","text":"This database keeps track of every user's funds, since the actual tokens from all users are pooled together in the hot and cold wallets. The Exchange server updates this DB in response to user's deposits and withdrawals.","title":"Balances DB"},{"location":"exchange/architecture/#flare-observer-node","text":"An observer node is a regular Flare node that does not partake in consensus but is still aware of the current state of the blockchain and allows submitting transactions. It is highly recommended that Exchanges deploy their own observer nodes to access the network, instead of relying on third-party services. Read the Deploying an Observer Node guide to learn how to do this.","title":"Flare Observer Node"},{"location":"exchange/architecture/#detecting-deposits","text":"The Exchange server must be continuously monitoring transfers into ALL reception wallets to detect incoming deposits. Here's a summary of the process: Depositing to an Exchange. The user deposits (transfers) funds to their assigned reception wallet . The transaction is detected by the Exchange server monitoring the wallets. The server can discover a new transaction as soon as it is submitted by subscribing to the pendingTransactions event. This allows showing the transaction as \"pending\" in the UI, but there is still a chance that it is reverted. To avoid problems, the Exchange should only act on transactions appearing on blocks old enough for the chance of them being reverted to be negligible. This can be done by subscribing to the newBlockHeaders event and examining the transactions in a previous block (for example, 5 blocks behind). The code below exemplifies this process ( See the web3.js documentation for the API details): // https://web3js.readthedocs.io const Web3 = require ( 'web3' ); // Use your own node URL // https://docs.flare.network/dev/reference/coston-testnet/ const web3 = new Web3 ( \"wss://coston-api.flare.network/ext/bc/C/ws\" ); // Use your receiving wallet address const receivingAddress = \"0x947c76694491d3fD67a73688003c4d36C8780A97\" ; web3 . eth . subscribe ( \"pendingTransactions\" ) . on ( \"data\" , async ( transactionHash ) => { // New transaction hash received. // Retrieve the actual transaction. let tx = await web3 . eth . getTransaction ( transactionHash ); // If it is directed to our address... if ( tx . to === receivingAddress ) { // Mark it as pending. console . log ( \"Transaction\" , tx . hash , \"is pending\" ); } }). on ( \"error\" , console . error ); web3 . eth . subscribe ( \"newBlockHeaders\" ) . on ( \"data\" , async ( blockHeader ) => { // New block has been produced. // Retrieve a block old enough to be considered confirmed. let block = await web3 . eth . getBlock ( blockHeader . number - 5 ); // Get all its transactions. block . transactions . forEach ( async ( transactionHash ) => { // Retrieve the actual transaction. let tx = await web3 . eth . getTransaction ( transactionHash ); // If it is directed to our address... if ( tx . to === receivingAddress ) { // Mark it as confirmed. console . log ( \"Transaction\" , tx . hash , \"is confirmed in block\" , block . number ); } }); }). on ( \"error\" , console . error ); Caution Note that all transactions from a block are retrieved simultaneously and this can easily trigger a rate limit on the node. A proper implementation should avoid this by serializing requests or managing the request rate manually . The server then checks the wallet address to find which user account it belongs to, and adds the received amount to the user's balance . The server announces a transaction to the network (through the Exchange's own observer node ) to move the received funds to the hot wallet . See a JavaScript example in the Ethereum documentation . Since you will be using your own node, you can skip the Alchemy part and directly use the web3 package as in the example above. The received funds are transferred to the hot wallet when the transaction is approved by the network. The reception wallets always remain empty.","title":"Detecting Deposits"},{"location":"exchange/architecture/#performing-withdrawals","text":"Users must request withdrawals directly to the Exchange server through its user interface . After checking that the user has the required balance, the funds are transferred from the Exchange's hot wallet directly to the user's wallet. Here's a summary of the process: Withdrawing from an Exchange. The user requests a withdrawal to the Exchange server . The request includes some kind of user ID, the requested amount and the destination wallet's address. The server checks that the user has the required balance to perform the withdrawal. The server announces a transaction to the network (through the Exchange's own observer node ) to move the requested funds from the hot wallet to the requested destination address. See a JavaScript example in the Ethereum documentation . Since you will be using your own node, you can skip the Alchemy part and directly use the web3 package as in the example above. Caution Please make sure you sign the transaction before submitting it, as shown in the example. Unsigned transactions are ignored by the network. The requested funds are transferred to the user's wallet when the transaction is approved by the network.","title":"Performing Withdrawals"},{"location":"exchange/delegation/","text":"Delegating on the User's Behalf # Delegation is one of the multiple ways in which the Flare blockchain rewards participants of the ecosystem. In particular, delegation allows token holders to put their stake behind an FTSO data provider to increase its relative weight (See the FTSO page for more information). In return, each time a data provider submits useful information it shares its reward with all the token holders that delegated to it . The Delegation Guide details this process for users. However, since Exchanges keep user's tokens, only Exchanges can perform delegation. If you are an Exchange and want to offer your users the ability to earn rewards by delegation, this page summarizes the process and explains how to perform it on the user's behalf. Introduction # Flare (and Songbird) accounts can delegate any percentage they choose of their tokens to one or two FTSO data providers . This limitation means that, if your Exchange keeps all users' tokens in a single wallet (as described in the Architecture of an Exchange page), you cannot give your users the option to select the data provider they want to delegate to: The wallet containing all tokens can only delegate to one (or two) data providers . Keeping this in mind, this page explains how to delegate the users' tokens and collect the rewards. Reward Epochs As shown later, several features of the delegation mechanism are timed in Reward Epochs . On Songbird, these epochs last 7 days and start every Saturday at around 8:40AM UTC . On Flare, they last 3.5 days and start roughly every Monday at 7:00 UTC and Thursday at 19:00 UTC . Selecting a Data Provider # It is the Exchange that must select the FTSO data provider upon which to delegate, so the first step is to choose the one you are most confident to provide consistently good data (and therefore higher rewards). Anyone can become an FTSO data provider, but only the ones that had the most voting power during the previous reward epoch are available for delegation. The list of available data providers for the current reward epoch can be retrieved from the VoterWhitelister smart contract, method getFtsoWhitelistedPriceProviders . There exist a number of websites like flaremetrics.io or ftso-signal-providers that display this information in a far more convenient way. Note Data providers take a fee before sharing their rewards with their delegators. An Exchange can decide to run its own data provider to avoid paying this fee to an external entity, at the cost of having to develop a good price prediction algorithm . Keep in mind that FTSO data providing is already a very competitive business, and only the most successful algorithms are being rewarded. Lastly, delegations can be changed at any time, but they are only taken into account once per reward epoch (See more details in the FTSO page). Therefore, depending on the time it is submitted, a new delegation will not take effect until the beginning of the next reward epoch, or the one after that . Furthermore, rewards cannot be collected until another reward epoch has elapsed . Delegation Process # See Manual Delegation and Claiming in the FTSO page.","title":"Delegating on the User's Behalf"},{"location":"exchange/delegation/#delegating-on-the-users-behalf","text":"Delegation is one of the multiple ways in which the Flare blockchain rewards participants of the ecosystem. In particular, delegation allows token holders to put their stake behind an FTSO data provider to increase its relative weight (See the FTSO page for more information). In return, each time a data provider submits useful information it shares its reward with all the token holders that delegated to it . The Delegation Guide details this process for users. However, since Exchanges keep user's tokens, only Exchanges can perform delegation. If you are an Exchange and want to offer your users the ability to earn rewards by delegation, this page summarizes the process and explains how to perform it on the user's behalf.","title":"Delegating on the User's Behalf"},{"location":"exchange/delegation/#introduction","text":"Flare (and Songbird) accounts can delegate any percentage they choose of their tokens to one or two FTSO data providers . This limitation means that, if your Exchange keeps all users' tokens in a single wallet (as described in the Architecture of an Exchange page), you cannot give your users the option to select the data provider they want to delegate to: The wallet containing all tokens can only delegate to one (or two) data providers . Keeping this in mind, this page explains how to delegate the users' tokens and collect the rewards. Reward Epochs As shown later, several features of the delegation mechanism are timed in Reward Epochs . On Songbird, these epochs last 7 days and start every Saturday at around 8:40AM UTC . On Flare, they last 3.5 days and start roughly every Monday at 7:00 UTC and Thursday at 19:00 UTC .","title":"Introduction"},{"location":"exchange/delegation/#selecting-a-data-provider","text":"It is the Exchange that must select the FTSO data provider upon which to delegate, so the first step is to choose the one you are most confident to provide consistently good data (and therefore higher rewards). Anyone can become an FTSO data provider, but only the ones that had the most voting power during the previous reward epoch are available for delegation. The list of available data providers for the current reward epoch can be retrieved from the VoterWhitelister smart contract, method getFtsoWhitelistedPriceProviders . There exist a number of websites like flaremetrics.io or ftso-signal-providers that display this information in a far more convenient way. Note Data providers take a fee before sharing their rewards with their delegators. An Exchange can decide to run its own data provider to avoid paying this fee to an external entity, at the cost of having to develop a good price prediction algorithm . Keep in mind that FTSO data providing is already a very competitive business, and only the most successful algorithms are being rewarded. Lastly, delegations can be changed at any time, but they are only taken into account once per reward epoch (See more details in the FTSO page). Therefore, depending on the time it is submitted, a new delegation will not take effect until the beginning of the next reward epoch, or the one after that . Furthermore, rewards cannot be collected until another reward epoch has elapsed .","title":"Selecting a Data Provider"},{"location":"exchange/delegation/#delegation-process","text":"See Manual Delegation and Claiming in the FTSO page.","title":"Delegation Process"},{"location":"exchange/troubleshooting/","text":"Troubleshooting Guide # This page contains links to other sections answering the most common support requests received when integrating with the Flare network. Regarding Node Deployment Regarding Delegation Regarding Reward Claiming","title":"Troubleshooting Guide"},{"location":"exchange/troubleshooting/#troubleshooting-guide","text":"This page contains links to other sections answering the most common support requests received when integrating with the Flare network. Regarding Node Deployment Regarding Delegation Regarding Reward Claiming","title":"Troubleshooting Guide"},{"location":"infra/","text":"Infrastructure Guides # This section contains step-by-step guides on how to deploy the different components that make up the Flare ecosystem, and be rewarded for it. Select one of the topics below: Becoming an Attestation Provider FTSO Data Providers Observer Nodes Validator Nodes","title":"Infrastructure Guides"},{"location":"infra/#infrastructure-guides","text":"This section contains step-by-step guides on how to deploy the different components that make up the Flare ecosystem, and be rewarded for it. Select one of the topics below: Becoming an Attestation Provider FTSO Data Providers Observer Nodes Validator Nodes","title":"Infrastructure Guides"},{"location":"infra/attestation/","text":"Attestation Providers # Select one of the topics below: Operating an Attestation Provider","title":"Attestation Providers"},{"location":"infra/attestation/#attestation-providers","text":"Select one of the topics below: Operating an Attestation Provider","title":"Attestation Providers"},{"location":"infra/attestation/operating/","text":"Operating an Attestation Provider # Anyone may operate an attestation provider without any capital requirement (see the attestation-client repository for deployment information), which can readily be used as a local provider on validators that trust it. To be included in the default set , though, the same operator must run one of the top-performing FTSO data providers to prove its commitment to the network's well-being. More details will be added soon.","title":"Operating an Attestation Provider"},{"location":"infra/attestation/operating/#operating-an-attestation-provider","text":"Anyone may operate an attestation provider without any capital requirement (see the attestation-client repository for deployment information), which can readily be used as a local provider on validators that trust it. To be included in the default set , though, the same operator must run one of the top-performing FTSO data providers to prove its commitment to the network's well-being. More details will be added soon.","title":"Operating an Attestation Provider"},{"location":"infra/data/","text":"FTSO Data Providers # Select one of the topics below: Operating a Data Provider Working with Whitelists Managing the Ecosystem","title":"FTSO Data Providers"},{"location":"infra/data/#ftso-data-providers","text":"Select one of the topics below: Operating a Data Provider Working with Whitelists Managing the Ecosystem","title":"FTSO Data Providers"},{"location":"infra/data/operating/","text":"Operating a Data Provider # Introduction # Quick links NPM Kickoff package Reference implementation Data providers play an essential role in the decentralized oracle system by submitting data to on-chain contracts deployed on the Flare and Songbird networks. Operating a data provider generates rewards in $FLR , $SGB , or both for you and the people who delegate tokens to you. To maximize your rewards, your data provider needs to be constantly available and operating. If your data provider is unavailable and doesn't send data during a specific epoch, you and your delegators won't earn rewards during that epoch. If all the submission and reveal transactions are successful, the cost is approximately 3 - 4 $FLR or $SGB per day. Data providers consist of the following code components, and you can write them in any language: FTSO interface : The code that submits data to the FTSO. This code is all the necessary logic to determine which data epoch you want to submit data in and to assess when and what to submit throughout all reward epochs. Data algorithm : The code that runs the algorithm that collects and processes data. The more efficient this code is the better advantage over competing data providers you will have. Consider these tips for maximizing your advantage . The rest of this guide explains how to deploy and operate a data provider. Prerequisites # While none of the listed prerequisites are required, you will be more successful if you have them before you try to deploy an FTSO data provider: Familiarity with smart contracts, signal processing, game theory, and prompt data submission on blockchains Experience with a coding language that has a web3 library, for example: Language Web3 Library Go go-web3 Java web3.j JavaScript ethers.js , web3.js Node.js ethers.js , web3.js Python web3.py Rust rust-web3 Getting Started # To start building your data provider, use the npm kick-off package . It showcases the main contracts related to whitelisting a data provider and submitting data, and it enables you to deploy FTSO mock contracts in a local setup and submit data to those contracts. Providing data by using this package is like providing data on-chain. The following aspects work identically in the package and on-chain: Smart-contract APIs Events Timing aspects in the package work similarly but not identically to timing aspects on-chain. The package does not run the weighted-median algorithm or do calculations to distribute rewards like the FTSO smart contract deployed on-chain does. The Flare Network price provider repository shows an example of a data-provider implementation. This implementation shows the FTSO interface and a sample data algorithm. To earn rewards, you must write your own data algorithm. Interacting with Smart Contracts # Data providers interact primarily with the PriceSubmitter contract and the different FTSO contracts. Other useful contracts are: FtsoRegistry : Holds information about specific FTSOs, their symbols, indices, and addresses. To see supported tickers, query the getSupportedSymbols method. New tickers can be added by a governance vote. FtsoManager : Holds epoch and voting-related configuration data, oversees all FTSOs, and gives access to additional useful contracts, such as the Inflation and Supply contracts. VoterWhitelister : Accepts the names of data providers that list themselves to submit data. Find these contract's addresses in the Contract Addresses page. Generating Random Numbers # The data-providing process is structured as a commit-and-reveal scheme to prevent users from copying another user's submitted data. The commit-and-reveal phases are restricted to only a few minutes in duration. With each reveal the data provider also provides a random number. The random number is used first as a salt in the commit-and-reveal scheme and later during the reward calculation process. Strong random numbers are important for network security because they are the only true source of randomness on the network, and they make the commit-and-reveal scheme resilient to attacks. Random numbers below 2 128 are considered weak and unsafe, and they are rejected when they are revealed. To provide strong, cryptographically secure, random numbers with high entropy and sufficient range, consider implementing the following strategies: Use available random-number generators, such as the csprng library for Node.js applications or the web3.utils.toBN(web3.utils.randomHex(32)) function in the web3.utils package for JavaScript. Submit 256-bit random numbers. Calculating Hash for the Commit-and-Reveal Scheme # The FTSO price provider shows the complete specification for the commit-and-reveal scheme. The following code snippets show how to generate hashes in Typescript and Python using publicly available web3 libraries: Typescript Python import BN from \"bn.js\" ; import { BigNumber } from \"ethers\" ; import { ethers } from \"hardhat\" ; const MIN_RANDOM = web3 . utils . toBN ( 2 ). pow ( web3 . utils . toBN ( 128 )); function submitHash ( ftsoIndices : ( number | BN | BigNumber )[], prices : ( number | BN | BigNumber )[], random : number | BN | BigNumber , address : string ) : string { return ethers . utils . keccak256 ( web3 . eth . abi . encodeParameters ( [ \"uint256[]\" , \"uint256[]\" , \"uint256\" , \"address\" ], [ ftsoIndices , prices , random , address ])); } const ftsoIndices = [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ]; const randoms = [ MIN_RANDOM , MIN_RANDOM . addn ( 5 ), MIN_RANDOM . addn ( 1059 ), MIN_RANDOM . addn ( 10682 ), MIN_RANDOM . addn ( 159726 ) ]; const prices = [ 0 , 1 , 2 , 3 , 5 , 10 , 50 , 100 , 101 , 10 ** 5 + 1 , 10 ** 8 ]; const addrs = [ accounts [ 10 ], accounts [ 11 ], accounts [ 12 ], accounts [ 13 ]]; console . log ( `Prices: ${ prices } ` ); for ( let addr of addrs ) { console . log ( `Address: ${ addr } ` ); for ( let random of randoms ) { console . log ( `\\tRandom: ${ random } ` ) const hash = submitHash ( ftsoIndices , prices , random , addr ); console . log ( `\\t\\t ${ hash } ` ); } } from typing import List from web3 import Web3 import eth_abi minimal_random = 2 ** 128 def submit_price_hash ( ftsoIndices : List [ int ], prices : List [ int ], random : int , address : str ) -> str : assert len ( ftsoIndices ) == len ( prices ) assert list ( sorted ( ftsoIndices )) == ftsoIndices and len ( set ( ftsoIndices ) ) == len ( ftsoIndices ), \"Indices are non increasing\" return Web3 . keccak ( eth_abi . encode_abi ( [ \"uint256[]\" , \"uint256[]\" , \"uint256\" , \"address\" ], [ ftsoIndices , prices , random , address ], ) ) . hex () def test_fun ( prices : List [ int ], random : int , address = \"0xD7de703D9BBC4602242D0f3149E5fFCD30Eb3ADF\" , ) -> List [ str ]: return submit_price_hash ( list ( range ( len ( prices ))), prices , random , address ) addrs = [ \"0xD7de703D9BBC4602242D0f3149E5fFCD30Eb3ADF\" , \"0xEa960515F8b4C237730F028cBAcF0a28E7F45dE0\" , \"0x3d91185a02774C70287F6c74Dd26d13DFB58ff16\" , ] prices = [ 0 , 1 , 2 , 3 , 5 , 10 , 50 , 100 , 101 , 10 ** 5 + 1 , 10 ** 8 ] randoms = [ min_random + r for r in [ 0 , 1 , 100 , 101 , 100000000000000000000 ] ] for addr in addrs : print ( f \"Address: { addr } \" ) for rand in randoms : print ( f \" Random: { rand } \" ) print ( \" hash:\" , test_fun ( prices , rand , addr )) print () Info To see sample code for calculating submit hashes using the web3.py library, see the hasher.py gist . Retrieving Information About Rewarded Data # Listen for PriceFinalized events, which contain information about calculated median data and rewarding bounds. Each FTSO emits these events. Managing Vote Power # To check your vote power in a specific vote power block, use the votePowerOfAt method in the WNat contract. To find the vote-power block of the current reward epoch, use the getCurrentRewardEpoch method in the FtsoManager contract. Then, use the getRewardEpochVotePowerBlock method in the same contract. Vote power delegated to you belongs to only you; you cannot redelegate it. To retrieve information about delegations you receive, listen to Delegate events because this information is not contained in any on-chain structure. Retrieving Price Epoch Information # Use the getPriceEpochConfiguration method in the FtsoManager contract to retrieve: When the first price epoch started, as a UNIX timestamp. The duration of every price epoch, in seconds. The duration of every reveal phase, in seconds. These numbers allow you to calculate the price epoch number from any timestamp. The duration of price epochs is fixed and can only change through a governance decision. Submitting Data On-Chain # After you feel comfortable running the local npm package, you can start submitting your data on the real network. To run on the real network, you need to: Gain vote power : You can whitelist yourself as a data provider only if you have enough vote power. Optimize your timing : Align with the on-chain time data. Because the network is decentralized, the on-chain timestamp might skew up to 30 - 40 seconds from the real-world time. To avoid missing commit-and-reveal periods, synchronize local time with global time through the Network Time Protocol (NTP) . The later you submit, the more time you have to gather data. However, if you submit too late, you might miss the epoch window. Find the balance that works best for you. Claim rewards : Ensure you regularly claim your rewards and wrap them to earn more vote power. Each FTSO emits a PriceFinalized event that contains information about calculated median data and rewarding bounds. Set the gas limit of your commit-and-reveal transactions to around 2'500'000 gwei so that you provide enough gas. Maximizing Your Data Algorithm's Performance # Use the following tips: Run your own observer node and submit all your data through it. This will allow you to more efficiently and securely operate your data provider. Gather your data directly from each source instead of using APIs provided by data aggregators. Write your own code instead of relying entirely on third-party code. Keep an open mind, and try new strategies to find your advantage over other data providers and keep it. If your submissions are reverted, ensure the node you submit them through is healthy and has enough peers, and review the above tips.","title":"Operating a Data Provider"},{"location":"infra/data/operating/#operating-a-data-provider","text":"","title":"Operating a Data Provider"},{"location":"infra/data/operating/#introduction","text":"Quick links NPM Kickoff package Reference implementation Data providers play an essential role in the decentralized oracle system by submitting data to on-chain contracts deployed on the Flare and Songbird networks. Operating a data provider generates rewards in $FLR , $SGB , or both for you and the people who delegate tokens to you. To maximize your rewards, your data provider needs to be constantly available and operating. If your data provider is unavailable and doesn't send data during a specific epoch, you and your delegators won't earn rewards during that epoch. If all the submission and reveal transactions are successful, the cost is approximately 3 - 4 $FLR or $SGB per day. Data providers consist of the following code components, and you can write them in any language: FTSO interface : The code that submits data to the FTSO. This code is all the necessary logic to determine which data epoch you want to submit data in and to assess when and what to submit throughout all reward epochs. Data algorithm : The code that runs the algorithm that collects and processes data. The more efficient this code is the better advantage over competing data providers you will have. Consider these tips for maximizing your advantage . The rest of this guide explains how to deploy and operate a data provider.","title":"Introduction"},{"location":"infra/data/operating/#prerequisites","text":"While none of the listed prerequisites are required, you will be more successful if you have them before you try to deploy an FTSO data provider: Familiarity with smart contracts, signal processing, game theory, and prompt data submission on blockchains Experience with a coding language that has a web3 library, for example: Language Web3 Library Go go-web3 Java web3.j JavaScript ethers.js , web3.js Node.js ethers.js , web3.js Python web3.py Rust rust-web3","title":"Prerequisites"},{"location":"infra/data/operating/#getting-started","text":"To start building your data provider, use the npm kick-off package . It showcases the main contracts related to whitelisting a data provider and submitting data, and it enables you to deploy FTSO mock contracts in a local setup and submit data to those contracts. Providing data by using this package is like providing data on-chain. The following aspects work identically in the package and on-chain: Smart-contract APIs Events Timing aspects in the package work similarly but not identically to timing aspects on-chain. The package does not run the weighted-median algorithm or do calculations to distribute rewards like the FTSO smart contract deployed on-chain does. The Flare Network price provider repository shows an example of a data-provider implementation. This implementation shows the FTSO interface and a sample data algorithm. To earn rewards, you must write your own data algorithm.","title":"Getting Started"},{"location":"infra/data/operating/#interacting-with-smart-contracts","text":"Data providers interact primarily with the PriceSubmitter contract and the different FTSO contracts. Other useful contracts are: FtsoRegistry : Holds information about specific FTSOs, their symbols, indices, and addresses. To see supported tickers, query the getSupportedSymbols method. New tickers can be added by a governance vote. FtsoManager : Holds epoch and voting-related configuration data, oversees all FTSOs, and gives access to additional useful contracts, such as the Inflation and Supply contracts. VoterWhitelister : Accepts the names of data providers that list themselves to submit data. Find these contract's addresses in the Contract Addresses page.","title":"Interacting with Smart Contracts"},{"location":"infra/data/operating/#generating-random-numbers","text":"The data-providing process is structured as a commit-and-reveal scheme to prevent users from copying another user's submitted data. The commit-and-reveal phases are restricted to only a few minutes in duration. With each reveal the data provider also provides a random number. The random number is used first as a salt in the commit-and-reveal scheme and later during the reward calculation process. Strong random numbers are important for network security because they are the only true source of randomness on the network, and they make the commit-and-reveal scheme resilient to attacks. Random numbers below 2 128 are considered weak and unsafe, and they are rejected when they are revealed. To provide strong, cryptographically secure, random numbers with high entropy and sufficient range, consider implementing the following strategies: Use available random-number generators, such as the csprng library for Node.js applications or the web3.utils.toBN(web3.utils.randomHex(32)) function in the web3.utils package for JavaScript. Submit 256-bit random numbers.","title":"Generating Random Numbers"},{"location":"infra/data/operating/#calculating-hash-for-the-commit-and-reveal-scheme","text":"The FTSO price provider shows the complete specification for the commit-and-reveal scheme. The following code snippets show how to generate hashes in Typescript and Python using publicly available web3 libraries: Typescript Python import BN from \"bn.js\" ; import { BigNumber } from \"ethers\" ; import { ethers } from \"hardhat\" ; const MIN_RANDOM = web3 . utils . toBN ( 2 ). pow ( web3 . utils . toBN ( 128 )); function submitHash ( ftsoIndices : ( number | BN | BigNumber )[], prices : ( number | BN | BigNumber )[], random : number | BN | BigNumber , address : string ) : string { return ethers . utils . keccak256 ( web3 . eth . abi . encodeParameters ( [ \"uint256[]\" , \"uint256[]\" , \"uint256\" , \"address\" ], [ ftsoIndices , prices , random , address ])); } const ftsoIndices = [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ]; const randoms = [ MIN_RANDOM , MIN_RANDOM . addn ( 5 ), MIN_RANDOM . addn ( 1059 ), MIN_RANDOM . addn ( 10682 ), MIN_RANDOM . addn ( 159726 ) ]; const prices = [ 0 , 1 , 2 , 3 , 5 , 10 , 50 , 100 , 101 , 10 ** 5 + 1 , 10 ** 8 ]; const addrs = [ accounts [ 10 ], accounts [ 11 ], accounts [ 12 ], accounts [ 13 ]]; console . log ( `Prices: ${ prices } ` ); for ( let addr of addrs ) { console . log ( `Address: ${ addr } ` ); for ( let random of randoms ) { console . log ( `\\tRandom: ${ random } ` ) const hash = submitHash ( ftsoIndices , prices , random , addr ); console . log ( `\\t\\t ${ hash } ` ); } } from typing import List from web3 import Web3 import eth_abi minimal_random = 2 ** 128 def submit_price_hash ( ftsoIndices : List [ int ], prices : List [ int ], random : int , address : str ) -> str : assert len ( ftsoIndices ) == len ( prices ) assert list ( sorted ( ftsoIndices )) == ftsoIndices and len ( set ( ftsoIndices ) ) == len ( ftsoIndices ), \"Indices are non increasing\" return Web3 . keccak ( eth_abi . encode_abi ( [ \"uint256[]\" , \"uint256[]\" , \"uint256\" , \"address\" ], [ ftsoIndices , prices , random , address ], ) ) . hex () def test_fun ( prices : List [ int ], random : int , address = \"0xD7de703D9BBC4602242D0f3149E5fFCD30Eb3ADF\" , ) -> List [ str ]: return submit_price_hash ( list ( range ( len ( prices ))), prices , random , address ) addrs = [ \"0xD7de703D9BBC4602242D0f3149E5fFCD30Eb3ADF\" , \"0xEa960515F8b4C237730F028cBAcF0a28E7F45dE0\" , \"0x3d91185a02774C70287F6c74Dd26d13DFB58ff16\" , ] prices = [ 0 , 1 , 2 , 3 , 5 , 10 , 50 , 100 , 101 , 10 ** 5 + 1 , 10 ** 8 ] randoms = [ min_random + r for r in [ 0 , 1 , 100 , 101 , 100000000000000000000 ] ] for addr in addrs : print ( f \"Address: { addr } \" ) for rand in randoms : print ( f \" Random: { rand } \" ) print ( \" hash:\" , test_fun ( prices , rand , addr )) print () Info To see sample code for calculating submit hashes using the web3.py library, see the hasher.py gist .","title":"Calculating Hash for the Commit-and-Reveal Scheme"},{"location":"infra/data/operating/#retrieving-information-about-rewarded-data","text":"Listen for PriceFinalized events, which contain information about calculated median data and rewarding bounds. Each FTSO emits these events.","title":"Retrieving Information About Rewarded Data"},{"location":"infra/data/operating/#managing-vote-power","text":"To check your vote power in a specific vote power block, use the votePowerOfAt method in the WNat contract. To find the vote-power block of the current reward epoch, use the getCurrentRewardEpoch method in the FtsoManager contract. Then, use the getRewardEpochVotePowerBlock method in the same contract. Vote power delegated to you belongs to only you; you cannot redelegate it. To retrieve information about delegations you receive, listen to Delegate events because this information is not contained in any on-chain structure.","title":"Managing Vote Power"},{"location":"infra/data/operating/#retrieving-price-epoch-information","text":"Use the getPriceEpochConfiguration method in the FtsoManager contract to retrieve: When the first price epoch started, as a UNIX timestamp. The duration of every price epoch, in seconds. The duration of every reveal phase, in seconds. These numbers allow you to calculate the price epoch number from any timestamp. The duration of price epochs is fixed and can only change through a governance decision.","title":"Retrieving Price Epoch Information"},{"location":"infra/data/operating/#submitting-data-on-chain","text":"After you feel comfortable running the local npm package, you can start submitting your data on the real network. To run on the real network, you need to: Gain vote power : You can whitelist yourself as a data provider only if you have enough vote power. Optimize your timing : Align with the on-chain time data. Because the network is decentralized, the on-chain timestamp might skew up to 30 - 40 seconds from the real-world time. To avoid missing commit-and-reveal periods, synchronize local time with global time through the Network Time Protocol (NTP) . The later you submit, the more time you have to gather data. However, if you submit too late, you might miss the epoch window. Find the balance that works best for you. Claim rewards : Ensure you regularly claim your rewards and wrap them to earn more vote power. Each FTSO emits a PriceFinalized event that contains information about calculated median data and rewarding bounds. Set the gas limit of your commit-and-reveal transactions to around 2'500'000 gwei so that you provide enough gas.","title":"Submitting Data On-Chain"},{"location":"infra/data/operating/#maximizing-your-data-algorithms-performance","text":"Use the following tips: Run your own observer node and submit all your data through it. This will allow you to more efficiently and securely operate your data provider. Gather your data directly from each source instead of using APIs provided by data aggregators. Write your own code instead of relying entirely on third-party code. Keep an open mind, and try new strategies to find your advantage over other data providers and keep it. If your submissions are reverted, ensure the node you submit them through is healthy and has enough peers, and review the above tips.","title":"Maximizing Your Data Algorithm's Performance"},{"location":"infra/data/whitelisting/","text":"Working with Whitelists # Introduction # To be a data provider, you must be whitelisted . Only the top 100 data providers with the most vote power per FTSO can submit data. No minimum amount of vote power is required. Per FTSO, a data provider's vote power is based on its balance of $WFLR or $WSGB . When a data provider tries to whitelist itself, its vote power is calculated by the vote-power block of the current reward epoch. Increased vote power on a different block will not enable your address to be whitelisted. Vote power is only read and whitelists updated once per reward epoch. Reward epochs start roughly on Saturdays at 8:40AM UTC on Songbird, and on Monday at 7:00 UTC and Thursday at 19:00 UTC on Flare. Whitelisting a data provider is a fully decentralized process facilitated by the VoterWhitelister contract. To retrieve this contract, see Contract Addresses . To be added to the whitelist, submit a request for your address by using one of the functions listed in the next section. When the whitelist is not full, your address is immediately added to it. If both the list is full and your vote power is greater than the data provider with the lowest vote power, your address replaces that data provider's address on the whitelist. If the number of spaces for data providers is ever reduced by governance, addresses will be removed from the whitelist one by one, beginning with the address with the lowest vote power. Events are emitted to notify providers about changes of their status on the whitelist. Once an address is delisted, submissions will also start reverting. Requesting to be Added to the Whitelist or Relisted # Use the following methods in the VoterWhitelister contract: requestWhitelistingVoter() : Requests whitelisting for a specific asset index. requestFullVoterWhitelisting() : Requests whitelisting for all assets. Ensure you have more delegations and vote power than the data provider that has the lowest amount before the vote power block is chosen and before you submit the request to be relisted. Reading Whitelists # Each FTSO contains an array of whitelisted addresses. Use the functions in the following contracts to determine whether you are on the list and eligible to submit data: VoterWhitelister contract The getFtsoWhitelistedPriceProviders function returns a list of addresses for all data providers on the whitelist. Specify the required index, run the query, and search for your address. PriceSubmitter contract The voterWhitelistBitmap function returns a bitmap corresponding to allowed FTSO indices in big-endian format. Specify your address, run the query and examine the returned bitmap. E.g., if you were allowed to submit prices for FTSOs with indices 0, 2 and 3, the returned bitmap would be 13 ( 1101 in binary). Monitoring Your Whitelist Status # When you are added to a whitelist, the VoterWhitelisted event is emitted from the VoterWhitelister contract. When you are removed from a whitelist, the VoterRemovedFromWhitelist event is emitted, and your subsequent submissions fail. To stay aware of your whitelist status, consider listening to events that notify you about additions and removals when they happen.","title":"Working with Whitelists"},{"location":"infra/data/whitelisting/#working-with-whitelists","text":"","title":"Working with Whitelists"},{"location":"infra/data/whitelisting/#introduction","text":"To be a data provider, you must be whitelisted . Only the top 100 data providers with the most vote power per FTSO can submit data. No minimum amount of vote power is required. Per FTSO, a data provider's vote power is based on its balance of $WFLR or $WSGB . When a data provider tries to whitelist itself, its vote power is calculated by the vote-power block of the current reward epoch. Increased vote power on a different block will not enable your address to be whitelisted. Vote power is only read and whitelists updated once per reward epoch. Reward epochs start roughly on Saturdays at 8:40AM UTC on Songbird, and on Monday at 7:00 UTC and Thursday at 19:00 UTC on Flare. Whitelisting a data provider is a fully decentralized process facilitated by the VoterWhitelister contract. To retrieve this contract, see Contract Addresses . To be added to the whitelist, submit a request for your address by using one of the functions listed in the next section. When the whitelist is not full, your address is immediately added to it. If both the list is full and your vote power is greater than the data provider with the lowest vote power, your address replaces that data provider's address on the whitelist. If the number of spaces for data providers is ever reduced by governance, addresses will be removed from the whitelist one by one, beginning with the address with the lowest vote power. Events are emitted to notify providers about changes of their status on the whitelist. Once an address is delisted, submissions will also start reverting.","title":"Introduction"},{"location":"infra/data/whitelisting/#requesting-to-be-added-to-the-whitelist-or-relisted","text":"Use the following methods in the VoterWhitelister contract: requestWhitelistingVoter() : Requests whitelisting for a specific asset index. requestFullVoterWhitelisting() : Requests whitelisting for all assets. Ensure you have more delegations and vote power than the data provider that has the lowest amount before the vote power block is chosen and before you submit the request to be relisted.","title":"Requesting to be Added to the Whitelist or Relisted"},{"location":"infra/data/whitelisting/#reading-whitelists","text":"Each FTSO contains an array of whitelisted addresses. Use the functions in the following contracts to determine whether you are on the list and eligible to submit data: VoterWhitelister contract The getFtsoWhitelistedPriceProviders function returns a list of addresses for all data providers on the whitelist. Specify the required index, run the query, and search for your address. PriceSubmitter contract The voterWhitelistBitmap function returns a bitmap corresponding to allowed FTSO indices in big-endian format. Specify your address, run the query and examine the returned bitmap. E.g., if you were allowed to submit prices for FTSOs with indices 0, 2 and 3, the returned bitmap would be 13 ( 1101 in binary).","title":"Reading Whitelists"},{"location":"infra/data/whitelisting/#monitoring-your-whitelist-status","text":"When you are added to a whitelist, the VoterWhitelisted event is emitted from the VoterWhitelister contract. When you are removed from a whitelist, the VoterRemovedFromWhitelist event is emitted, and your subsequent submissions fail. To stay aware of your whitelist status, consider listening to events that notify you about additions and removals when they happen.","title":"Monitoring Your Whitelist Status"},{"location":"infra/data/managing-ecosystem/","text":"Managing the Ecosystem # The following information explains how to manage the FTSO ecosystem by participating in the FTSO Management Group, as described in FIP.02 , which was accepted on March 6, 2023. To prevent malicious behaviors that impair the FTSO ecosystem, the FTSO Management Group reports possible infractions committed by FTSO data providers and determines whether to punish them . Punished data providers are chilled , which means they are removed from the whitelist , either temporarily or permanently, depending on the quantity of infractions they have committed. Any address can request to be a member of the group, but only upstanding FTSO data providers are accepted. As a security measure to be used only when absolutely necessary, the Flare Foundation reserves the right to add and remove members on its own accord. Management Process # The group adheres to the following management process . For complete details about each step in the process, click each hyperlink. Discuss possible infractions (section 2.2.1). Submit a chill proposal (section 2.2.2). Vote on the proposal (sections 2.2.2 - 2.2.4). Depending on the outcome of the vote, the provider might be chilled (section 2.3). Discussing Infractions # When you suspect a data provider is harming the ecosystem, you must discuss the malicious behavior with other group members in the Flare FTSO Self-Policing Forum to inform the FTSO community about the problem and gather the necessary quorum for a potential vote. It facilitates the decision about whether to submit a formal proposal to chill the attacker. The discussion is not binding. Retrieving the PollingFtso contract # The PollingFtso contract handles interactions such as managing group members, submitting proposals, voting, and more. The following procedure explains how to interact directly with this contract. However, if you prefer a simpler interface, the Flare community is developing front-ends to facilitate the interactions, such as Flaremetrics . Open a block explorer for the appropriate network. Follow the Retrieval from Blockchain procedure to find and open the PollingFtso contract. The Contract Address Details page is displayed. Optional: If you need to call a method in the Write tab, click the Write Contract tab, click Connect Wallet , and complete the steps to connect your wallet. After the PollingFtso contract is open in the explorer, you can complete operations to manage members and chill proposals. Managing Group Members # To be a member you need to be an upstanding data provider , which means: You have received FTSO rewards for the last 20 reward epochs. You have not been chilled in the last 20 reward epochs. You have not been removed from the group in the last week. After the PollingFtso contract is open in the explorer, you can do the following operations, among others. Adding Members # Anyone can request to become a member of the FTSO Management Group. In the Write tab, locate the addMember method, and click Write to call it. Follow the steps to complete the transaction in your wallet. Your request to be added to the group is submitted. If you meet the conditions of an upstanding data provider , you are automatically added to the group. Removing Members # Anyone can ask for a member of the FTSO Management Group to be removed. In the Write tab, locate the removeMember method, and specify a value for this parameter: _account(address) : The address of the member you want to remove from the group. Click Write to call the removeMember method. Follow the steps to complete the transaction in your wallet. Your request to remove a member from the group is submitted. If the member no longer meets the conditions of an upstanding data provider , the member is immediately removed. Managing Chill Proposals # After the PollingFtso contract is open in the explorer, you can do the following operations, among others. Submitting a Proposal # If you are a member of the FTSO Management Group or a member's proxy , you can submit a chill proposal. In the Write tab, locate the propose method, and specify values for these parameters: _description(string) : A free-form description of the problem to be voted on. It does not have a fixed structure, but it must contain at least the URL for the discussion in the forum (section 2.2.2.d) value(FLR or SGB) : The cost to call the propose method to submit the proposal, which you must specify as the value. The current cost is 100 $FLR or $SGB . Because this cost can fluctuate, retrieve the current cost by locating the proposalFeeValueWei method in the Read tab, which automatically displays the cost. Click Write to call the propose method. Follow the steps to complete the transaction in your wallet. Your proposal is submitted, and the proposalId is returned. Post the proposalId in the discussion thread so that members of the group can use it to vote on the proposal. Voting on a Proposal # You can vote on a proposal when the following conditions are met: You are a member of the FTSO Management Group or a member's proxy . The proposal is active. To vote on a proposal: In the Write tab, locate the castVote method, and specify values for these parameters: _proposalId(uint256) : The proposal ID posted by the proponent in the discussion thread. This ID was obtained by proponent when the proposal was submitted. If you specify nonexistent IDs or IDs for proposals that have completed, the transaction reverts, and the explorer returns empty results. _support(uint8) : Specify one of the following values. 0 : Vote against the proposal. 1 : Vote in favor of the proposal. If you specify values other than 0 or 1 , the transaction reverts. Click Write to call the castVote method. Follow the steps to complete the transaction in your wallet. Your vote is cast. Setting a Proxy Voter # If you are a member of the group, you can declare one address that can manage proposals and vote on them on your behalf. This address is known as your proxy. Your proxy can submit proposals and vote on them. In the Write tab, locate the setProxyVoter method, and specify the value for this parameter: _proxyVoter(address) : The address you want to declare as your proxy. Click Write to call the setProxyVoter method. Follow the steps to complete the transaction in your wallet. The specified address is set as your proxy voter. Removing a Proxy Voter # In the Write tab, locate the setProxyVoter method, and specify the value for this parameter: _proxyVoter(address) : Specify the zero address 0x0000000000000000000000000000000000000000 . Click Write to call the setProxyVoter method. Follow the steps to complete the transaction in your wallet. The previously specified proxy address is revoked. Determining Your Proxy Voter's Address # In the Read tab, locate the providerToProxy method, and specify the value for this parameter: (address) : The address that declared the proxy. Click Query to call the providerToProxy method. The address of the proxy voter is returned. Retrieving the Last Proposal # In the Read tab, locate the getLastProposal method. The number of the most recent proposal and its description are displayed. Retrieving a List of Group Members # In the Read tab, locate the getManagementGroupMembers method. A list of the addresses of members is displayed. Retrieving a Proposal Description # In the Read tab, locate the getProposalDescription method, and specify the value for this parameter: proposalId(uint256) : The ID of the proposal whose description you want. If you don't know the proposal ID, refer to the proposal's discussion thread. Click Query to call the getProposalDescription method. The description of the specified proposal ID is returned. If you specified a nonexistent ID for the proposalId parameter, an empty string is returned. Retrieving a Vote Count # In the Read tab, locate the getProposalVotes method, and specify the value for this parameter: proposalId(uint256) : The ID of the proposal whose vote count you want. Proposal IDs are posted in its corresponding discussion thread. Click Query to call the getProposalVotes method. The number of votes in favor of the proposal and the number of votes against it are returned. If you specified a nonexistent ID for the proposalId parameter, 0 is returned as the number of votes for the proposal and as the number of votes against it. Determining a Member's Vote Status # In the Read tab, locate the hasVoted method, and specify the value for these parameters: proposalId(uint256) : The ID of the proposal for which you want to determine a member's vote status. voter(address) : The address of the member. If you do not know the address, refer to the list of addresses for all group members . Click Query to call the hasVoted method. A boolean value indicating whether the member has voted is returned. If you specified a nonexistent ID for the proposalId parameter, false is returned. Related Guides # Exploring Collusion Monitoring Price History","title":"Managing the Ecosystem"},{"location":"infra/data/managing-ecosystem/#managing-the-ecosystem","text":"The following information explains how to manage the FTSO ecosystem by participating in the FTSO Management Group, as described in FIP.02 , which was accepted on March 6, 2023. To prevent malicious behaviors that impair the FTSO ecosystem, the FTSO Management Group reports possible infractions committed by FTSO data providers and determines whether to punish them . Punished data providers are chilled , which means they are removed from the whitelist , either temporarily or permanently, depending on the quantity of infractions they have committed. Any address can request to be a member of the group, but only upstanding FTSO data providers are accepted. As a security measure to be used only when absolutely necessary, the Flare Foundation reserves the right to add and remove members on its own accord.","title":"Managing the Ecosystem"},{"location":"infra/data/managing-ecosystem/#management-process","text":"The group adheres to the following management process . For complete details about each step in the process, click each hyperlink. Discuss possible infractions (section 2.2.1). Submit a chill proposal (section 2.2.2). Vote on the proposal (sections 2.2.2 - 2.2.4). Depending on the outcome of the vote, the provider might be chilled (section 2.3).","title":"Management Process"},{"location":"infra/data/managing-ecosystem/#discussing-infractions","text":"When you suspect a data provider is harming the ecosystem, you must discuss the malicious behavior with other group members in the Flare FTSO Self-Policing Forum to inform the FTSO community about the problem and gather the necessary quorum for a potential vote. It facilitates the decision about whether to submit a formal proposal to chill the attacker. The discussion is not binding.","title":"Discussing Infractions"},{"location":"infra/data/managing-ecosystem/#retrieving-the-pollingftso-contract","text":"The PollingFtso contract handles interactions such as managing group members, submitting proposals, voting, and more. The following procedure explains how to interact directly with this contract. However, if you prefer a simpler interface, the Flare community is developing front-ends to facilitate the interactions, such as Flaremetrics . Open a block explorer for the appropriate network. Follow the Retrieval from Blockchain procedure to find and open the PollingFtso contract. The Contract Address Details page is displayed. Optional: If you need to call a method in the Write tab, click the Write Contract tab, click Connect Wallet , and complete the steps to connect your wallet. After the PollingFtso contract is open in the explorer, you can complete operations to manage members and chill proposals.","title":"Retrieving the PollingFtso contract"},{"location":"infra/data/managing-ecosystem/#managing-group-members","text":"To be a member you need to be an upstanding data provider , which means: You have received FTSO rewards for the last 20 reward epochs. You have not been chilled in the last 20 reward epochs. You have not been removed from the group in the last week. After the PollingFtso contract is open in the explorer, you can do the following operations, among others.","title":"Managing Group Members"},{"location":"infra/data/managing-ecosystem/#adding-members","text":"Anyone can request to become a member of the FTSO Management Group. In the Write tab, locate the addMember method, and click Write to call it. Follow the steps to complete the transaction in your wallet. Your request to be added to the group is submitted. If you meet the conditions of an upstanding data provider , you are automatically added to the group.","title":"Adding Members"},{"location":"infra/data/managing-ecosystem/#removing-members","text":"Anyone can ask for a member of the FTSO Management Group to be removed. In the Write tab, locate the removeMember method, and specify a value for this parameter: _account(address) : The address of the member you want to remove from the group. Click Write to call the removeMember method. Follow the steps to complete the transaction in your wallet. Your request to remove a member from the group is submitted. If the member no longer meets the conditions of an upstanding data provider , the member is immediately removed.","title":"Removing Members"},{"location":"infra/data/managing-ecosystem/#managing-chill-proposals","text":"After the PollingFtso contract is open in the explorer, you can do the following operations, among others.","title":"Managing Chill Proposals"},{"location":"infra/data/managing-ecosystem/#submitting-a-proposal","text":"If you are a member of the FTSO Management Group or a member's proxy , you can submit a chill proposal. In the Write tab, locate the propose method, and specify values for these parameters: _description(string) : A free-form description of the problem to be voted on. It does not have a fixed structure, but it must contain at least the URL for the discussion in the forum (section 2.2.2.d) value(FLR or SGB) : The cost to call the propose method to submit the proposal, which you must specify as the value. The current cost is 100 $FLR or $SGB . Because this cost can fluctuate, retrieve the current cost by locating the proposalFeeValueWei method in the Read tab, which automatically displays the cost. Click Write to call the propose method. Follow the steps to complete the transaction in your wallet. Your proposal is submitted, and the proposalId is returned. Post the proposalId in the discussion thread so that members of the group can use it to vote on the proposal.","title":"Submitting a Proposal"},{"location":"infra/data/managing-ecosystem/#voting-on-a-proposal","text":"You can vote on a proposal when the following conditions are met: You are a member of the FTSO Management Group or a member's proxy . The proposal is active. To vote on a proposal: In the Write tab, locate the castVote method, and specify values for these parameters: _proposalId(uint256) : The proposal ID posted by the proponent in the discussion thread. This ID was obtained by proponent when the proposal was submitted. If you specify nonexistent IDs or IDs for proposals that have completed, the transaction reverts, and the explorer returns empty results. _support(uint8) : Specify one of the following values. 0 : Vote against the proposal. 1 : Vote in favor of the proposal. If you specify values other than 0 or 1 , the transaction reverts. Click Write to call the castVote method. Follow the steps to complete the transaction in your wallet. Your vote is cast.","title":"Voting on a Proposal"},{"location":"infra/data/managing-ecosystem/#setting-a-proxy-voter","text":"If you are a member of the group, you can declare one address that can manage proposals and vote on them on your behalf. This address is known as your proxy. Your proxy can submit proposals and vote on them. In the Write tab, locate the setProxyVoter method, and specify the value for this parameter: _proxyVoter(address) : The address you want to declare as your proxy. Click Write to call the setProxyVoter method. Follow the steps to complete the transaction in your wallet. The specified address is set as your proxy voter.","title":"Setting a Proxy Voter"},{"location":"infra/data/managing-ecosystem/#removing-a-proxy-voter","text":"In the Write tab, locate the setProxyVoter method, and specify the value for this parameter: _proxyVoter(address) : Specify the zero address 0x0000000000000000000000000000000000000000 . Click Write to call the setProxyVoter method. Follow the steps to complete the transaction in your wallet. The previously specified proxy address is revoked.","title":"Removing a Proxy Voter"},{"location":"infra/data/managing-ecosystem/#determining-your-proxy-voters-address","text":"In the Read tab, locate the providerToProxy method, and specify the value for this parameter: (address) : The address that declared the proxy. Click Query to call the providerToProxy method. The address of the proxy voter is returned.","title":"Determining Your Proxy Voter's Address"},{"location":"infra/data/managing-ecosystem/#retrieving-the-last-proposal","text":"In the Read tab, locate the getLastProposal method. The number of the most recent proposal and its description are displayed.","title":"Retrieving the Last Proposal"},{"location":"infra/data/managing-ecosystem/#retrieving-a-list-of-group-members","text":"In the Read tab, locate the getManagementGroupMembers method. A list of the addresses of members is displayed.","title":"Retrieving a List of Group Members"},{"location":"infra/data/managing-ecosystem/#retrieving-a-proposal-description","text":"In the Read tab, locate the getProposalDescription method, and specify the value for this parameter: proposalId(uint256) : The ID of the proposal whose description you want. If you don't know the proposal ID, refer to the proposal's discussion thread. Click Query to call the getProposalDescription method. The description of the specified proposal ID is returned. If you specified a nonexistent ID for the proposalId parameter, an empty string is returned.","title":"Retrieving a Proposal Description"},{"location":"infra/data/managing-ecosystem/#retrieving-a-vote-count","text":"In the Read tab, locate the getProposalVotes method, and specify the value for this parameter: proposalId(uint256) : The ID of the proposal whose vote count you want. Proposal IDs are posted in its corresponding discussion thread. Click Query to call the getProposalVotes method. The number of votes in favor of the proposal and the number of votes against it are returned. If you specified a nonexistent ID for the proposalId parameter, 0 is returned as the number of votes for the proposal and as the number of votes against it.","title":"Retrieving a Vote Count"},{"location":"infra/data/managing-ecosystem/#determining-a-members-vote-status","text":"In the Read tab, locate the hasVoted method, and specify the value for these parameters: proposalId(uint256) : The ID of the proposal for which you want to determine a member's vote status. voter(address) : The address of the member. If you do not know the address, refer to the list of addresses for all group members . Click Query to call the hasVoted method. A boolean value indicating whether the member has voted is returned. If you specified a nonexistent ID for the proposalId parameter, false is returned.","title":"Determining a Member's Vote Status"},{"location":"infra/data/managing-ecosystem/#related-guides","text":"Exploring Collusion Monitoring Price History","title":"Related Guides"},{"location":"infra/data/managing-ecosystem/exploring-collusion/","text":"Exploring Collusion # Members of the FTSO Management Group are responsible for monitoring the FTSO ecosystem for malicious behaviors, such as collusion. Collusion in the FTSO ecosystem is a problem for several reasons: It artificially raises the power of the colluding data providers, which endangers the quality of the FTSO data. It is specifically forbidden by FIP.02 . In a healthy ecosystem, submissions from data providers are chasing the median, and they are close to the reward band. Collusion is possibly evident in this environment when multiple data providers submit similar data that is relatively distant from the median. To explore possible collusion between data providers in the ecosystem, use the collusion tool in the Flare FTSO Monitor . Collusion Tool Dashboard # The following image shows the dashboard of the collusion tool : FTSO Monitor Collusion Tool. The elements of the collusion tool are: Threshold : Scans for the percentage of similarity that you want to see between the data providers for which you search. Details about how to specify the percentage are in step 2 of the procedure to identify data providers . Search : Locates data providers within the FTSO ecosystem. Details about how to specify names of data providers are in step 3 of the procedure to identify data providers . End time : Sets the date you want to view. Cluster map of data providers : Illustrates data providers that might be colluding by linking them with weighted connectors. The map is generated based on the data submitted during 00:00 - 24:00 UTC on the date you select in the End time field. Heavier weights suggest more potential for collusion than lighter weights. For example, the following image of part of the cluster map shows a pair of data providers weighted heavily enough to suggest a case of collusion. Heavily Weighted Data Providers. Identifying Colluding Data Providers # For exploratory purposes only Use this tool only for exploratory purposes. Do not exclusively rely on this tool to infer that collusion has occurred. Open the collusion tool in the FTSO Monitor . The collusion tool dashboard is displayed. In the Threshold field, specify the percentage of similarity you want to see. For example, if you specify .98 , 98% of the weakest similarities are omitted, and the strongest 2% of the similarities are displayed. Use one of the following search methods: If you know the names of the data providers you want to compare, specify them in a comma-separated series in the Search field. The field is case-sensitive and accepts partial names of providers. For example, if you specify FTSO , the tool selects all providers that have FTSO in their names, regardless of case. In the cluster map, locate data provider nodes linked with heavily weighted connectors by zooming in. Zoom in and out by using the appropriate method on your device, such as spinning a mouse wheel. After you zoom in, you can center a node or a group of them on the screen by clicking the map and dragging it. Select at least two providers you want to compare by pressing and holding the Control key while you click each data provider node. Optional: Explore a previous date by changing the End time option to a date other than the current date. Click Compare . As shown in the following image, the Prices tab opens, displaying a line graph that shows the data submitted by each specified data provider during the most recent 30-minute interval on the date you selected in the End time field. Price History. Comparing Price History # In the price history , analyze the data for multiple providers consistently submitting prices that are distant from the median but near each other. In your analysis, consider anomalous situations, such as an exchange going offline, a vast region of the internet becoming disconnected, or a stablecoin depegging from its reference asset. In these situations, submitted data from providers is expected to be wildly different. If multiple providers still manage to submit similar data, carefully examine them. Although a depegged stablecoin should not affect FTSO prices, because price pairs use USD instead of a stablecoin, prices have been affected in the past, and the evidence is noticeable in the line graph. This situation reveals data providers who were using a stablecoin instead of USD in their submissions. As shown in the image in each tab below, additional details about the data providers and the submitted data are provided beneath the price-history dashboard. The details on Songbird are different from the details on Flare because of the secondary reward band implemented by STP.02 . Use these details to more deeply explore the similarities between the data submitted by the providers you selected. Flare Songbird Details About Specified Data Providers. Address : The hexadecimal identifier of the data provider. The circle beside the address corresponds with the address in the graph. The correspondence between the circle and the address works for up to five addresses. Number of cases : The quantity of data samples during the specified interval. High : The percentage of samples above the reward band. Low : The percentage of samples below the reward band. Out : The total percentage of high combined with low. Border : The percentage of samples on the border of the reward band. Inner : The percentage of samples inside the reward band. Expected : The success rate of the data. The value is represented as a percentage and calculated by the formula Inner + 0.5(Border) . In the following image, the percentage of samples are color-coded in the following ways: IQR reward band : Interquartile range percentages are blue. Pct reward band : Percentage range percentages are red. Details About Specified Data Providers. Address : The hexadecimal identifier of the data provider. The circle beside the address corresponds with the address in the graph. The correspondence between the circle and the address works for up to five addresses. Number of cases : The quantity of data samples during the specified interval. High : The percentage of samples above the reward bands. Low : The percentage of samples below the reward bands. Out : The total percentage of high combined with low. Border : The percentage of samples on the borders of the reward bands. Inner : The percentage of samples inside the reward bands. Expected : The success rate of the data. The value is represented as a percentage and calculated by the formula Inner + 0.5(Border) . The Similarity Metric # This section describes the similarity metric used to obtain the cluster map . To estimate collusion, the similarity metric assigns a value of similarity between data submitted by pairs of data providers. As previously stated, collusion between data providers is evident when they submit similar data that is relatively distant from the median because similar algorithms will make similar mistakes. For data providers DP1 and DP2 during a given range of price epoch for comparison, the prices P1 and P2 submitted for each cryptocurrency pair and epoch are checked. If both prices are available alongside the median price M , the contribution to the collusion metric is calculated in the following way: diff = abs ( P2 - P1 ) diff1 = abs ( P1 - M ) diff2 = abs ( P2 - M ) relativePriceDiff = max ( diff / M , threshold ) relativeOffset = scale ( min ( diff1 , diff2 ) / M ) contribution = relativeOffset / relativePriceDiff where threshold = 0.00000001 scale ( x ) = 20000 x + 1 , if x < 0.0001 and 3 otherwise The threshold is selected to avoid a division by zero when the two providers submit exactly the same data, and scale displays the data more clearly.","title":"Exploring Collusion"},{"location":"infra/data/managing-ecosystem/exploring-collusion/#exploring-collusion","text":"Members of the FTSO Management Group are responsible for monitoring the FTSO ecosystem for malicious behaviors, such as collusion. Collusion in the FTSO ecosystem is a problem for several reasons: It artificially raises the power of the colluding data providers, which endangers the quality of the FTSO data. It is specifically forbidden by FIP.02 . In a healthy ecosystem, submissions from data providers are chasing the median, and they are close to the reward band. Collusion is possibly evident in this environment when multiple data providers submit similar data that is relatively distant from the median. To explore possible collusion between data providers in the ecosystem, use the collusion tool in the Flare FTSO Monitor .","title":"Exploring Collusion"},{"location":"infra/data/managing-ecosystem/exploring-collusion/#collusion-tool-dashboard","text":"The following image shows the dashboard of the collusion tool : FTSO Monitor Collusion Tool. The elements of the collusion tool are: Threshold : Scans for the percentage of similarity that you want to see between the data providers for which you search. Details about how to specify the percentage are in step 2 of the procedure to identify data providers . Search : Locates data providers within the FTSO ecosystem. Details about how to specify names of data providers are in step 3 of the procedure to identify data providers . End time : Sets the date you want to view. Cluster map of data providers : Illustrates data providers that might be colluding by linking them with weighted connectors. The map is generated based on the data submitted during 00:00 - 24:00 UTC on the date you select in the End time field. Heavier weights suggest more potential for collusion than lighter weights. For example, the following image of part of the cluster map shows a pair of data providers weighted heavily enough to suggest a case of collusion. Heavily Weighted Data Providers.","title":"Collusion Tool Dashboard"},{"location":"infra/data/managing-ecosystem/exploring-collusion/#identifying-colluding-data-providers","text":"For exploratory purposes only Use this tool only for exploratory purposes. Do not exclusively rely on this tool to infer that collusion has occurred. Open the collusion tool in the FTSO Monitor . The collusion tool dashboard is displayed. In the Threshold field, specify the percentage of similarity you want to see. For example, if you specify .98 , 98% of the weakest similarities are omitted, and the strongest 2% of the similarities are displayed. Use one of the following search methods: If you know the names of the data providers you want to compare, specify them in a comma-separated series in the Search field. The field is case-sensitive and accepts partial names of providers. For example, if you specify FTSO , the tool selects all providers that have FTSO in their names, regardless of case. In the cluster map, locate data provider nodes linked with heavily weighted connectors by zooming in. Zoom in and out by using the appropriate method on your device, such as spinning a mouse wheel. After you zoom in, you can center a node or a group of them on the screen by clicking the map and dragging it. Select at least two providers you want to compare by pressing and holding the Control key while you click each data provider node. Optional: Explore a previous date by changing the End time option to a date other than the current date. Click Compare . As shown in the following image, the Prices tab opens, displaying a line graph that shows the data submitted by each specified data provider during the most recent 30-minute interval on the date you selected in the End time field. Price History.","title":"Identifying Colluding Data Providers"},{"location":"infra/data/managing-ecosystem/exploring-collusion/#comparing-price-history","text":"In the price history , analyze the data for multiple providers consistently submitting prices that are distant from the median but near each other. In your analysis, consider anomalous situations, such as an exchange going offline, a vast region of the internet becoming disconnected, or a stablecoin depegging from its reference asset. In these situations, submitted data from providers is expected to be wildly different. If multiple providers still manage to submit similar data, carefully examine them. Although a depegged stablecoin should not affect FTSO prices, because price pairs use USD instead of a stablecoin, prices have been affected in the past, and the evidence is noticeable in the line graph. This situation reveals data providers who were using a stablecoin instead of USD in their submissions. As shown in the image in each tab below, additional details about the data providers and the submitted data are provided beneath the price-history dashboard. The details on Songbird are different from the details on Flare because of the secondary reward band implemented by STP.02 . Use these details to more deeply explore the similarities between the data submitted by the providers you selected. Flare Songbird Details About Specified Data Providers. Address : The hexadecimal identifier of the data provider. The circle beside the address corresponds with the address in the graph. The correspondence between the circle and the address works for up to five addresses. Number of cases : The quantity of data samples during the specified interval. High : The percentage of samples above the reward band. Low : The percentage of samples below the reward band. Out : The total percentage of high combined with low. Border : The percentage of samples on the border of the reward band. Inner : The percentage of samples inside the reward band. Expected : The success rate of the data. The value is represented as a percentage and calculated by the formula Inner + 0.5(Border) . In the following image, the percentage of samples are color-coded in the following ways: IQR reward band : Interquartile range percentages are blue. Pct reward band : Percentage range percentages are red. Details About Specified Data Providers. Address : The hexadecimal identifier of the data provider. The circle beside the address corresponds with the address in the graph. The correspondence between the circle and the address works for up to five addresses. Number of cases : The quantity of data samples during the specified interval. High : The percentage of samples above the reward bands. Low : The percentage of samples below the reward bands. Out : The total percentage of high combined with low. Border : The percentage of samples on the borders of the reward bands. Inner : The percentage of samples inside the reward bands. Expected : The success rate of the data. The value is represented as a percentage and calculated by the formula Inner + 0.5(Border) .","title":"Comparing Price History"},{"location":"infra/data/managing-ecosystem/exploring-collusion/#the-similarity-metric","text":"This section describes the similarity metric used to obtain the cluster map . To estimate collusion, the similarity metric assigns a value of similarity between data submitted by pairs of data providers. As previously stated, collusion between data providers is evident when they submit similar data that is relatively distant from the median because similar algorithms will make similar mistakes. For data providers DP1 and DP2 during a given range of price epoch for comparison, the prices P1 and P2 submitted for each cryptocurrency pair and epoch are checked. If both prices are available alongside the median price M , the contribution to the collusion metric is calculated in the following way: diff = abs ( P2 - P1 ) diff1 = abs ( P1 - M ) diff2 = abs ( P2 - M ) relativePriceDiff = max ( diff / M , threshold ) relativeOffset = scale ( min ( diff1 , diff2 ) / M ) contribution = relativeOffset / relativePriceDiff where threshold = 0.00000001 scale ( x ) = 20000 x + 1 , if x < 0.0001 and 3 otherwise The threshold is selected to avoid a division by zero when the two providers submit exactly the same data, and scale displays the data more clearly.","title":"The Similarity Metric"},{"location":"infra/data/managing-ecosystem/monitoring-price-history/","text":"Monitoring Price History # Work in Progress Some functions for monitoring price history are works in progress. In the FTSO system, price histories show the evolution of submitted and calculated prices over time on a line graph. The data plotted on the line graph enables you to study in detail the relationship between suspicious data providers, which you can first observe by using the collusion tool . The data on the graph includes: Median prices. Quantity of votes. This information helps you locate outage periods in which a large-enough number of providers failed to submit data to impact the graph. Reward bands. This information indicates the dispersion of the submitted values. Additionally, if the price history is displayed because you selected data providers by using the collusion tool , the graph includes submissions by those providers, enabling you to see: Whether a submission is inside or outside of the reward band and by how much. Whether multiple providers were chasing each other instead of the median, which could imply collusion. Price-History Dashboard # Price-History Dashboard. The elements of the dashboard are: Navigation Bar : The main functions of the Flare FTSO Monitor. Network Selector : Toggles between FTSO Monitors for other Flare networks. Line Graph : Displays the price history and the number of votes when you are not comparing specific data providers. Cryptocurrency Selector : Toggles between supported cryptocurrencies. Exchange Selector : Feature is currently not enabled. Date and Time Selector : Isolates the price history for the date and time you specify. View Selector : Toggles to relative view, which typically makes reward bands on the graph more apparent. Time Frame Slider : Changes the time frame displayed in the graph based on selections you make by moving the slider. Interval Selector : Toggles the interval during which you want to view price history. The default settings are: Cryptocurrency symbol : XRP Time frame : 30m End time : The current date and time when you opened the Prices tab. Comparing Price History # Open the price-history dashboard in the FTSO Monitor . The price-history dashboard, which is based on the default settings, is displayed. Optional: If you need to monitor the FTSO ecosystem on a different network, click the Network Selector , as shown in the price-history dashboard , and select a different network. For more specific comparisons, change the default settings by using the various elements in the dashboard to further express the data: Toggle the currencies and interval. Adjust the date and time. Add or remove from the graph some data, such as an address, a currency's median price, the voter count, and the award area. If the price-history dashboard opened because you compared data providers using the collusion tool, the list of data providers is also displayed below the dashboard.","title":"Monitoring Price History"},{"location":"infra/data/managing-ecosystem/monitoring-price-history/#monitoring-price-history","text":"Work in Progress Some functions for monitoring price history are works in progress. In the FTSO system, price histories show the evolution of submitted and calculated prices over time on a line graph. The data plotted on the line graph enables you to study in detail the relationship between suspicious data providers, which you can first observe by using the collusion tool . The data on the graph includes: Median prices. Quantity of votes. This information helps you locate outage periods in which a large-enough number of providers failed to submit data to impact the graph. Reward bands. This information indicates the dispersion of the submitted values. Additionally, if the price history is displayed because you selected data providers by using the collusion tool , the graph includes submissions by those providers, enabling you to see: Whether a submission is inside or outside of the reward band and by how much. Whether multiple providers were chasing each other instead of the median, which could imply collusion.","title":"Monitoring Price History"},{"location":"infra/data/managing-ecosystem/monitoring-price-history/#price-history-dashboard","text":"Price-History Dashboard. The elements of the dashboard are: Navigation Bar : The main functions of the Flare FTSO Monitor. Network Selector : Toggles between FTSO Monitors for other Flare networks. Line Graph : Displays the price history and the number of votes when you are not comparing specific data providers. Cryptocurrency Selector : Toggles between supported cryptocurrencies. Exchange Selector : Feature is currently not enabled. Date and Time Selector : Isolates the price history for the date and time you specify. View Selector : Toggles to relative view, which typically makes reward bands on the graph more apparent. Time Frame Slider : Changes the time frame displayed in the graph based on selections you make by moving the slider. Interval Selector : Toggles the interval during which you want to view price history. The default settings are: Cryptocurrency symbol : XRP Time frame : 30m End time : The current date and time when you opened the Prices tab.","title":"Price-History Dashboard"},{"location":"infra/data/managing-ecosystem/monitoring-price-history/#comparing-price-history","text":"Open the price-history dashboard in the FTSO Monitor . The price-history dashboard, which is based on the default settings, is displayed. Optional: If you need to monitor the FTSO ecosystem on a different network, click the Network Selector , as shown in the price-history dashboard , and select a different network. For more specific comparisons, change the default settings by using the various elements in the dashboard to further express the data: Toggle the currencies and interval. Adjust the date and time. Add or remove from the graph some data, such as an address, a currency's median price, the voter count, and the award area. If the price-history dashboard opened because you compared data providers using the collusion tool, the list of data providers is also displayed below the dashboard.","title":"Comparing Price History"},{"location":"infra/observation/","text":"Observer Nodes # Select one of the topics below: Deploying an Observer Node FAQ","title":"Observer Nodes"},{"location":"infra/observation/#observer-nodes","text":"Select one of the topics below: Deploying an Observer Node FAQ","title":"Observer Nodes"},{"location":"infra/observation/deploying/","text":"Deploying an Observer Node # Introduction # Observer nodes enable anyone to observe the network and submit transactions. Unlike validator nodes , which provide state consensus and add blocks, observer nodes remain outside the network and have no effect on consensus or blocks. Running an observer node is optional. However, submitting transactions through your own node offers a number of benefits: Transactions are sent directly to the network instead of through a third party, removing a potential security risk. Public nodes are usually rate-limited (the amount of requests they accept per second is restricted). Your own node does not have such restriction. The time savings described above allow FTSO data providers to submit their data a few seconds later, thus having more time to gather data before submitting. This guide explains how to deploy your own observer node so you can reap these benefits. Prerequisites # This guide contains different instructions depending on which Flare network you want to deploy to, so make sure you are aware of the available networks . Flare Songbird Coston Coston 2 Hardware Software CPU cores 8 Operating System Ubuntu (18.04 or 20.04) or macOS (>= 10.15 Catalina) RAM 32 GB Dependencies Go (>= 1.18.5) Disk space 1 TB SSD gcc Disk growth 2.5 TB/year g++ jq Hardware Software CPU cores 8 Operating System Ubuntu (18.04 or 20.04) or macOS (>= 10.15 Catalina) RAM 32 GB Dependencies Go (>= 1.16.8) Disk space 3.5 TB SSD gcc Disk growth 2.5 TB/year g++ jq Hardware Software CPU cores 4 Operating System Ubuntu (18.04 or 20.04) or macOS (>= 10.15 Catalina) RAM 16 GB Dependencies Go (>= 1.16.8) Disk space 500 GB SSD gcc Disk growth 250 GB/year g++ jq Hardware Software CPU cores 4 Operating System Ubuntu (18.04 or 20.04) or macOS (>= 10.15 Catalina) RAM 16 GB Dependencies Go (>= 1.18.5) Disk space 500 GB SSD gcc Disk growth 250 GB/year g++ jq Plus a reliable IPv4 or IPv6 network connection, with an open public port. Keep in mind that enabling pruning as described below can reduce the required disk space by as much as 60%. Guide # 1. Installation # Flare & Coston 2 Songbird & Coston Clone the go-flare repository and run the build.sh script: git clone https://github.com/flare-foundation/go-flare.git cd go-flare/avalanchego ./scripts/build.sh The resulting executable will be build/avalanchego . Note You can verify the installation by running: go test $( go list ./... | grep -v /tests/ ) # avalanchego unit tests cd ../coreth go test ./... # coreth unit tests cd ../avalanchego Clone the go-songbird repository and run the build.sh script: git clone https://github.com/flare-foundation/go-songbird.git cd go-songbird/avalanchego ./scripts/build.sh The resulting executable will be build/flare . Note You can verify the installation by running: go test $( go list ./... | grep -v /tests/ ) # avalanchego unit tests cd coreth go test ./... # coreth unit tests cd .. 2. Songbird Node Whitelisting # While Songbird network is being tested, all nodes wanting to peer with it (including observer nodes) need to have their IP address whitelisted . To do this, please contact Tom T. over Discord ( Tom T#7603 ), Telegram ( @TampaBay7 ) or email ( tom@flare.network ) and request to be whitelisted. Checking the status of your Songbird whitelisting request curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeIP\" }' \\ -H 'content-type:application/json;' \\ https://songbird.flare.network/ext/info If your IP address is whitelisted, this command returns a JSON response. Otherwise you will get a 403 error (\"Forbidden\"). Please note that whitelisting is not needed on the Flare network or any of the Coston networks . 3. Run the Node # This is the minimum command to quickly get your node up and running. To understand each parameter read the following step before launching the node. Flare Songbird Coston Coston 2 ./build/avalanchego --network-id = flare --http-host = \\ --bootstrap-ips = \" $( curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeIP\" }' \\ -H 'content-type:application/json;' https://flare.flare.network/ext/info \\ | jq -r \".result.ip\" ) \" \\ --bootstrap-ids = \" $( curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeID\" }' \\ -H 'content-type:application/json;' https://flare.flare.network/ext/info \\ | jq -r \".result.nodeID\" ) \" ./build/flare --network-id = songbird --http-host = \\ --bootstrap-ips = \" $( curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeIP\" }' \\ -H 'content-type:application/json;' https://songbird.flare.network/ext/info \\ | jq -r \".result.ip\" ) \" \\ --bootstrap-ids = \" $( curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeID\" }' \\ -H 'content-type:application/json;' https://songbird.flare.network/ext/info \\ | jq -r \".result.nodeID\" ) \" ./build/flare --network-id = coston --http-host = \\ --bootstrap-ips = \" $( curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeIP\" }' \\ -H 'content-type:application/json;' https://coston.flare.network/ext/info \\ | jq -r \".result.ip\" ) \" \\ --bootstrap-ids = \" $( curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeID\" }' \\ -H 'content-type:application/json;' https://coston.flare.network/ext/info \\ | jq -r \".result.nodeID\" ) \" ./build/avalanchego --network-id = costwo --http-host = \\ --bootstrap-ips = \" $( curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeIP\" }' \\ -H 'content-type:application/json;' https://coston2.flare.network/ext/info \\ | jq -r \".result.ip\" ) \" \\ --bootstrap-ids = \" $( curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeID\" }' \\ -H 'content-type:application/json;' https://coston2.flare.network/ext/info \\ | jq -r \".result.nodeID\" ) \" After a lot of log messages the node should start synchronizing with the network, which might take a long time (currently about 4 hours for Flare, over a week for Songbird, depending on network speed and machine specs). You can stop the node at any time by pressing Ctrl-C . Use the same command line as before to restart the node. Synchronization will resume where it left if it is interrupted. You will know your node is fully booted and accepting transactions when the output of this command: curl http://127.0.0.1:9650/ext/health Contains the field \"healthy\":true in the returned JSON object. Note If the node gets stuck during bootstrap (it takes far longer than the estimates given above), try to add the parameter --bootstrap-retry-enabled=false . 4. Additional Configuration # These are some of the most relevant command line parameters you can use. You can read about all of them in the Avalanche documentation . --bootstrap-ips , --bootstrap-ids : IP address and node ID of the peer used to connect to the rest of the network for bootstrapping. You can use Flare's public nodes for this, as shown in the quick start command given above: Flare Songbird Coston Coston 2 Peer's IP address: curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeIP\" }' \\ -H 'content-type:application/json;' \\ https://flare.flare.network/ext/info | jq -r \".result.ip\" Peer's node ID: curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeID\" }' \\ -H 'content-type:application/json;' \\ https://flare.flare.network/ext/info | jq -r \".result.nodeID\" Peer's IP address: curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeIP\" }' \\ -H 'content-type:application/json;' \\ https://songbird.flare.network/ext/info | jq -r \".result.ip\" Peer's node ID: curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeID\" }' \\ -H 'content-type:application/json;' \\ https://songbird.flare.network/ext/info | jq -r \".result.nodeID\" Peer's IP address: curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeIP\" }' \\ -H 'content-type:application/json;' \\ https://coston.flare.network/ext/info | jq -r \".result.ip\" Peer's node ID: curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeID\" }' \\ -H 'content-type:application/json;' \\ https://coston.flare.network/ext/info | jq -r \".result.nodeID\" Peer's IP address: curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeIP\" }' \\ -H 'content-type:application/json;' \\ https://coston2.flare.network/ext/info | jq -r \".result.ip\" Peer's node ID: curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeID\" }' \\ -H 'content-type:application/json;' \\ https://coston2.flare.network/ext/info | jq -r \".result.nodeID\" Remember that you need to whitelist your node's IP address or your queries will always be answered with 403 error codes. --http-host : Use --http-host= (empty) to allow connections from other machines. Otherwise, only connections from localhost are accepted. --http-port : The port through which the node will listen to API requests. The default value is 9650 . --staking-port : The port through which the network peers will connect to this node externally. Having this port accessible from the internet is required for correct node operation. The default value is 9651 . --db-dir : Directory where the database is stored. Make sure to use a disk with enough space as recommended in the Hardware prerequisites section. It defaults to ~/.avalanchego/db on Flare and Coston 2, and to ~/.flare/db on Songbird and Coston. You can use this option to store the database on an external drive, for example. --chain-config-dir : Optional JSON configuration file, in case you want to use lots of non-default values. Sample configuration file for observer nodes These are the most common configuration options. Put them in a file in the {chain-config-dir}/C/config.json folder. { \"snowman-api-enabled\" : false , \"coreth-admin-api-enabled\" : false , \"eth-apis\" : [ \"public-eth\" , \"public-eth-filter\" , \"net\" , \"web3\" , \"internal-public-eth\" , \"internal-public-blockchain\" , \"internal-public-transaction-pool\" ], \"rpc-gas-cap\" : 50000000 , \"rpc-tx-fee-cap\" : 100 , \"pruning-enabled\" : true , \"local-txs-enabled\" : false , \"api-max-duration\" : 0 , \"api-max-blocks-per-request\" : 0 , \"allow-unfinalized-queries\" : false , \"allow-unprotected-txs\" : false , \"remote-tx-gossip-only-enabled\" : false , \"log-level\" : \"info\" } Archival nodes : An archival node keeps the whole history of the blockchain, instead of pruning old transactions which is the default setting. Use the pruning-enabled configuration setting to control whether your node performs pruning or not. Archival nodes have significantly increased disk requirements.","title":"Deploying an Observer Node"},{"location":"infra/observation/deploying/#deploying-an-observer-node","text":"","title":"Deploying an Observer Node"},{"location":"infra/observation/deploying/#introduction","text":"Observer nodes enable anyone to observe the network and submit transactions. Unlike validator nodes , which provide state consensus and add blocks, observer nodes remain outside the network and have no effect on consensus or blocks. Running an observer node is optional. However, submitting transactions through your own node offers a number of benefits: Transactions are sent directly to the network instead of through a third party, removing a potential security risk. Public nodes are usually rate-limited (the amount of requests they accept per second is restricted). Your own node does not have such restriction. The time savings described above allow FTSO data providers to submit their data a few seconds later, thus having more time to gather data before submitting. This guide explains how to deploy your own observer node so you can reap these benefits.","title":"Introduction"},{"location":"infra/observation/deploying/#prerequisites","text":"This guide contains different instructions depending on which Flare network you want to deploy to, so make sure you are aware of the available networks . Flare Songbird Coston Coston 2 Hardware Software CPU cores 8 Operating System Ubuntu (18.04 or 20.04) or macOS (>= 10.15 Catalina) RAM 32 GB Dependencies Go (>= 1.18.5) Disk space 1 TB SSD gcc Disk growth 2.5 TB/year g++ jq Hardware Software CPU cores 8 Operating System Ubuntu (18.04 or 20.04) or macOS (>= 10.15 Catalina) RAM 32 GB Dependencies Go (>= 1.16.8) Disk space 3.5 TB SSD gcc Disk growth 2.5 TB/year g++ jq Hardware Software CPU cores 4 Operating System Ubuntu (18.04 or 20.04) or macOS (>= 10.15 Catalina) RAM 16 GB Dependencies Go (>= 1.16.8) Disk space 500 GB SSD gcc Disk growth 250 GB/year g++ jq Hardware Software CPU cores 4 Operating System Ubuntu (18.04 or 20.04) or macOS (>= 10.15 Catalina) RAM 16 GB Dependencies Go (>= 1.18.5) Disk space 500 GB SSD gcc Disk growth 250 GB/year g++ jq Plus a reliable IPv4 or IPv6 network connection, with an open public port. Keep in mind that enabling pruning as described below can reduce the required disk space by as much as 60%.","title":"Prerequisites"},{"location":"infra/observation/deploying/#guide","text":"","title":"Guide"},{"location":"infra/observation/deploying/#1-installation","text":"Flare & Coston 2 Songbird & Coston Clone the go-flare repository and run the build.sh script: git clone https://github.com/flare-foundation/go-flare.git cd go-flare/avalanchego ./scripts/build.sh The resulting executable will be build/avalanchego . Note You can verify the installation by running: go test $( go list ./... | grep -v /tests/ ) # avalanchego unit tests cd ../coreth go test ./... # coreth unit tests cd ../avalanchego Clone the go-songbird repository and run the build.sh script: git clone https://github.com/flare-foundation/go-songbird.git cd go-songbird/avalanchego ./scripts/build.sh The resulting executable will be build/flare . Note You can verify the installation by running: go test $( go list ./... | grep -v /tests/ ) # avalanchego unit tests cd coreth go test ./... # coreth unit tests cd ..","title":"1. Installation"},{"location":"infra/observation/deploying/#2-songbird-node-whitelisting","text":"While Songbird network is being tested, all nodes wanting to peer with it (including observer nodes) need to have their IP address whitelisted . To do this, please contact Tom T. over Discord ( Tom T#7603 ), Telegram ( @TampaBay7 ) or email ( tom@flare.network ) and request to be whitelisted. Checking the status of your Songbird whitelisting request curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeIP\" }' \\ -H 'content-type:application/json;' \\ https://songbird.flare.network/ext/info If your IP address is whitelisted, this command returns a JSON response. Otherwise you will get a 403 error (\"Forbidden\"). Please note that whitelisting is not needed on the Flare network or any of the Coston networks .","title":"2. Songbird Node Whitelisting"},{"location":"infra/observation/deploying/#3-run-the-node","text":"This is the minimum command to quickly get your node up and running. To understand each parameter read the following step before launching the node. Flare Songbird Coston Coston 2 ./build/avalanchego --network-id = flare --http-host = \\ --bootstrap-ips = \" $( curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeIP\" }' \\ -H 'content-type:application/json;' https://flare.flare.network/ext/info \\ | jq -r \".result.ip\" ) \" \\ --bootstrap-ids = \" $( curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeID\" }' \\ -H 'content-type:application/json;' https://flare.flare.network/ext/info \\ | jq -r \".result.nodeID\" ) \" ./build/flare --network-id = songbird --http-host = \\ --bootstrap-ips = \" $( curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeIP\" }' \\ -H 'content-type:application/json;' https://songbird.flare.network/ext/info \\ | jq -r \".result.ip\" ) \" \\ --bootstrap-ids = \" $( curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeID\" }' \\ -H 'content-type:application/json;' https://songbird.flare.network/ext/info \\ | jq -r \".result.nodeID\" ) \" ./build/flare --network-id = coston --http-host = \\ --bootstrap-ips = \" $( curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeIP\" }' \\ -H 'content-type:application/json;' https://coston.flare.network/ext/info \\ | jq -r \".result.ip\" ) \" \\ --bootstrap-ids = \" $( curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeID\" }' \\ -H 'content-type:application/json;' https://coston.flare.network/ext/info \\ | jq -r \".result.nodeID\" ) \" ./build/avalanchego --network-id = costwo --http-host = \\ --bootstrap-ips = \" $( curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeIP\" }' \\ -H 'content-type:application/json;' https://coston2.flare.network/ext/info \\ | jq -r \".result.ip\" ) \" \\ --bootstrap-ids = \" $( curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeID\" }' \\ -H 'content-type:application/json;' https://coston2.flare.network/ext/info \\ | jq -r \".result.nodeID\" ) \" After a lot of log messages the node should start synchronizing with the network, which might take a long time (currently about 4 hours for Flare, over a week for Songbird, depending on network speed and machine specs). You can stop the node at any time by pressing Ctrl-C . Use the same command line as before to restart the node. Synchronization will resume where it left if it is interrupted. You will know your node is fully booted and accepting transactions when the output of this command: curl http://127.0.0.1:9650/ext/health Contains the field \"healthy\":true in the returned JSON object. Note If the node gets stuck during bootstrap (it takes far longer than the estimates given above), try to add the parameter --bootstrap-retry-enabled=false .","title":"3. Run the Node"},{"location":"infra/observation/deploying/#4-additional-configuration","text":"These are some of the most relevant command line parameters you can use. You can read about all of them in the Avalanche documentation . --bootstrap-ips , --bootstrap-ids : IP address and node ID of the peer used to connect to the rest of the network for bootstrapping. You can use Flare's public nodes for this, as shown in the quick start command given above: Flare Songbird Coston Coston 2 Peer's IP address: curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeIP\" }' \\ -H 'content-type:application/json;' \\ https://flare.flare.network/ext/info | jq -r \".result.ip\" Peer's node ID: curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeID\" }' \\ -H 'content-type:application/json;' \\ https://flare.flare.network/ext/info | jq -r \".result.nodeID\" Peer's IP address: curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeIP\" }' \\ -H 'content-type:application/json;' \\ https://songbird.flare.network/ext/info | jq -r \".result.ip\" Peer's node ID: curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeID\" }' \\ -H 'content-type:application/json;' \\ https://songbird.flare.network/ext/info | jq -r \".result.nodeID\" Peer's IP address: curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeIP\" }' \\ -H 'content-type:application/json;' \\ https://coston.flare.network/ext/info | jq -r \".result.ip\" Peer's node ID: curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeID\" }' \\ -H 'content-type:application/json;' \\ https://coston.flare.network/ext/info | jq -r \".result.nodeID\" Peer's IP address: curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeIP\" }' \\ -H 'content-type:application/json;' \\ https://coston2.flare.network/ext/info | jq -r \".result.ip\" Peer's node ID: curl -m 10 -sX POST \\ --data '{ \"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"info.getNodeID\" }' \\ -H 'content-type:application/json;' \\ https://coston2.flare.network/ext/info | jq -r \".result.nodeID\" Remember that you need to whitelist your node's IP address or your queries will always be answered with 403 error codes. --http-host : Use --http-host= (empty) to allow connections from other machines. Otherwise, only connections from localhost are accepted. --http-port : The port through which the node will listen to API requests. The default value is 9650 . --staking-port : The port through which the network peers will connect to this node externally. Having this port accessible from the internet is required for correct node operation. The default value is 9651 . --db-dir : Directory where the database is stored. Make sure to use a disk with enough space as recommended in the Hardware prerequisites section. It defaults to ~/.avalanchego/db on Flare and Coston 2, and to ~/.flare/db on Songbird and Coston. You can use this option to store the database on an external drive, for example. --chain-config-dir : Optional JSON configuration file, in case you want to use lots of non-default values. Sample configuration file for observer nodes These are the most common configuration options. Put them in a file in the {chain-config-dir}/C/config.json folder. { \"snowman-api-enabled\" : false , \"coreth-admin-api-enabled\" : false , \"eth-apis\" : [ \"public-eth\" , \"public-eth-filter\" , \"net\" , \"web3\" , \"internal-public-eth\" , \"internal-public-blockchain\" , \"internal-public-transaction-pool\" ], \"rpc-gas-cap\" : 50000000 , \"rpc-tx-fee-cap\" : 100 , \"pruning-enabled\" : true , \"local-txs-enabled\" : false , \"api-max-duration\" : 0 , \"api-max-blocks-per-request\" : 0 , \"allow-unfinalized-queries\" : false , \"allow-unprotected-txs\" : false , \"remote-tx-gossip-only-enabled\" : false , \"log-level\" : \"info\" } Archival nodes : An archival node keeps the whole history of the blockchain, instead of pruning old transactions which is the default setting. Use the pruning-enabled configuration setting to control whether your node performs pruning or not. Archival nodes have significantly increased disk requirements.","title":"4. Additional Configuration"},{"location":"infra/observation/faq/","text":"FAQ # Do I need to re-whitelist my peering node IP? # No, you do not need to re-whitelist the IP address. I want to have greater redundancy and would like to whitelist multiple nodes, can I do that? # Yes, you can whitelist multiple IPs per single provider. Can an unhealthy node cause my transactions to revert? # Yes, at times, not enough connected peers can cause your transactions to revert. Make sure your node state is healthy and that it has enough connected peers. How do I check the number of connected peers? # curl http://127.0.0.1:9650/ext/health | jq And look for the line containing connectedPeers . If you want to automate the process you can use: curl -s http://127.0.0.1:9650/ext/health | \\ jq -r \".checks.network.message.connectedPeers\" What is the required number of connected peers? # If the number of peers falls below 16, chances are your node will not work correctly. While the network is being decentralized, any number below 20 is indication of a problem. In any case, try restarting the node. The node does not sync after a long time and dies abruptly, what should I do? # Make sure, that the database location has sufficient disk space (database size might change a lot during bootstrapping). I am getting strange errors on submission and revert messages are cryptic # This might be a symptom of a node connection error. Try to restart the node and make sure you have enough disk space. I am getting a strange error related to GetAcceptedFrontier during bootstrapping # failed to send GetAcceptedFrontier(MtF8bVH241hetCQJgsKEdKyJBs8vhp1BC, 11111111111111111111111111111111LpoYY, NUMBER) It looks like your node got disconnected during bootstrapping. Try restarting the node. I have synced the node but it does not become healthy. What can I do? # It often happens that a new node gets synced but stays unhealthy for no apparent reason. A restart usually helps.","title":"FAQ"},{"location":"infra/observation/faq/#faq","text":"","title":"FAQ"},{"location":"infra/observation/faq/#do-i-need-to-re-whitelist-my-peering-node-ip","text":"No, you do not need to re-whitelist the IP address.","title":"Do I need to re-whitelist my peering node IP?"},{"location":"infra/observation/faq/#i-want-to-have-greater-redundancy-and-would-like-to-whitelist-multiple-nodes-can-i-do-that","text":"Yes, you can whitelist multiple IPs per single provider.","title":"I want to have greater redundancy and would like to whitelist multiple nodes, can I do that?"},{"location":"infra/observation/faq/#can-an-unhealthy-node-cause-my-transactions-to-revert","text":"Yes, at times, not enough connected peers can cause your transactions to revert. Make sure your node state is healthy and that it has enough connected peers.","title":"Can an unhealthy node cause my transactions to revert?"},{"location":"infra/observation/faq/#how-do-i-check-the-number-of-connected-peers","text":"curl http://127.0.0.1:9650/ext/health | jq And look for the line containing connectedPeers . If you want to automate the process you can use: curl -s http://127.0.0.1:9650/ext/health | \\ jq -r \".checks.network.message.connectedPeers\"","title":"How do I check the number of connected peers?"},{"location":"infra/observation/faq/#what-is-the-required-number-of-connected-peers","text":"If the number of peers falls below 16, chances are your node will not work correctly. While the network is being decentralized, any number below 20 is indication of a problem. In any case, try restarting the node.","title":"What is the required number of connected peers?"},{"location":"infra/observation/faq/#the-node-does-not-sync-after-a-long-time-and-dies-abruptly-what-should-i-do","text":"Make sure, that the database location has sufficient disk space (database size might change a lot during bootstrapping).","title":"The node does not sync after a long time and dies abruptly, what should I do?"},{"location":"infra/observation/faq/#i-am-getting-strange-errors-on-submission-and-revert-messages-are-cryptic","text":"This might be a symptom of a node connection error. Try to restart the node and make sure you have enough disk space.","title":"I am getting strange errors on submission and revert messages are cryptic"},{"location":"infra/observation/faq/#i-am-getting-a-strange-error-related-to-getacceptedfrontier-during-bootstrapping","text":"failed to send GetAcceptedFrontier(MtF8bVH241hetCQJgsKEdKyJBs8vhp1BC, 11111111111111111111111111111111LpoYY, NUMBER) It looks like your node got disconnected during bootstrapping. Try restarting the node.","title":"I am getting a strange error related to GetAcceptedFrontier during bootstrapping"},{"location":"infra/observation/faq/#i-have-synced-the-node-but-it-does-not-become-healthy-what-can-i-do","text":"It often happens that a new node gets synced but stays unhealthy for no apparent reason. A restart usually helps.","title":"I have synced the node but it does not become healthy. What can I do?"},{"location":"infra/validation/","text":"Validator Nodes # Select the topic below: Deploying a Validator Node Staking on a Validator","title":"Validator Nodes"},{"location":"infra/validation/#validator-nodes","text":"Select the topic below: Deploying a Validator Node Staking on a Validator","title":"Validator Nodes"},{"location":"infra/validation/deploying/","text":"Deploying a Validator Node # Introduction # As explained in the Validator Nodes page, these servers fulfill a critical role in securing the network: They check that all received transactions are valid. They run a consensus algorithm so that all validators in the network agree on the transactions to add to the blockchain. Finally, they add the agreed-upon transactions to their copy of the ledger . Additionally, all blockchains must employ measures against Sybil attacks and the Flare network is planning two such measures: Validators will need to stake native tokens, just like in regular Proof of Stake . Validators will also need to be FTSO Data Providers , and their performance in this role will have an impact on their validation rewards, leading to a meritocratic system. However, given the importance of the validator role and the novelty of the meritocratic approach, these measures are being implemented in phases: Implementation phases Phase 0 : Only validators with preregistered keys can be deployed. Some users will receive preregistered validator keys , this is, the keys required to launch a node which has already been registered as a validator . This is the only way to deploy a validator node during this phase. Phase 1 : Candidate FTSO validators. FTSO data providers that wish to become validators need to undergo a KYC process (Contact Tom T. over Discord ( Tom T#7603 ), Telegram ( @TampaBay7 ) or email ) and operate an Observer node . Random security scans will be performed on the node, and if all of them are successful (see Mandatory security measures below) validator rewards will be accrued. Validator rewards are split evenly among all candidate validators that passed the security scans. More phases will be added as the process is refined. Information affecting only specific phases is indicated in this guide with colored boxes like this one. This guide explains how to deploy your own validator node so you can participate in the consensus and collect the rewards that the network provides to those who help secure it. The following instructions apply to the Flare network only. Prerequisites # Validators run the same software as regular observer nodes , therefore, this guide assumes you have already read the Deploying an Observer Node guide. The requirements to deploy a validator node are the same as for observer nodes, except on the CPU and RAM front which are heavier due to the extra work required: Hardware Software CPU cores 16 Operating System Ubuntu (18.04 or 20.04) or macOS (>= 10.15 Catalina) RAM 64 GB Dependencies Go (>= 1.18.5) Disk space 1 TB SSD gcc Disk growth 2.5 TB/year g++ jq npm (>= 8.11) Guide # 1. Configure the Node # A validator node is deployed like an observer node, but there are some additional considerations. Firstly, validators do more work than plain observer nodes so please consider the recommended hardware specifications above. And secondly, validator security impacts the whole network. Please consider the following items carefully: Mandatory security measures # Ensure port 9650 is not externally reachable. This is the port used to answer API requests and validators should not be doing that. Disallow password authentication over SSH. Don't run any non-validator services on the same IP (website, mail server, etc). Warning A monitoring tool run by Flare periodically checks that the above measures are followed by all validators. Failure to comply impacts the validator's rewards. Phase 1 exemption To ease the deployment of candidate validators during phase 1 port 9650, used to answer API requests, might be left open. This allows running the candidate validator on the same machine currently running the observer node used to submit FTSO data. Suggested security measures # Disallow any ICMP traffic. Have the machine firewalled . Only the ports required for validator operation should be open (i.e. only the staking port, which defaults to 9651). If you use a virtual server, use only its web interface for management and close the SSH port. If the SSH port must be open, it should ideally be restricted to a private IP (i.e. only accessible through VPN) or only temporarily open to the operator's office/home static IP or a bastion SSH VM that can be turned off between use. The node should only act as a validator , and not accept RPC API calls. You should deploy a separate observer node for tasks requiring RPC API access. Additionally, this observer node can point to your validator for peering and bootstrapping. The validator should only enable the minimum set of EVM APIs by adding this line to a configuration file : \"eth-apis\" : [ \"web3\" ] Sample configuration file for validator nodes { \"snowman-api-enabled\" : false , \"coreth-admin-api-enabled\" : false , \"coreth-admin-api-dir\" : \"\" , \"eth-apis\" : [ \"web3\" ], \"continuous-profiler-dir\" : \"\" , \"continuous-profiler-frequency\" : 900000000000 , \"continuous-profiler-max-files\" : 5 , \"rpc-gas-cap\" : 50000000 , \"rpc-tx-fee-cap\" : 100 , \"preimages-enabled\" : false , \"pruning-enabled\" : false , \"snapshot-async\" : true , \"snapshot-verification-enabled\" : false , \"metrics-enabled\" : true , \"metrics-expensive-enabled\" : false , \"local-txs-enabled\" : false , \"api-max-duration\" : 30000000000 , \"ws-cpu-refill-rate\" : 0 , \"ws-cpu-max-stored\" : 0 , \"api-max-blocks-per-request\" : 30 , \"allow-unfinalized-queries\" : false , \"allow-unprotected-txs\" : false , \"keystore-directory\" : \"\" , \"keystore-external-signer\" : \"\" , \"keystore-insecure-unlock-allowed\" : false , \"remote-tx-gossip-only-enabled\" : false , \"tx-regossip-frequency\" : 60000000000 , \"tx-regossip-max-size\" : 15 , \"log-level\" : \"info\" , \"offline-pruning-enabled\" : false , \"offline-pruning-bloom-filter-size\" : 512 , \"offline-pruning-data-directory\" : \"\" } 2. Run the Node # After taking the above considerations into account, you can now start up your node by following the Deploying an Observation Node guide. Preregistered validator keys Some users have received preregistered validator keys , this is, the keys required to deploy a node which has already been registered as a validator. If that is your case, you just need to add these parameters to the launch command line: --staking-tls-cert-file = \\ --staking-tls-key-file = ","title":"Deploying a Validator Node"},{"location":"infra/validation/deploying/#deploying-a-validator-node","text":"","title":"Deploying a Validator Node"},{"location":"infra/validation/deploying/#introduction","text":"As explained in the Validator Nodes page, these servers fulfill a critical role in securing the network: They check that all received transactions are valid. They run a consensus algorithm so that all validators in the network agree on the transactions to add to the blockchain. Finally, they add the agreed-upon transactions to their copy of the ledger . Additionally, all blockchains must employ measures against Sybil attacks and the Flare network is planning two such measures: Validators will need to stake native tokens, just like in regular Proof of Stake . Validators will also need to be FTSO Data Providers , and their performance in this role will have an impact on their validation rewards, leading to a meritocratic system. However, given the importance of the validator role and the novelty of the meritocratic approach, these measures are being implemented in phases: Implementation phases Phase 0 : Only validators with preregistered keys can be deployed. Some users will receive preregistered validator keys , this is, the keys required to launch a node which has already been registered as a validator . This is the only way to deploy a validator node during this phase. Phase 1 : Candidate FTSO validators. FTSO data providers that wish to become validators need to undergo a KYC process (Contact Tom T. over Discord ( Tom T#7603 ), Telegram ( @TampaBay7 ) or email ) and operate an Observer node . Random security scans will be performed on the node, and if all of them are successful (see Mandatory security measures below) validator rewards will be accrued. Validator rewards are split evenly among all candidate validators that passed the security scans. More phases will be added as the process is refined. Information affecting only specific phases is indicated in this guide with colored boxes like this one. This guide explains how to deploy your own validator node so you can participate in the consensus and collect the rewards that the network provides to those who help secure it. The following instructions apply to the Flare network only.","title":"Introduction"},{"location":"infra/validation/deploying/#prerequisites","text":"Validators run the same software as regular observer nodes , therefore, this guide assumes you have already read the Deploying an Observer Node guide. The requirements to deploy a validator node are the same as for observer nodes, except on the CPU and RAM front which are heavier due to the extra work required: Hardware Software CPU cores 16 Operating System Ubuntu (18.04 or 20.04) or macOS (>= 10.15 Catalina) RAM 64 GB Dependencies Go (>= 1.18.5) Disk space 1 TB SSD gcc Disk growth 2.5 TB/year g++ jq npm (>= 8.11)","title":"Prerequisites"},{"location":"infra/validation/deploying/#guide","text":"","title":"Guide"},{"location":"infra/validation/deploying/#1-configure-the-node","text":"A validator node is deployed like an observer node, but there are some additional considerations. Firstly, validators do more work than plain observer nodes so please consider the recommended hardware specifications above. And secondly, validator security impacts the whole network. Please consider the following items carefully:","title":"1. Configure the Node"},{"location":"infra/validation/deploying/#mandatory-security-measures","text":"Ensure port 9650 is not externally reachable. This is the port used to answer API requests and validators should not be doing that. Disallow password authentication over SSH. Don't run any non-validator services on the same IP (website, mail server, etc). Warning A monitoring tool run by Flare periodically checks that the above measures are followed by all validators. Failure to comply impacts the validator's rewards. Phase 1 exemption To ease the deployment of candidate validators during phase 1 port 9650, used to answer API requests, might be left open. This allows running the candidate validator on the same machine currently running the observer node used to submit FTSO data.","title":"Mandatory security measures"},{"location":"infra/validation/deploying/#suggested-security-measures","text":"Disallow any ICMP traffic. Have the machine firewalled . Only the ports required for validator operation should be open (i.e. only the staking port, which defaults to 9651). If you use a virtual server, use only its web interface for management and close the SSH port. If the SSH port must be open, it should ideally be restricted to a private IP (i.e. only accessible through VPN) or only temporarily open to the operator's office/home static IP or a bastion SSH VM that can be turned off between use. The node should only act as a validator , and not accept RPC API calls. You should deploy a separate observer node for tasks requiring RPC API access. Additionally, this observer node can point to your validator for peering and bootstrapping. The validator should only enable the minimum set of EVM APIs by adding this line to a configuration file : \"eth-apis\" : [ \"web3\" ] Sample configuration file for validator nodes { \"snowman-api-enabled\" : false , \"coreth-admin-api-enabled\" : false , \"coreth-admin-api-dir\" : \"\" , \"eth-apis\" : [ \"web3\" ], \"continuous-profiler-dir\" : \"\" , \"continuous-profiler-frequency\" : 900000000000 , \"continuous-profiler-max-files\" : 5 , \"rpc-gas-cap\" : 50000000 , \"rpc-tx-fee-cap\" : 100 , \"preimages-enabled\" : false , \"pruning-enabled\" : false , \"snapshot-async\" : true , \"snapshot-verification-enabled\" : false , \"metrics-enabled\" : true , \"metrics-expensive-enabled\" : false , \"local-txs-enabled\" : false , \"api-max-duration\" : 30000000000 , \"ws-cpu-refill-rate\" : 0 , \"ws-cpu-max-stored\" : 0 , \"api-max-blocks-per-request\" : 30 , \"allow-unfinalized-queries\" : false , \"allow-unprotected-txs\" : false , \"keystore-directory\" : \"\" , \"keystore-external-signer\" : \"\" , \"keystore-insecure-unlock-allowed\" : false , \"remote-tx-gossip-only-enabled\" : false , \"tx-regossip-frequency\" : 60000000000 , \"tx-regossip-max-size\" : 15 , \"log-level\" : \"info\" , \"offline-pruning-enabled\" : false , \"offline-pruning-bloom-filter-size\" : 512 , \"offline-pruning-data-directory\" : \"\" }","title":"Suggested security measures"},{"location":"infra/validation/deploying/#2-run-the-node","text":"After taking the above considerations into account, you can now start up your node by following the Deploying an Observation Node guide. Preregistered validator keys Some users have received preregistered validator keys , this is, the keys required to deploy a node which has already been registered as a validator. If that is your case, you just need to add these parameters to the launch command line: --staking-tls-cert-file = \\ --staking-tls-key-file = ","title":"2. Run the Node"},{"location":"infra/validation/staking-cli/","text":"Staking on a Validator # Flare has a command-line interface (CLI) tool called Flare Stake CLI, which allows performing stake operations on validator nodes from a terminal. A staking app with a graphical user interface (GUI) is also being developed to simplify the staking process. Still, a CLI tool has other advantages, like allowing it to be part of automated processes. Table of Contents Staking Overview : What you need to know about staking. Installing the Flare Stake CLI : Install required tools. Staking Guide : How to perform staking. Claiming Guide : How to claim staking rewards. Troubleshooting : Addressing common issues. Staking Overview # If you already know how staking on validators works on the Flare network, skip this section. Note Proof of stake is being implemented in phases. Ensure that you have read the Validators page to learn about them. Staking works by locking funds for a period of time to support a specific network validator . When validator owners stake to their own nodes they self-bond , whereas all other participants are said to delegate their stake to that validator. Participants choose how much to stake and for how long their stake will be locked. The minimum values are: Self-bond Delegation Minimum amount 1M $FLR 50K $FLR Minimum duration 60 days 14 days At the end of every reward epoch , participants are rewarded according to how well their chosen validator performed in that period. The deployment phases summary shows other rewards that staked funds can still earn while they are locked. Given that the Flare network uses two independent underlying chains , there is one extra step that must be considered. Funds must be transferred from the C-chain, where smart contracts run, to the P-chain, where staking happens. After the staking period expires and funds are unlocked, they can be transferred back to the C-chain. This guide explains how to perform the above operations using the Flare Stake CLI tool. Installing the Flare Stake CLI # This tool is open source, so it can be installed from its source code . However, it is more convenient to use the prepackaged npm version . The Flare Stake CLI works on Windows, Mac, and Linux. Note It is not recommended to run this tool using the Windows Subsystem for Linux (WSL), as it might have issues accessing hardware wallets through USB ports. On Windows, use the standard Windows command prompt or terminal instead. Prerequisites # Install the npm package manager . This guide has been tested with Node.js v18.16.0 and npm v9.5.1 . Installation # After npm is available, type this command into a terminal to make the tool available from any folder: npm install @flarenetwork/flare-stake-tool -g Check that the tool has been correctly installed by running: flare-stake-tool The tool's banner is displayed: _____ _ ____ _ _ ____ _ ___ | ___| | __ _ _ __ ___ / ___|| |_ __ _| | _____ / ___| | |_ _| | |_ | |/ _` | '__/ _ \\ \\___ \\| __/ _` | |/ / _ \\ | | | | | | | _| | | (_| | | | __/ ___) | || (_| | < __/ | |___| |___ | | |_| |_|\\__,_|_| \\___| |____/ \\__\\__,_|_|\\_\\___| \\____|_____|___| Version: 3.0.2 Make sure at least version 3.0.0 has been installed. Configuration # You can specify the account from which staking will take place in different ways. Choose one of the following two options. Note that using a Ledger hardware wallet is the only recommended way. Ledger Configuration Your device must be configured before it can be used: Install the Avalanche application : Connect the device to your computer and unlock it using your PIN code. Open the Ledger Live application. Go to the My Ledger tab and make sure the device is using the latest firmware. In the App catalog tab, search for \"Avalanche\" and click on the Install button. Note that this app requires all available space on a Ledger Nano S device (138 KB). You might need to remove other apps first to free up space. Select your desired account : Exit the Ledger Live application and make sure the device is not connected to any other application like MetaMask. Open the Avalanche app on the Ledger. The screen should show \"Avalanche Ready\". From a terminal, enter: flare-stake-tool interactive This command starts the staking tool in interactive mode. In this mode the tool asks questions until it has enough information to execute a command. Then, after the welcome banner: ? How do you want to connect your wallet? (Use arrow keys) > Ledger Public Key Private Key (not recommended) Select Ledger with the cursor keys and press Enter . The next question is: ? Which network do you want to connect to? (Use arrow keys) > Flare (Mainnet) Coston2 (Testnet) LocalHost (for development only) Select Flare (Mainnet) and press Enter . This message shows for a few seconds: Fetching Addresses... Eventually a list of addresses is shown. These are the addresses that can be used from this device. Choose the one you want to stake from and press Enter . Keep in mind that this address needs to have a positive $FLR balance to pay for transaction fees and be able to stake. You can transfer funds to it later on. Finally the main menu appears: ? What do you want to do? (Use arrow keys) View chain addresses > Check on-chain balance Get network info Get validator info Move assets from C-chain to P-chain Move assets from P-chain to C-chain Add a validator node As an example, choose Check on-chain balance and press Enter . The balance of your selected account is shown for both the C-chain and the P-chain and the tool exits. At this point, a ctx.json file has been created in the current folder containing the selected account. When you run the tool from the same folder again, you will be given the option to use the same account. Using the same account saves you the inconvenience of repeating the above steps every time. Private Key Configuration If you have a Ledger device and you have already configured it, skip this step. If you do not have access to a Ledger device, you can still provide your account's private key in a plain text file, but this method is significantly less secure . Create a text file in a secure folder, i.e., one that is visible only to you. Give it any name you want. Inside, add one of the following two lines, depending on the format of your private key: PRIVATE_KEY_CB58=\"\" PRIVATE_KEY_HEX=\"\" If your key is in CB58 format, use the CB58 line. If your key is 64 hexadecimal characters, use the HEX line. Put the key inside the quotes. Enter this command on a terminal to check that the key works correctly: flare-stake-tool interactive This command starts the staking tool in interactive mode. In this mode the tool asks questions until it has enough information to execute a command. After the welcome banner you see: ? How do you want to connect your wallet? (Use arrow keys) Ledger Public Key > Private Key (not recommended) Select Private Key with the cursor keys and press Enter . The next question is: Warning: You are connecting using your private key which is not recommended ? Enter Path to Private Key file (E.g. /home/wallet/pvtKeyFile): Enter the name and path to the file you and created in step 1 and press Enter . Then: ? Which network do you want to connect to? (Use arrow keys) > Flare (Mainnet) Coston2 (Testnet) LocalHost (for development only) Select Flare (Mainnet) and press Enter . Finally the main menu appears: ? What do you want to do? (Use arrow keys) View chain addresses > Check on-chain balance Get network info Get validator info Move assets from C-chain to P-chain Move assets from P-chain to C-chain Add a validator node As an example, choose Check on-chain balance , and press Enter . The balance of your selected account is shown for both the C-chain and the P-chain and the tool exits. You can follow the rest of this guide by selecting the Private Key option when prompted. Staking Guide # To stake on a validator node, you need to: Check your current P-chain balance. Move funds from the C-chain to the P-chain. Stake them on a validator. Optionally, check that the request has been recorded. Optionally, move the staked funds back to the C-chain once they become unlocked. Before you start During the process you will need three pieces of information. Take note of them before you start so you can follow the rest of the steps uninterrupted. The node ID of the validator you want to stake to. If you created the validator, its nodeID was shown to you during the deployment process . If you want to stake to somebody else's validator, you can: See the list of current validators on flaremetrics.io . Remember to add NodeID- before the ID shown on the page. Use flare-stake-tool info validators to get a JSON list of all validators. The desired staking start time and end time . When staking to an existing validator, both these times must be inside the period when the validator is active, which you can find on flaremetrics.io or again using flare-stake-tool info validators . You need to provide these times as a UNIX timestamp , so you might need to use an online conversion tool like Epoch Converter or the Linux date command. As an example, the 1693185095 timestamp corresponds to Monday, August 28, 2023 1:11:35 AM. 1. Check your Balances # Check your balance by executing flare-stake-tool interactive and selecting the Check on-chain balance option: ? How do you want to connect your wallet? Ledger You already have an existing Ctx file with the following parameters - Public Key: \u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf Network: flare Eth Address: 0x\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf ? Do you wish to continue with this? yes ? What do you want to do? Check on-chain balance Using network: flare Balances on the network \"flare\" C-chain 0x\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf: 100000.0 FLR P-chain P-flare\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf: 50000.0 FLR Your currently available funds on the C-chain and P-chain are shown in the last lines. Funds currently staked are locked and are not reflected in the P-chain balance. They will become automatically available when the staking period expires. 2. Move Funds to P-Chain # If your funds are already on the P-Chain, skip this step. Move the funds by executing flare-stake-tool interactive again and selecting the Move assets from C-chain to P-chain option. You are asked the amount of $FLR you want to transfer: ? What do you want to do? Move assets from C-chain to P-chain ? Enter amount (in FLR): 50000 Transaction Fees When transferring from the C-chain to the P-chain, transaction fees are wholly paid from the C-chain. Make sure you leave enough funds on the C-chain after the transfer, or it will fail. Transfers between chains are made of two operations: an export from the C-chain followed by an import to the P-chain. Therefore, you are asked to confirm TWO transactions on your hardware wallet. Please approve export transaction Using network: flare Fetching account from ledger... Creating export transaction... Using fee of 0.00028075 FLR Please review and sign the transaction on your ledger device... Sending transaction to the node... Transaction with id \u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf sent to the node Please approve import transaction Using network: flare Fetching account from ledger... Creating export transaction... Please review and sign the transaction on your ledger device... Sending transaction to the node... Transaction with id \u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf sent to the node Finished execution You can check your balances again to verify that the transfer was successful. If you encounter any problem, see the Troubleshooting section. 3. Stake # After you have funds on the P-chain, execute flare-stake-tool interactive again and select the appropriate option: If you are going to delegate to your own node (self-bonding), select Add a validator node . Otherwise, if you are going to stake to another node (delegation), select Delegate to a validator node . Press the down key a few times for this last option to show. First-time Address Registration The first time you use the Add a validator node or Delegate to a validator node options you are asked to sign an additional transaction. This step is required so that staking rewards accrued on the P-chain can be claimed on the C-chain and participate in the wider ecosystem. This procedure only needs to be done once per P-chain address and it progresses like this: Checking Address Registration... No address found for key 0x\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf Note: You need to register your wallet address before you can delegate your funds Please complete this registration transaction to proceed Submitting txn to the chain Cryptographical Background Both your P-chain and C-chain addresses are derived from the same public key, but the process is not symmetrical: public keys cannot be derived from addresses. Therefore, smart contracts have no way of knowing the P-chain address that corresponds to a given C-chain address, unless they are both provided by their owner. This step performs exactly this operation, allowing a C-chain address to claim rewards that were accrued by its P-chain counterpart. Manual Address Registration Should automatic registration through the Flare Stake CLI tool fail, you can still register your addresses manually using the Block Explorer: Retrieve the public key that generated the accounts you want to use. From a terminal, run flare-stake-tool info addresses and copy the long hexadecimal string starting with 0x in the last line. Using network: flare Addresses on the network \"flare\" P-chain address: P-flare\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf C-chain address hex: 0x\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf secp256k1 public key: 0x\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf You need to interact with the AddressBinder smart contract, so you must retrieve its address from the FlareContractRegistry as explained in the retrieving Contract Addresses page . Enter the address of the AddressBinder contract in the Block Explorer , and go to the Write Contract tab. Click on Connect Wallet . You do not need to use the same account as the one you are binding. Locate the registerPublicKey method and paste the public key from step 1 into the _publicKey field. Click on Write and confirm the transaction from your wallet. If the transaction is successful, your account's P and C-chain addresses are now bound. You then need to provide the following information: Amount to stake : With the restrictions stated above . Amount must be provided in FLR units. Validator's NodeID : As explained in the Before you start section . Start time : As explained in the Before you start section . End time : As explained in the Before you start section . If you selected Add a validator node , you have one more question to answer: Delegation fee : This is the percentage of all rewards that the node owner keeps. The rest is split proportionally between the self-bond and all delegators that contributed stake. 10 means 10%, so the maximum value is 100. ? What do you want to do? Add a validator node ? Enter amount (in FLR): 50000 ? Enter Node NodeId (E.g. NodeID-FQKTLuZHEsjCxPeFTFgsojsucmdyNDsz1): NodeID-\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf ? Enter start time(E.g. 1693185095): \u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf ? Enter end time(E.g. 1693185095): \u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf ? Enter delegation fee(E.g. 10): 10 You are then asked to confirm the staking transaction on your hardware wallet. Using network: flare Fetching account from ledger... Creating export transaction... Please review and sign the transaction on your ledger device... Sending transaction to the node... Transaction with id \u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf sent to the node Finished execution Your stake is now locked and will start accruing rewards after the configured start time arrives. When the end time arrives, the funds will be automatically unlocked. If you encounter any problem, see the Troubleshooting section. 4. Check Stake # You can double-check that the operation has been properly registered by looking at the current list of validators: flare-stake-tool info validators > validators.txt This creates a file called validators.txt . Open it and search for the line containing the P-chain address of your account. If you don't know it, use flare-stake-tool info addresses . If your account has stake on any node, you will find a section similar to: { \"txID\" : \"28Yf5yQ3xt9yaMvfZ1RP5jkCkT4y2pfD86UheZUHFVng2tFcWd\" , \"startTime\" : \"1688569201\" , \"endTime\" : \"1696345201\" , \"stakeAmount\" : \"16750000000000000\" , \"nodeID\" : \"NodeID-C6i8mruq11VdxGQ7tiUBgrRqoLBot86df\" , \"rewardOwner\" : { \"locktime\" : \"0\" , \"threshold\" : \"1\" , \"addresses\" : [ \"P-flare19c8zfml39x6efnw5j90nl85dmwdqhluwhrxz9g\" ] }, }, Check that the stakeAmount (in wei), nodeID , startTime , and endTime match the values you configured. If you have multiple active stakes, your address can show multiple times. 5. Move funds back to C-Chain # Finally, you also have the option to move your P-chain funds back to the C-chain where they can participate in the wider ecosystem. You can only transfer P-chain funds that are not currently locked in any stake. Execute flare-stake-tool interactive and select the Move assets from P-chain to C-chain option. You are asked the amount of $FLR you want to transfer: ? What do you want to do? Move assets from P-chain to C-chain ? Enter amount (in FLR): 50000 Transaction Fees When transferring from the P to the C-chain, transaction fees are paid from BOTH chains. Make sure you leave enough funds on both chains after the transfer, or it will fail. Again, the transfer between the two chains require you to confirm TWO transactions on your hardware wallet. Please approve export transaction Using network: flare Fetching account from ledger... Creating export transaction... Please review and sign the transaction on your ledger device... Sending transaction to the node... Transaction with id \u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf sent to the node Please approve import transaction Using network: flare Fetching account from ledger... Creating export transaction... Using fee of 0.00028075 FLR Please review and sign the transaction on your ledger device... Sending transaction to the node... Transaction with id \u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf sent to the node Finished execution You can check your balances again to verify that the transfer was successful. If you encounter any problem, see the Troubleshooting section. Claiming Guide # At the end of every reward epoch , participants are rewarded according to how well their chosen validator performed in that period. Rewards are accumulated in a dedicated smart contract and can be claimed from the Flare Stake CLI tool: Execute flare-stake-tool interactive and select the Claim Rewards option. Press the down key a few times for this option to show. You are shown the amount of pending rewards (in wei) and are asked how much you want to claim (in FLR): ? What do you want to do? Claim Rewards Checking your Rewards status... You have unclaimed rewards worth 1000000000000000000 ? Enter amount to claim (in FLR): 1 Next, select Receive with another wallet and enter the C-chain address where you want the rewards to be sent. This can be the same address from where you are staking. ? Where do you want to receive your rewards? Receive with another wallet ? Please enter the C-address where you want to receive your rewards: 0x\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf You are then asked to confirm the staking transaction on your hardware wallet. Please sign the transaction on your ledger Submitting txn to the chain Rewards successfully claimed Finished execution Manual Reward Claiming Rewards can also be claimed directly from the ValidatorRewardManager contract that accumulates them: You need to interact with the ValidatorRewardManager smart contract, so you must retrieve its address from the FlareContractRegistry as explained in the retrieving Contract Addresses page . Enter the address of the ValidatorRewardManager contract in the Block Explorer , and go to the Write Contract tab. Click on Connect Wallet . You need to connect the account for which you are claiming. Locate the claim method and enter the following information: _rewardOwner : C-chain address that accrued the rewards. _recipient : Address where the rewards must be sent. _rewardAmount : Amount to claim. Find the pending amount using the getStateOfRewards method in the Read Contract tab. _wrap : Whether the rewards should be also wrapped, as a convenience. Click on Write and confirm the transaction from your wallet. If the transaction is successful, the reward is transferred to the specified recipient. Troubleshooting # Cannot connect to Ledger device, No Device, Cannot retrieve addresses, or similar Make sure: The device is connected, the Avalanche app is opened, and it shows the \"Avalanche Ready\" message. No other application like Ledger Live or MetaMask is connected to the device. The device is not in stand-by mode. You are not running on Windows from a Linux terminal (WSL). Use a native Windows console instead. Insufficient funds Make sure enough funds will remain after a transaction to pay for the transaction fees. If too much time has elapsed between the transaction's creation and its confirmation on the Ledger, the calculated fee might be incorrect. Try the operation again. The network might be congested and the calculated fees might not be high enough. Try the operation again after a while. Import transaction failed and the funds have vanished Transfer operations require an export and an import transaction . If the export succeeds, but then the import fails, it looks like the funds have disappeared from both chains, but they are still retrievable. Repeat the failed import operation manually: If you are moving funds from the C-chain to the P-chain: flare-stake-tool transaction importCP --ledger --blind If you are moving funds from the P-chain to the C-chain: flare-stake-tool transaction importPC --ledger --blind Unsupported digital routines If you get the following error message: E: Error: error:0308010C:digital envelope routines::unsupported Make sure you are using the correct Node.js version, as advised in the Prerequisites section . You can find out the version of Node.js you are running with the following command: node --version","title":"Staking on a Validator"},{"location":"infra/validation/staking-cli/#staking-on-a-validator","text":"Flare has a command-line interface (CLI) tool called Flare Stake CLI, which allows performing stake operations on validator nodes from a terminal. A staking app with a graphical user interface (GUI) is also being developed to simplify the staking process. Still, a CLI tool has other advantages, like allowing it to be part of automated processes. Table of Contents Staking Overview : What you need to know about staking. Installing the Flare Stake CLI : Install required tools. Staking Guide : How to perform staking. Claiming Guide : How to claim staking rewards. Troubleshooting : Addressing common issues.","title":"Staking on a Validator"},{"location":"infra/validation/staking-cli/#staking-overview","text":"If you already know how staking on validators works on the Flare network, skip this section. Note Proof of stake is being implemented in phases. Ensure that you have read the Validators page to learn about them. Staking works by locking funds for a period of time to support a specific network validator . When validator owners stake to their own nodes they self-bond , whereas all other participants are said to delegate their stake to that validator. Participants choose how much to stake and for how long their stake will be locked. The minimum values are: Self-bond Delegation Minimum amount 1M $FLR 50K $FLR Minimum duration 60 days 14 days At the end of every reward epoch , participants are rewarded according to how well their chosen validator performed in that period. The deployment phases summary shows other rewards that staked funds can still earn while they are locked. Given that the Flare network uses two independent underlying chains , there is one extra step that must be considered. Funds must be transferred from the C-chain, where smart contracts run, to the P-chain, where staking happens. After the staking period expires and funds are unlocked, they can be transferred back to the C-chain. This guide explains how to perform the above operations using the Flare Stake CLI tool.","title":"Staking Overview"},{"location":"infra/validation/staking-cli/#installing-the-flare-stake-cli","text":"This tool is open source, so it can be installed from its source code . However, it is more convenient to use the prepackaged npm version . The Flare Stake CLI works on Windows, Mac, and Linux. Note It is not recommended to run this tool using the Windows Subsystem for Linux (WSL), as it might have issues accessing hardware wallets through USB ports. On Windows, use the standard Windows command prompt or terminal instead.","title":"Installing the Flare Stake CLI"},{"location":"infra/validation/staking-cli/#prerequisites","text":"Install the npm package manager . This guide has been tested with Node.js v18.16.0 and npm v9.5.1 .","title":"Prerequisites"},{"location":"infra/validation/staking-cli/#installation","text":"After npm is available, type this command into a terminal to make the tool available from any folder: npm install @flarenetwork/flare-stake-tool -g Check that the tool has been correctly installed by running: flare-stake-tool The tool's banner is displayed: _____ _ ____ _ _ ____ _ ___ | ___| | __ _ _ __ ___ / ___|| |_ __ _| | _____ / ___| | |_ _| | |_ | |/ _` | '__/ _ \\ \\___ \\| __/ _` | |/ / _ \\ | | | | | | | _| | | (_| | | | __/ ___) | || (_| | < __/ | |___| |___ | | |_| |_|\\__,_|_| \\___| |____/ \\__\\__,_|_|\\_\\___| \\____|_____|___| Version: 3.0.2 Make sure at least version 3.0.0 has been installed.","title":"Installation"},{"location":"infra/validation/staking-cli/#configuration","text":"You can specify the account from which staking will take place in different ways. Choose one of the following two options. Note that using a Ledger hardware wallet is the only recommended way. Ledger Configuration Your device must be configured before it can be used: Install the Avalanche application : Connect the device to your computer and unlock it using your PIN code. Open the Ledger Live application. Go to the My Ledger tab and make sure the device is using the latest firmware. In the App catalog tab, search for \"Avalanche\" and click on the Install button. Note that this app requires all available space on a Ledger Nano S device (138 KB). You might need to remove other apps first to free up space. Select your desired account : Exit the Ledger Live application and make sure the device is not connected to any other application like MetaMask. Open the Avalanche app on the Ledger. The screen should show \"Avalanche Ready\". From a terminal, enter: flare-stake-tool interactive This command starts the staking tool in interactive mode. In this mode the tool asks questions until it has enough information to execute a command. Then, after the welcome banner: ? How do you want to connect your wallet? (Use arrow keys) > Ledger Public Key Private Key (not recommended) Select Ledger with the cursor keys and press Enter . The next question is: ? Which network do you want to connect to? (Use arrow keys) > Flare (Mainnet) Coston2 (Testnet) LocalHost (for development only) Select Flare (Mainnet) and press Enter . This message shows for a few seconds: Fetching Addresses... Eventually a list of addresses is shown. These are the addresses that can be used from this device. Choose the one you want to stake from and press Enter . Keep in mind that this address needs to have a positive $FLR balance to pay for transaction fees and be able to stake. You can transfer funds to it later on. Finally the main menu appears: ? What do you want to do? (Use arrow keys) View chain addresses > Check on-chain balance Get network info Get validator info Move assets from C-chain to P-chain Move assets from P-chain to C-chain Add a validator node As an example, choose Check on-chain balance and press Enter . The balance of your selected account is shown for both the C-chain and the P-chain and the tool exits. At this point, a ctx.json file has been created in the current folder containing the selected account. When you run the tool from the same folder again, you will be given the option to use the same account. Using the same account saves you the inconvenience of repeating the above steps every time. Private Key Configuration If you have a Ledger device and you have already configured it, skip this step. If you do not have access to a Ledger device, you can still provide your account's private key in a plain text file, but this method is significantly less secure . Create a text file in a secure folder, i.e., one that is visible only to you. Give it any name you want. Inside, add one of the following two lines, depending on the format of your private key: PRIVATE_KEY_CB58=\"\" PRIVATE_KEY_HEX=\"\" If your key is in CB58 format, use the CB58 line. If your key is 64 hexadecimal characters, use the HEX line. Put the key inside the quotes. Enter this command on a terminal to check that the key works correctly: flare-stake-tool interactive This command starts the staking tool in interactive mode. In this mode the tool asks questions until it has enough information to execute a command. After the welcome banner you see: ? How do you want to connect your wallet? (Use arrow keys) Ledger Public Key > Private Key (not recommended) Select Private Key with the cursor keys and press Enter . The next question is: Warning: You are connecting using your private key which is not recommended ? Enter Path to Private Key file (E.g. /home/wallet/pvtKeyFile): Enter the name and path to the file you and created in step 1 and press Enter . Then: ? Which network do you want to connect to? (Use arrow keys) > Flare (Mainnet) Coston2 (Testnet) LocalHost (for development only) Select Flare (Mainnet) and press Enter . Finally the main menu appears: ? What do you want to do? (Use arrow keys) View chain addresses > Check on-chain balance Get network info Get validator info Move assets from C-chain to P-chain Move assets from P-chain to C-chain Add a validator node As an example, choose Check on-chain balance , and press Enter . The balance of your selected account is shown for both the C-chain and the P-chain and the tool exits. You can follow the rest of this guide by selecting the Private Key option when prompted.","title":"Configuration"},{"location":"infra/validation/staking-cli/#staking-guide","text":"To stake on a validator node, you need to: Check your current P-chain balance. Move funds from the C-chain to the P-chain. Stake them on a validator. Optionally, check that the request has been recorded. Optionally, move the staked funds back to the C-chain once they become unlocked. Before you start During the process you will need three pieces of information. Take note of them before you start so you can follow the rest of the steps uninterrupted. The node ID of the validator you want to stake to. If you created the validator, its nodeID was shown to you during the deployment process . If you want to stake to somebody else's validator, you can: See the list of current validators on flaremetrics.io . Remember to add NodeID- before the ID shown on the page. Use flare-stake-tool info validators to get a JSON list of all validators. The desired staking start time and end time . When staking to an existing validator, both these times must be inside the period when the validator is active, which you can find on flaremetrics.io or again using flare-stake-tool info validators . You need to provide these times as a UNIX timestamp , so you might need to use an online conversion tool like Epoch Converter or the Linux date command. As an example, the 1693185095 timestamp corresponds to Monday, August 28, 2023 1:11:35 AM.","title":"Staking Guide"},{"location":"infra/validation/staking-cli/#1-check-your-balances","text":"Check your balance by executing flare-stake-tool interactive and selecting the Check on-chain balance option: ? How do you want to connect your wallet? Ledger You already have an existing Ctx file with the following parameters - Public Key: \u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf Network: flare Eth Address: 0x\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf ? Do you wish to continue with this? yes ? What do you want to do? Check on-chain balance Using network: flare Balances on the network \"flare\" C-chain 0x\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf: 100000.0 FLR P-chain P-flare\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf: 50000.0 FLR Your currently available funds on the C-chain and P-chain are shown in the last lines. Funds currently staked are locked and are not reflected in the P-chain balance. They will become automatically available when the staking period expires.","title":"1. Check your Balances"},{"location":"infra/validation/staking-cli/#2-move-funds-to-p-chain","text":"If your funds are already on the P-Chain, skip this step. Move the funds by executing flare-stake-tool interactive again and selecting the Move assets from C-chain to P-chain option. You are asked the amount of $FLR you want to transfer: ? What do you want to do? Move assets from C-chain to P-chain ? Enter amount (in FLR): 50000 Transaction Fees When transferring from the C-chain to the P-chain, transaction fees are wholly paid from the C-chain. Make sure you leave enough funds on the C-chain after the transfer, or it will fail. Transfers between chains are made of two operations: an export from the C-chain followed by an import to the P-chain. Therefore, you are asked to confirm TWO transactions on your hardware wallet. Please approve export transaction Using network: flare Fetching account from ledger... Creating export transaction... Using fee of 0.00028075 FLR Please review and sign the transaction on your ledger device... Sending transaction to the node... Transaction with id \u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf sent to the node Please approve import transaction Using network: flare Fetching account from ledger... Creating export transaction... Please review and sign the transaction on your ledger device... Sending transaction to the node... Transaction with id \u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf sent to the node Finished execution You can check your balances again to verify that the transfer was successful. If you encounter any problem, see the Troubleshooting section.","title":"2. Move Funds to P-Chain"},{"location":"infra/validation/staking-cli/#3-stake","text":"After you have funds on the P-chain, execute flare-stake-tool interactive again and select the appropriate option: If you are going to delegate to your own node (self-bonding), select Add a validator node . Otherwise, if you are going to stake to another node (delegation), select Delegate to a validator node . Press the down key a few times for this last option to show. First-time Address Registration The first time you use the Add a validator node or Delegate to a validator node options you are asked to sign an additional transaction. This step is required so that staking rewards accrued on the P-chain can be claimed on the C-chain and participate in the wider ecosystem. This procedure only needs to be done once per P-chain address and it progresses like this: Checking Address Registration... No address found for key 0x\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf Note: You need to register your wallet address before you can delegate your funds Please complete this registration transaction to proceed Submitting txn to the chain Cryptographical Background Both your P-chain and C-chain addresses are derived from the same public key, but the process is not symmetrical: public keys cannot be derived from addresses. Therefore, smart contracts have no way of knowing the P-chain address that corresponds to a given C-chain address, unless they are both provided by their owner. This step performs exactly this operation, allowing a C-chain address to claim rewards that were accrued by its P-chain counterpart. Manual Address Registration Should automatic registration through the Flare Stake CLI tool fail, you can still register your addresses manually using the Block Explorer: Retrieve the public key that generated the accounts you want to use. From a terminal, run flare-stake-tool info addresses and copy the long hexadecimal string starting with 0x in the last line. Using network: flare Addresses on the network \"flare\" P-chain address: P-flare\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf C-chain address hex: 0x\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf secp256k1 public key: 0x\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf You need to interact with the AddressBinder smart contract, so you must retrieve its address from the FlareContractRegistry as explained in the retrieving Contract Addresses page . Enter the address of the AddressBinder contract in the Block Explorer , and go to the Write Contract tab. Click on Connect Wallet . You do not need to use the same account as the one you are binding. Locate the registerPublicKey method and paste the public key from step 1 into the _publicKey field. Click on Write and confirm the transaction from your wallet. If the transaction is successful, your account's P and C-chain addresses are now bound. You then need to provide the following information: Amount to stake : With the restrictions stated above . Amount must be provided in FLR units. Validator's NodeID : As explained in the Before you start section . Start time : As explained in the Before you start section . End time : As explained in the Before you start section . If you selected Add a validator node , you have one more question to answer: Delegation fee : This is the percentage of all rewards that the node owner keeps. The rest is split proportionally between the self-bond and all delegators that contributed stake. 10 means 10%, so the maximum value is 100. ? What do you want to do? Add a validator node ? Enter amount (in FLR): 50000 ? Enter Node NodeId (E.g. NodeID-FQKTLuZHEsjCxPeFTFgsojsucmdyNDsz1): NodeID-\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf ? Enter start time(E.g. 1693185095): \u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf ? Enter end time(E.g. 1693185095): \u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf ? Enter delegation fee(E.g. 10): 10 You are then asked to confirm the staking transaction on your hardware wallet. Using network: flare Fetching account from ledger... Creating export transaction... Please review and sign the transaction on your ledger device... Sending transaction to the node... Transaction with id \u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf sent to the node Finished execution Your stake is now locked and will start accruing rewards after the configured start time arrives. When the end time arrives, the funds will be automatically unlocked. If you encounter any problem, see the Troubleshooting section.","title":"3. Stake"},{"location":"infra/validation/staking-cli/#4-check-stake","text":"You can double-check that the operation has been properly registered by looking at the current list of validators: flare-stake-tool info validators > validators.txt This creates a file called validators.txt . Open it and search for the line containing the P-chain address of your account. If you don't know it, use flare-stake-tool info addresses . If your account has stake on any node, you will find a section similar to: { \"txID\" : \"28Yf5yQ3xt9yaMvfZ1RP5jkCkT4y2pfD86UheZUHFVng2tFcWd\" , \"startTime\" : \"1688569201\" , \"endTime\" : \"1696345201\" , \"stakeAmount\" : \"16750000000000000\" , \"nodeID\" : \"NodeID-C6i8mruq11VdxGQ7tiUBgrRqoLBot86df\" , \"rewardOwner\" : { \"locktime\" : \"0\" , \"threshold\" : \"1\" , \"addresses\" : [ \"P-flare19c8zfml39x6efnw5j90nl85dmwdqhluwhrxz9g\" ] }, }, Check that the stakeAmount (in wei), nodeID , startTime , and endTime match the values you configured. If you have multiple active stakes, your address can show multiple times.","title":"4. Check Stake"},{"location":"infra/validation/staking-cli/#5-move-funds-back-to-c-chain","text":"Finally, you also have the option to move your P-chain funds back to the C-chain where they can participate in the wider ecosystem. You can only transfer P-chain funds that are not currently locked in any stake. Execute flare-stake-tool interactive and select the Move assets from P-chain to C-chain option. You are asked the amount of $FLR you want to transfer: ? What do you want to do? Move assets from P-chain to C-chain ? Enter amount (in FLR): 50000 Transaction Fees When transferring from the P to the C-chain, transaction fees are paid from BOTH chains. Make sure you leave enough funds on both chains after the transfer, or it will fail. Again, the transfer between the two chains require you to confirm TWO transactions on your hardware wallet. Please approve export transaction Using network: flare Fetching account from ledger... Creating export transaction... Please review and sign the transaction on your ledger device... Sending transaction to the node... Transaction with id \u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf sent to the node Please approve import transaction Using network: flare Fetching account from ledger... Creating export transaction... Using fee of 0.00028075 FLR Please review and sign the transaction on your ledger device... Sending transaction to the node... Transaction with id \u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf sent to the node Finished execution You can check your balances again to verify that the transfer was successful. If you encounter any problem, see the Troubleshooting section.","title":"5. Move funds back to C-Chain"},{"location":"infra/validation/staking-cli/#claiming-guide","text":"At the end of every reward epoch , participants are rewarded according to how well their chosen validator performed in that period. Rewards are accumulated in a dedicated smart contract and can be claimed from the Flare Stake CLI tool: Execute flare-stake-tool interactive and select the Claim Rewards option. Press the down key a few times for this option to show. You are shown the amount of pending rewards (in wei) and are asked how much you want to claim (in FLR): ? What do you want to do? Claim Rewards Checking your Rewards status... You have unclaimed rewards worth 1000000000000000000 ? Enter amount to claim (in FLR): 1 Next, select Receive with another wallet and enter the C-chain address where you want the rewards to be sent. This can be the same address from where you are staking. ? Where do you want to receive your rewards? Receive with another wallet ? Please enter the C-address where you want to receive your rewards: 0x\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf\u25cf You are then asked to confirm the staking transaction on your hardware wallet. Please sign the transaction on your ledger Submitting txn to the chain Rewards successfully claimed Finished execution Manual Reward Claiming Rewards can also be claimed directly from the ValidatorRewardManager contract that accumulates them: You need to interact with the ValidatorRewardManager smart contract, so you must retrieve its address from the FlareContractRegistry as explained in the retrieving Contract Addresses page . Enter the address of the ValidatorRewardManager contract in the Block Explorer , and go to the Write Contract tab. Click on Connect Wallet . You need to connect the account for which you are claiming. Locate the claim method and enter the following information: _rewardOwner : C-chain address that accrued the rewards. _recipient : Address where the rewards must be sent. _rewardAmount : Amount to claim. Find the pending amount using the getStateOfRewards method in the Read Contract tab. _wrap : Whether the rewards should be also wrapped, as a convenience. Click on Write and confirm the transaction from your wallet. If the transaction is successful, the reward is transferred to the specified recipient.","title":"Claiming Guide"},{"location":"infra/validation/staking-cli/#troubleshooting","text":"Cannot connect to Ledger device, No Device, Cannot retrieve addresses, or similar Make sure: The device is connected, the Avalanche app is opened, and it shows the \"Avalanche Ready\" message. No other application like Ledger Live or MetaMask is connected to the device. The device is not in stand-by mode. You are not running on Windows from a Linux terminal (WSL). Use a native Windows console instead. Insufficient funds Make sure enough funds will remain after a transaction to pay for the transaction fees. If too much time has elapsed between the transaction's creation and its confirmation on the Ledger, the calculated fee might be incorrect. Try the operation again. The network might be congested and the calculated fees might not be high enough. Try the operation again after a while. Import transaction failed and the funds have vanished Transfer operations require an export and an import transaction . If the export succeeds, but then the import fails, it looks like the funds have disappeared from both chains, but they are still retrievable. Repeat the failed import operation manually: If you are moving funds from the C-chain to the P-chain: flare-stake-tool transaction importCP --ledger --blind If you are moving funds from the P-chain to the C-chain: flare-stake-tool transaction importPC --ledger --blind Unsupported digital routines If you get the following error message: E: Error: error:0308010C:digital envelope routines::unsupported Make sure you are using the correct Node.js version, as advised in the Prerequisites section . You can find out the version of Node.js you are running with the following command: node --version","title":"Troubleshooting"},{"location":"tech/","text":"Flare Fundamentals # This section contains in-depth descriptions of Flare's key concepts, technology and tools. Select one of the topics below: What Is Flare? Automatic Claiming The FlareDrop Flare Beta Flare API Portal FTSO Governance Personal Delegation Accounts State Connector Validator Nodes Glossary Archive","title":"Flare Fundamentals"},{"location":"tech/#flare-fundamentals","text":"This section contains in-depth descriptions of Flare's key concepts, technology and tools. Select one of the topics below: What Is Flare? Automatic Claiming The FlareDrop Flare Beta Flare API Portal FTSO Governance Personal Delegation Accounts State Connector Validator Nodes Glossary Archive","title":"Flare Fundamentals"},{"location":"tech/api-portal/","text":"Flare API Portal # Flare's API Portal is a paid product that gives developers access to a number of private nodes running on different blockchains, including Flare, Songbird and Coston , but also other networks like Bitcoin or XRPL. These nodes are not rate-limited , so it is typically more convenient to connect your apps to them than to deploy your own nodes, or connect to public nodes. This is one more step towards Flare's goal to connect all blockchains . Visit Flare's API Portal website Visit the API Portal's FAQ if you are having authentication issues!","title":"Flare API Portal"},{"location":"tech/api-portal/#flare-api-portal","text":"Flare's API Portal is a paid product that gives developers access to a number of private nodes running on different blockchains, including Flare, Songbird and Coston , but also other networks like Bitcoin or XRPL. These nodes are not rate-limited , so it is typically more convenient to connect your apps to them than to deploy your own nodes, or connect to public nodes. This is one more step towards Flare's goal to connect all blockchains . Visit Flare's API Portal website Visit the API Portal's FAQ if you are having authentication issues!","title":"Flare API Portal"},{"location":"tech/automatic-claiming/","text":"Automatic Claiming # Automatic claiming enables users to appoint an executor to claim rewards on their behalf. Introduction # The Flare network rewards users that contribute to it, for example, by delegating to an FTSO data provider . Delegation rewards accrue every 3.5 days when users have delegated wrapped Flare tokens (WFLR) to FTSO data providers. These rewards must be claimed periodically by users, since rewards expire after a few months. For users, claiming rewards can be inconvenient and can risk losing rewards and compound interest if overlooked. If users are claiming rewards from a cold wallet, they can expose the wallet more often than necessary. Instead, users can enlist the services of executors to claim for them, putting the responsibility of remembering to claim on the executor. Automatic claiming through an executor saves user time and inconvenience, optimizes the opportunity for compound interest, and avoids unnecessary exposure of users' cold wallets. Automatic claiming is secure because the executor cannot claim to any address but the ones the user provides. It is trustless (does not require trust) because it is managed by a smart contract, not the executor. For executors, automatic claiming is an opportunity to earn a fee for performing claiming as a service to users. How Automatic Claiming Works # Without an executor, users need to claim twice a week if they want to benefit from the rewards as soon as possible. The claiming process without an executor. With an executor, a third party can claim for users, for an optional fee. The claiming process with an executor. There are two ways to claim with an executor: manual and registered. They both provide \"automatic claiming\" for the user in the sense that claiming rewards requires no intervention from the user once the executor takes over. However, when the executor does not register, several parts of the process are not automated, such as finding each other and paying the fee. The \"manual\" version is less automated. The registered version is highly automated. Manual Claiming Process # If an executor account is not registered, claiming is said to be Manual . With Manual claiming users only need to provide the executor's address, which authorizes the executor to claim on the user's behalf. How the user discovers the executor's address and whether they will pay a service fee can only be settled off-chain. Example For example, executors could create a dapp where users pay a fee (in fiat or spot) and sign the transaction that sets the executor's address. Only reward claiming remains automated, whereby rewards are sent directly to the user's address. Executors do not receive a fee automatically. Here is how the process works when executor claiming is manual: Users who have accrued rewards and want an executor to claim on their behalf can identify an executor known to them off-chain. These users then make an off-chain agreement with the executor and they exchange addresses. Agreeing to a fee is optional and off-chain. If they do agree to a fee, they pay manually. Executors claim rewards for one or more users. Their fees are not automatically deducted from the claimed rewards. Executors notify users off-chain if they discontinue providing this service. Registered Claiming Process # On the other hand, the process can be simplified if the executor address is Registered . Registration allows accounts to list themselves on-chain as registered executors and post their service fees. Registration simplifies both the user task of finding a suitable executor and the executor's task, since its fee is automatically transferred when user rewards are claimed. The users pay a fee to set an executor to claim their rewards and their rewards are claimed automatically, i.e., without their intervention. With a registered executor, all agreements happen on-chain. Here is how the registered claiming process works, with applications performing these actions on behalf of executors and users: Executors who want to make themselves publicly available to users register as executors, paying a registration fee. The fee to register as an executor is burned. Registered executors post their fee for claiming rewards. Users who have accrued rewards and want an executor to claim on their behalf can choose from the list of registered executors. These users pay a setup fee to enable a registered executor to claim their rewards. The fee to enable a registered executor is sent to the executor. Executors claim rewards for one or more users, and their fees are automatically deducted from the claimed rewards. Executors notify users off-chain if they discontinue providing this service. Throughout the process: Users and executors can see reports on which addresses executors are claiming for and which executors are registered. Registered executors can change fees or unregister, and users can change the registered executors claiming on their behalf or disable automatic claiming. Other Use Cases # Cold Wallets # Many users claim from a cold wallet because they can reap the most rewards where they store the greatest share of their holdings. When they claim from a cold wallet, they are exposing it online. Setting an executor can protect the cold wallet, as the executor would claim the rewards and pass them on to the user's account automatically without putting the cold wallet online. Your Own Executor # If a user has multiple addresses, it may be convenient to designate one of their own addresses as an executor, and claim for all of them from it. Additionally, this avoids the fee that a public executor will typically charge. Warning By using the automatic claiming feature, neither Flare Foundation nor any of the contracts published on the Flare network guarantee that the selected executor will actually claim any or all of the user\u2019s rewards. This agreement is solely between the user and the selected executor. The Flare network offers only the possibility of setting up an automatic execution service and is not liable for any damages if this service is not performed. For more information, see FLARE TERMS OF SERVICE & PRIVACY POLICY . Developing autoclaiming functionality For information on how to develop an executor, or how to write an application that supports autoclaiming, see Automatic Claiming in the Developer section. Related User Guides # Automatic claiming Related Developer Docs # Automatic claiming","title":"Automatic Claiming"},{"location":"tech/automatic-claiming/#automatic-claiming","text":"Automatic claiming enables users to appoint an executor to claim rewards on their behalf.","title":"Automatic Claiming"},{"location":"tech/automatic-claiming/#introduction","text":"The Flare network rewards users that contribute to it, for example, by delegating to an FTSO data provider . Delegation rewards accrue every 3.5 days when users have delegated wrapped Flare tokens (WFLR) to FTSO data providers. These rewards must be claimed periodically by users, since rewards expire after a few months. For users, claiming rewards can be inconvenient and can risk losing rewards and compound interest if overlooked. If users are claiming rewards from a cold wallet, they can expose the wallet more often than necessary. Instead, users can enlist the services of executors to claim for them, putting the responsibility of remembering to claim on the executor. Automatic claiming through an executor saves user time and inconvenience, optimizes the opportunity for compound interest, and avoids unnecessary exposure of users' cold wallets. Automatic claiming is secure because the executor cannot claim to any address but the ones the user provides. It is trustless (does not require trust) because it is managed by a smart contract, not the executor. For executors, automatic claiming is an opportunity to earn a fee for performing claiming as a service to users.","title":"Introduction"},{"location":"tech/automatic-claiming/#how-automatic-claiming-works","text":"Without an executor, users need to claim twice a week if they want to benefit from the rewards as soon as possible. The claiming process without an executor. With an executor, a third party can claim for users, for an optional fee. The claiming process with an executor. There are two ways to claim with an executor: manual and registered. They both provide \"automatic claiming\" for the user in the sense that claiming rewards requires no intervention from the user once the executor takes over. However, when the executor does not register, several parts of the process are not automated, such as finding each other and paying the fee. The \"manual\" version is less automated. The registered version is highly automated.","title":"How Automatic Claiming Works"},{"location":"tech/automatic-claiming/#manual-claiming-process","text":"If an executor account is not registered, claiming is said to be Manual . With Manual claiming users only need to provide the executor's address, which authorizes the executor to claim on the user's behalf. How the user discovers the executor's address and whether they will pay a service fee can only be settled off-chain. Example For example, executors could create a dapp where users pay a fee (in fiat or spot) and sign the transaction that sets the executor's address. Only reward claiming remains automated, whereby rewards are sent directly to the user's address. Executors do not receive a fee automatically. Here is how the process works when executor claiming is manual: Users who have accrued rewards and want an executor to claim on their behalf can identify an executor known to them off-chain. These users then make an off-chain agreement with the executor and they exchange addresses. Agreeing to a fee is optional and off-chain. If they do agree to a fee, they pay manually. Executors claim rewards for one or more users. Their fees are not automatically deducted from the claimed rewards. Executors notify users off-chain if they discontinue providing this service.","title":"Manual Claiming Process"},{"location":"tech/automatic-claiming/#registered-claiming-process","text":"On the other hand, the process can be simplified if the executor address is Registered . Registration allows accounts to list themselves on-chain as registered executors and post their service fees. Registration simplifies both the user task of finding a suitable executor and the executor's task, since its fee is automatically transferred when user rewards are claimed. The users pay a fee to set an executor to claim their rewards and their rewards are claimed automatically, i.e., without their intervention. With a registered executor, all agreements happen on-chain. Here is how the registered claiming process works, with applications performing these actions on behalf of executors and users: Executors who want to make themselves publicly available to users register as executors, paying a registration fee. The fee to register as an executor is burned. Registered executors post their fee for claiming rewards. Users who have accrued rewards and want an executor to claim on their behalf can choose from the list of registered executors. These users pay a setup fee to enable a registered executor to claim their rewards. The fee to enable a registered executor is sent to the executor. Executors claim rewards for one or more users, and their fees are automatically deducted from the claimed rewards. Executors notify users off-chain if they discontinue providing this service. Throughout the process: Users and executors can see reports on which addresses executors are claiming for and which executors are registered. Registered executors can change fees or unregister, and users can change the registered executors claiming on their behalf or disable automatic claiming.","title":"Registered Claiming Process"},{"location":"tech/automatic-claiming/#other-use-cases","text":"","title":"Other Use Cases"},{"location":"tech/automatic-claiming/#cold-wallets","text":"Many users claim from a cold wallet because they can reap the most rewards where they store the greatest share of their holdings. When they claim from a cold wallet, they are exposing it online. Setting an executor can protect the cold wallet, as the executor would claim the rewards and pass them on to the user's account automatically without putting the cold wallet online.","title":"Cold Wallets"},{"location":"tech/automatic-claiming/#your-own-executor","text":"If a user has multiple addresses, it may be convenient to designate one of their own addresses as an executor, and claim for all of them from it. Additionally, this avoids the fee that a public executor will typically charge. Warning By using the automatic claiming feature, neither Flare Foundation nor any of the contracts published on the Flare network guarantee that the selected executor will actually claim any or all of the user\u2019s rewards. This agreement is solely between the user and the selected executor. The Flare network offers only the possibility of setting up an automatic execution service and is not liable for any damages if this service is not performed. For more information, see FLARE TERMS OF SERVICE & PRIVACY POLICY . Developing autoclaiming functionality For information on how to develop an executor, or how to write an application that supports autoclaiming, see Automatic Claiming in the Developer section.","title":"Your Own Executor"},{"location":"tech/automatic-claiming/#related-user-guides","text":"Automatic claiming","title":"Related User Guides"},{"location":"tech/automatic-claiming/#related-developer-docs","text":"Automatic claiming","title":"Related Developer Docs"},{"location":"tech/flare-beta/","text":"Flare Beta # Decentralization will be achieved by moving the transaction validation duty from the Flare Foundation to community-run FTSO data providers , but this will not happen instantly. Instead, to ensure a safe transition, a number of professional validators were initially enabled and continue to be employed. The professional validators were chosen among companies with proven experience running blockchain infrastructure and at first held most of the validation power . This power, though, will be progressively shifted onto the community-run validators until they run the network on their own. This initial period is called Flare Beta , and it will span several launch phases . Flare Beta Details # The Flare Beta began at the same time as the token distribution event (TDE). During this period: 20 total validators with equal validation power (20K FLR each, initially) are enabled. 4 run by the Flare Foundation. 16 run by 4 professional validators. Each FTSO running an observation node will be a candidate to become a validator node later. These nodes are regularly scanned to ensure they meet security standards. If they meet the security standards, they enable the node operators to receive rewards. Validator rewards are split 50% for the professional validators and 50% for the FTSOs running observation nodes. Estimated duration: 6 - 9 months, depending on the evolution of the network.","title":"Flare Beta"},{"location":"tech/flare-beta/#flare-beta","text":"Decentralization will be achieved by moving the transaction validation duty from the Flare Foundation to community-run FTSO data providers , but this will not happen instantly. Instead, to ensure a safe transition, a number of professional validators were initially enabled and continue to be employed. The professional validators were chosen among companies with proven experience running blockchain infrastructure and at first held most of the validation power . This power, though, will be progressively shifted onto the community-run validators until they run the network on their own. This initial period is called Flare Beta , and it will span several launch phases .","title":"Flare Beta"},{"location":"tech/flare-beta/#flare-beta-details","text":"The Flare Beta began at the same time as the token distribution event (TDE). During this period: 20 total validators with equal validation power (20K FLR each, initially) are enabled. 4 run by the Flare Foundation. 16 run by 4 professional validators. Each FTSO running an observation node will be a candidate to become a validator node later. These nodes are regularly scanned to ensure they meet security standards. If they meet the security standards, they enable the node operators to receive rewards. Validator rewards are split 50% for the professional validators and 50% for the FTSOs running observation nodes. Estimated duration: 6 - 9 months, depending on the evolution of the network.","title":"Flare Beta Details"},{"location":"tech/flare/","text":"What Is Flare? # Flare is the blockchain for data. It is a layer 1 , EVM smart contract platform designed to expand the utility of blockchain. Flare's aim is to provide data as a public good, meaning that data is not controlled by a centralized entity and is available to all. The infrastructure providers, which perform doubly as validators and data providers , enable two native oracles, the FTSO and the State Connector . This native processing provides developers on Flare with efficient access to large amounts of data and data proofs at minimal cost. By giving developers trustless access to the broadest range of data, Flare can advance the development of more blockchain use cases where data is important, such as in DeFi, gaming, NFT, music, and social networks. Flare Protocols # Flare has the following native data acquisition protocols at these stages of development: The Flare Time-Series Oracle (FTSO) provides continuous estimations of changing data, such as price pairs. The State Connector allows querying of verifiable, non-changing data from other chains and the internet. Flare LayerCake is being developed by Flare Labs to provide a decentralized, trustless bridging system between smart contract networks. For an overview of trustless bridges, see LayerCake . Developing on Flare # Flare developers can work in a familiar Ethereum-like environment. It offers the same API and uses the Ethereum Virtual Machine ( EVM ), so Ethereum's Solidity smart contracts can be used directly. Like Ethereum, Flare supports other assets, such as NFTs . See Developer Docs . The Flare native currency, $FLR , works the same as $ETH on the Ethereum blockchain. For those contracts that can only work with ERC-20 tokens, $FLR can be easily wrapped as $WFLR , which is an ERC-20 representation of $FLR . Flare's FTSO delegation and Flare governance are examples of such apps. Common blockchain tools like wallets , a token management portal , and block explorers are available on Flare. Flare is actively seeking developers eager to discover what new utility can be brought to the blockchain industry when acquiring data is possible in a decentralized way. To start, since Flare is EVM-compatible, you can migrate Ethereum smart-contract dapps to Flare. Then consider, for example, creating DeFi, gaming, NFT, music, or social network dapps. See Start Building , for more information. Flare Networks # Flare has 4 networks with different purposes: Flare is the main network , where $FLR is the native currency. Songbird is the canary network , where $SGB is the native currency. Created with users in mind, it is meant for testing features under \"real fire\" conditions, before deploying them on the main network. Coston is Songbird's public test network , created with developers in mind. Coston2 is Flare's public test network , created with developers in mind. General feature adoption flow. Flare Chains # Flare uses two chains and is developing a built-in interoperability mechanism between them. C-Chain: The contract chain that is used for smart contracts. It is where the Ethereum Virtual Machine operates, and is the chain where the vast bulk of the community currently interact. P-Chain: The platform chain that accommodates staking and provides rewards to its validators.","title":"What Is Flare?"},{"location":"tech/flare/#what-is-flare","text":"Flare is the blockchain for data. It is a layer 1 , EVM smart contract platform designed to expand the utility of blockchain. Flare's aim is to provide data as a public good, meaning that data is not controlled by a centralized entity and is available to all. The infrastructure providers, which perform doubly as validators and data providers , enable two native oracles, the FTSO and the State Connector . This native processing provides developers on Flare with efficient access to large amounts of data and data proofs at minimal cost. By giving developers trustless access to the broadest range of data, Flare can advance the development of more blockchain use cases where data is important, such as in DeFi, gaming, NFT, music, and social networks.","title":"What Is Flare?"},{"location":"tech/flare/#flare-protocols","text":"Flare has the following native data acquisition protocols at these stages of development: The Flare Time-Series Oracle (FTSO) provides continuous estimations of changing data, such as price pairs. The State Connector allows querying of verifiable, non-changing data from other chains and the internet. Flare LayerCake is being developed by Flare Labs to provide a decentralized, trustless bridging system between smart contract networks. For an overview of trustless bridges, see LayerCake .","title":"Flare Protocols"},{"location":"tech/flare/#developing-on-flare","text":"Flare developers can work in a familiar Ethereum-like environment. It offers the same API and uses the Ethereum Virtual Machine ( EVM ), so Ethereum's Solidity smart contracts can be used directly. Like Ethereum, Flare supports other assets, such as NFTs . See Developer Docs . The Flare native currency, $FLR , works the same as $ETH on the Ethereum blockchain. For those contracts that can only work with ERC-20 tokens, $FLR can be easily wrapped as $WFLR , which is an ERC-20 representation of $FLR . Flare's FTSO delegation and Flare governance are examples of such apps. Common blockchain tools like wallets , a token management portal , and block explorers are available on Flare. Flare is actively seeking developers eager to discover what new utility can be brought to the blockchain industry when acquiring data is possible in a decentralized way. To start, since Flare is EVM-compatible, you can migrate Ethereum smart-contract dapps to Flare. Then consider, for example, creating DeFi, gaming, NFT, music, or social network dapps. See Start Building , for more information.","title":"Developing on Flare"},{"location":"tech/flare/#flare-networks","text":"Flare has 4 networks with different purposes: Flare is the main network , where $FLR is the native currency. Songbird is the canary network , where $SGB is the native currency. Created with users in mind, it is meant for testing features under \"real fire\" conditions, before deploying them on the main network. Coston is Songbird's public test network , created with developers in mind. Coston2 is Flare's public test network , created with developers in mind. General feature adoption flow.","title":"Flare Networks"},{"location":"tech/flare/#flare-chains","text":"Flare uses two chains and is developing a built-in interoperability mechanism between them. C-Chain: The contract chain that is used for smart contracts. It is where the Ethereum Virtual Machine operates, and is the chain where the vast bulk of the community currently interact. P-Chain: The platform chain that accommodates staking and provides rewards to its validators.","title":"Flare Chains"},{"location":"tech/ftso/","text":"FTSO # The Flare Time Series Oracle (FTSO) is a smart contract running on the Flare network that provides continuous estimations for different types of data . It does so in a decentralized manner (no single party is in control of the process) and securely (it takes a lot of effort to disrupt the process). To achieve a secure, decentralized system, a set of independent data providers retrieves data from external sources, like centralized and decentralized exchanges, and supplies the data to the FTSO system. Then, this information is weighted according to each provider's vote power , and a median is calculated to produce the final estimate. Important When FTSOs were initially designed, they supported only cryptocurrency price pairs. Now, they support all types of data. However, contract names and methods still refer to prices and price epochs, and price pairs are used in the following information to show how FTSOs work. The following diagram shows how price pairs are submitted to and filtered by the FTSO system. FTSO summary. Data providers that supply useful information , such as price pairs that are not removed as outliers because they are too far away from the median value, are rewarded , and the resulting data estimates are finally published on-chain . The following information describes: The FTSO workflow How results are calculated Vote power Delegation How developers can submit data , claim rewards , and use the data in an app Procedure Overview # Using price data as an example, the procedure in the following diagram runs continuously. It produces new data estimates during every price epoch , which is 3 minutes long . FTSO workflow. Any user with an account (address) on the Flare network can act as an FTSO data provider, submit data , and collect rewards . During each epoch, only submissions from the 100 data providers with the most vote power are considered. An account's vote power is based on its wrapped $FLR or $SGB balance and the delegations made to it (see Vote Power below). Submitted data must be the current price (in $USD ) for one or more of the supported price pairs, currently: $ADA , $ALGO , $ARB , $AVAX , $BNB , $BTC , $DOGE , $ETH , $FIL , $FLR , $LTC , $MATIC , $SOL , $USDC , $USDT , $XDC , $XLM , and $XRP . On Songbird, replace $FLR with $SGB . More general data types might be added in the future. FTSO data providers submit data in rounds in a commit-and-reveal process, so they cannot see each other's submissions until a round is over. This process is like submitting data in a closed envelope, and when the round is over, all envelopes are opened. During a 3-minute price epoch, providers fetch the information, run their algorithms, and submit a hash of the data ( commit ). Then, during the first half of the following price epoch ( 1.5 minutes ), providers submit the actual data ( reveal ). See technical details about the data-submission process below. The FTSO system calculates the resulting median , taking into account each provider's vote power (see How Results are Calculated below). Results are publicly available for 5 price epochs for any app or contract to read. Previous epochs can always be retrieved from an archival node. For each price epoch in which the submitted data is close enough to the median value, data providers and their delegators are rewarded . Rewards are accumulated in reward epochs , which last 3.5 days on the Flare network and 7 days on Songbird, and you can claim them after the epoch finishes. See Rewards below. How Results are Calculated # The following example uses price pairs to show the filtering process that turns all submitted data into a single estimate. See all details in the Flare whitepaper . FTSO price calculation. The contract in charge of each price pair calculates the resulting price for a price epoch using the submissions received from all data providers during that epoch. Price epochs are 3 minutes long. Each submission has a price and a weight . Weight is based on the data provider's vote power , as explained below. The weighted median of the prices is the resulting price for the price epoch. Submissions in the top and bottom 25% range are not rewarded . Vote Power # FTSO delegation weight calculation. As explained above, an FTSO data provider's submissions are weighted by its vote power . A data provider's vote power is proportional to the amount of wrapped Flare or Songbird tokens ( $WFLR or $WSGB ) it holds, plus any amount delegated to it . A data provider's influence is limited A vote-power cap limits the influence of individual data providers to 2.5% of the total vote power on both Flare and Songbird. Any vote power above this cap is ignored. If vote power exceeds the limit, consider delegating those $WFLR or $WSGB to a different data provider. A snapshot of each data provider's vote power is taken once per reward epoch, and the resulting weight is then used throughout the next reward epoch . The actual snapshot block is called the vote-power block , and it is randomly chosen from the last blocks of the previous epoch. On Flare, the vote-power block is randomly chosen from roughly the last 50% of the blocks, and on Songbird, it is randomly chosen from roughly the last 25%. The random selection only roughly corresponds to the last 50% or 25% of the time because block production times are not constant. Reward epochs The first reward epoch on Songbird started on Saturday, 18 September 2021 08:41:39 (GMT), 1631954499 in Unix time and repeats every 7 days. Therefore, all Songbird reward epochs start on Saturday morning (GMT) . The first reward epoch on Flare started on Thursday, 21 July 2022 19:00:05 (GMT), 1658430005 in Unix time and repeats every 3.5 days. Therefore, all Flare reward epochs start on Thursday evening (GMT) and Monday morning (GMT) . Delegation # If you hold $FLR or $SGB tokens, you can delegate them to an FTSO data provider to increase its vote power and earn a share of its rewards , resulting in a mutually beneficial arrangement . When you delegate your vote power, you not only earn rewards but also support reliable data providers, which strengthens the stability of the FTSO and the whole ecosystem. Before you can delegate your native $FLR and $SGB tokens, you must wrap these tokens into ERC-20 $WFLR and $WSGB tokens, an operation you can reverse at any time. After you wrap your tokens, you will have the vote power that is equivalent to the wrapped token balance, and you can delegate 100% of this vote power to 1 or 2 data providers. Delegating 100% of your vote power to reliable data providers committed to providing accurate data maximizes your rewards and enhances the stability of the ecosystem. The reward rate (for advanced users) As you explore data providers, consider the expected reward rate each one offers. The reward rate describes how many tokens were earned by a data provider during a reward epoch for every 100 tokens delegated. The reward rate is calculated as \\(total\\_reward / vote\\_power * (100 - fee)\\) , where: \\(total\\_reward\\) : All accumulated rewards for the data provider and its delegators in the reward epoch. \\(vote\\_power\\) : All the data provider's $WFLR and all the $WFLR delegated to it in the vote-power block selected for the reward epoch. \\(fee\\) : The amount kept by the data provider as compensation for the service it provides. The value is specified as a percentage. For example, if the data provider's fee is 21.3%, specify 21.3 to calculate the reward rate. Because rewards are distributed in units of $FLR , the reward rate is calculated in units of $FLR . For the duration of the delegation, you will earn rewards that are commensurate with vote power and the performance of the chosen data providers. Rewards accumulate, and they become claimable for each reward epoch that is finalized. Inflation is distributed to everyone who participates in the FTSO system, which includes data providers and entities that delegate their vote power to the data providers. Delegated tokens are not locked , meaning that they remain in the user's control and the delegation can be removed at any time. Any $WFLR or $WSGB that is newly wrapped, sent, or received will automatically update your actual delegated vote power. However, if you receive native tokens, you must wrap them before you contribute to existing delegations. Immediate Delegation Revocation # Sometimes, a data provider might maliciously attack the FTSO system to skew the reported data. If this type of attack occurs, the vote power of a data provider can be revoked immediately instead of in the next reward epoch. In this situation, an off-chain process, such as a Twitter storm, calls for users to revoke vote power from the data provider that has attacked the system. When vote power is revoked, the revocation occurs immediately. Learn how to perform this operation from the block explorer. Effects of the Vote-Power Block Snapshot on Delegations # The following table shows when new, changed, and revoked delegations take effect in relation to the vote-power block snapshot. Delegation Type Before or After Vote-Power Block Snapshot When Delegation Takes Effect New or changed Before In the next reward epoch After After the next reward epoch ends Revoked N/A Immediately Delegation Procedure # You can delegate your tokens using the Flare Portal , a supported wallet like Bifrost , or a dapp . Some FTSO data providers have already started providing these dapps as a convenience. Take a look at flaremetrics.io and pick the one you prefer. If you are an advanced user, you can delegate manually by interacting directly with the FTSO smart contracts. Rewards # A percentage of the annual network inflation is reserved to reward FTSO data providers and distributed uniformly among the year's reward epochs. The mechanism that distributes rewards to data providers consists of several bands: Primary reward band : This band rewards 50% of submitted data, weighted by vote power and centered around the median price . That is, the primary reward band fixes the rewarded vote power at 50%, which makes the width of the primary reward band in each epoch variable. Secondary reward band : This band rewards submitted data that falls within a fixed percentage around the calculated median . That is, the width of the secondary reward band is fixed, which makes the rewarded vote power in each epoch variable. Submitted data in each reward epoch belongs to one of the following: Primary reward band Primary and secondary reward band Neither reward band On Flare, reward epochs are 3.5 days. On Songbird, reward epochs are 7 days. In each reward epoch, rewards are distributed to providers whose submission falls within the primary or secondary reward bands. Because the secondary reward band is wider, it rewards more data providers than the primary band. However, submissions still must be close enough to the median to be included. If a submission falls within both bands, it receives both rewards because each reward band is independent. The secondary reward band receives 30% of all FTSO rewards, and the primary reward band receives the remaining 70%. As the FTSO system evolves, these reward percentages might be revised later, in accordance with an accepted proposal that requests changes to the secondary reward band. After the band rewards are distributed, each provider can take an optional, configurable fee , which is set to 20% by default, and distributes the rest of the reward among all contributors to its vote power , i.e., itself and all its delegators, according to the delegated amounts. If you delegated to a data provider, the amount of your rewards depends on multiple factors: The percentage of vote power you delegated The data providers to which you delegated your vote power The performance of those data providers The fee charged by those data providers Whether the total vote power of one or both of those data providers exceeded the vote power cap You can claim your rewards at the end of each reward epoch. You must claim your rewards within 90 days of their availability. After 90 days, unclaimed rewards on Flare are burned, and on Songbird, they are reallocated. Reward-Claiming Procedure # FTSO rewards are not automatically transferred to their recipients. Instead, the amounts are accumulated in a contract, as described in the System Architecture , and must be claimed once the reward epoch is finished . You can claim your rewards using the Flare Portal , a supported wallet like Bifrost , or a dapp . Take a look at flaremetrics.io and pick the one you prefer. If you are an advanced user, you can claim manually by interacting directly with the FTSO smart contracts. To save on gas costs, rewards from multiple reward epochs are claimed simultaneously when you use the Portal. However, be aware that rewards expire after 90 days . Moreover, you probably want to claim soon, to redelegate the received amount and obtain compounded rewards. It is also worth noting that: Rewards are paid in the network's native currency. On Flare, the native token is $FLR , and on Songbird, the native token is $SGB . Data providers and their delegators must claim independently. Technical Details # This section is aimed at developers. System Architecture # The FTSO system is composed of multiple smart contracts running on the Flare Network. Using prices as an example, the following diagram shows the flow of data, queries, and rewards through the FTSO system: FTSO component smart contracts. The following list describes the most relevant contracts and their purposes: FTSO : Each data type is handled by its own FTSO contract, including calculation of the filtered feed. To retrieve information about a data type, access this contract. Note If an FTSO contract is redeployed (for example, to fix a bug), its address will change and apps using it will need to be updated. The FTSO Registry contract below tracks this change for you. You can retrieve the addresses of all FTSO contracts using the getAllFtsos method in the FTSO Registry. FTSO Registry : Aggregates the output of each individual FTSO contract and provides a convenient one-stop API to retrieve all data. Price Submitter : This contract is used by the FTSO data providers to submit their data. Although the contract is called PriceSubmitter , data is not limited to prices. Reward Manager : Use this contract to claim your rewards, whether you are a data provider or a delegator. Wrapped Native (WNat) : This contract is not exclusively related to the FTSO system, but it is required to wrap and unwrap native tokens into the $WFLR and $WSGB that delegation requires. Note The Contract Addresses page explains how to securely retrieve each contract's address. Other contracts, like the FTSO Manager or the FTSO Daemon, are only meant for internal use by the FTSO system. Manual Delegation and Claiming # The following graphic shows the delegation process. You can call methods in several different smart contracts to manually delegate vote power and claim rewards . FTSO delegation process summary. Data-Submission Process # Data submission uses a commit-and-reveal scheme to prevent providers from viewing each other's submissions until a round is over. To speed up the process, both phases are actually overlapped so: All Commit phases happen continuously in so-called 3-minute Price Epochs . Reveal phases happen during the first half ( first 90 seconds ) of the following Commit phase. The published price information is therefore updated every 3 minutes . Only a hash of the data is submitted during the Commit phase. Next, in the Reveal phase the actual data is sent. If its hash does not match the previous commitment, the data is discarded. The submission API is slightly different for the Flare and Songbird networks: Flare Songbird FTSO data providers submit data through the PriceSubmitter contract . Commit : A single hash is needed for each submission. function submitHash ( uint256 _epochId , bytes32 _hash ) external ; Reveal : After all data is submitted, a single random number must be submitted. function revealPrices ( uint256 _epochId , uint256 [] memory _ftsoIndices , uint256 [] memory _prices , uint256 _random ) external ; FTSO data providers submit data through the PriceSubmitter contract . Commit : A separate hash is needed for each submission. function submitPriceHashes ( uint256 _epochId , uint256 [] memory _ftsoIndices , bytes32 [] memory _hashes ) external ; Reveal : Along with each data submission, a random number must be submitted too. function revealPrices ( uint256 _epochId , uint256 [] memory _ftsoIndices , uint256 [] memory _prices , uint256 [] memory _randoms ) external ; Retrieving Data # Data produced by the FTSO is publicly available on the Flare and Songbird networks. All data can be retrieved either through the FtsoRegistry contract or directly through one of the Ftso contracts. In any case, using the getCurrentPriceWithDecimals method is recommended. The following examples show how to use this method to retrieve price data. Retrieve by pair index Retrieve by pair symbol Retrieve directly From the FtsoRegistry contract: function getCurrentPriceWithDecimals ( uint256 _ftsoIndex ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Where _ftsoIndex is one of the allowed indices returned by getSupportedIndices , for example. From the FtsoRegistry contract: function getCurrentPriceWithDecimals ( string memory _symbol ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Where _symbol is one of the allowed symbols returned by getSupportedSymbols , for example. First you need to obtain the address of the Ftso contract managing the price pair you are interested in. You can use getSupportedIndicesSymbolsAndFtsos from the FtsoRegistry , for example. Then call getCurrentPriceWithDecimals on the FTSO directly: function getCurrentPriceWithDecimals ( ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Note Individual FTSO contracts might be updated periodically, which will change their addresses. Instead of caching these addresses, use the FtsoRegistry . GetCurrentPriceWithDecimals returns the requested price (the outcome of the previous 3-minute price epoch) in $USD shifting the comma by the amount of decimal places returned in _assetPriceUsdDecimals . That is, the actual price is _price * 10 - _assetPriceUsdDecimals . For example, a return value of 2603 with _assetPriceUsdDecimals of 5 means a price of 0.02603 USD (There are only 5 significant decimal places). A standard Unix timestamp of the last price update is also returned. Related User Guides # Managing delegations Managing rewards Wrapping tokens Related Infrastructure Guides # Operating a Data Provider Working with Whitelists Managing the Ecosystem","title":"FTSO"},{"location":"tech/ftso/#ftso","text":"The Flare Time Series Oracle (FTSO) is a smart contract running on the Flare network that provides continuous estimations for different types of data . It does so in a decentralized manner (no single party is in control of the process) and securely (it takes a lot of effort to disrupt the process). To achieve a secure, decentralized system, a set of independent data providers retrieves data from external sources, like centralized and decentralized exchanges, and supplies the data to the FTSO system. Then, this information is weighted according to each provider's vote power , and a median is calculated to produce the final estimate. Important When FTSOs were initially designed, they supported only cryptocurrency price pairs. Now, they support all types of data. However, contract names and methods still refer to prices and price epochs, and price pairs are used in the following information to show how FTSOs work. The following diagram shows how price pairs are submitted to and filtered by the FTSO system. FTSO summary. Data providers that supply useful information , such as price pairs that are not removed as outliers because they are too far away from the median value, are rewarded , and the resulting data estimates are finally published on-chain . The following information describes: The FTSO workflow How results are calculated Vote power Delegation How developers can submit data , claim rewards , and use the data in an app","title":"FTSO"},{"location":"tech/ftso/#procedure-overview","text":"Using price data as an example, the procedure in the following diagram runs continuously. It produces new data estimates during every price epoch , which is 3 minutes long . FTSO workflow. Any user with an account (address) on the Flare network can act as an FTSO data provider, submit data , and collect rewards . During each epoch, only submissions from the 100 data providers with the most vote power are considered. An account's vote power is based on its wrapped $FLR or $SGB balance and the delegations made to it (see Vote Power below). Submitted data must be the current price (in $USD ) for one or more of the supported price pairs, currently: $ADA , $ALGO , $ARB , $AVAX , $BNB , $BTC , $DOGE , $ETH , $FIL , $FLR , $LTC , $MATIC , $SOL , $USDC , $USDT , $XDC , $XLM , and $XRP . On Songbird, replace $FLR with $SGB . More general data types might be added in the future. FTSO data providers submit data in rounds in a commit-and-reveal process, so they cannot see each other's submissions until a round is over. This process is like submitting data in a closed envelope, and when the round is over, all envelopes are opened. During a 3-minute price epoch, providers fetch the information, run their algorithms, and submit a hash of the data ( commit ). Then, during the first half of the following price epoch ( 1.5 minutes ), providers submit the actual data ( reveal ). See technical details about the data-submission process below. The FTSO system calculates the resulting median , taking into account each provider's vote power (see How Results are Calculated below). Results are publicly available for 5 price epochs for any app or contract to read. Previous epochs can always be retrieved from an archival node. For each price epoch in which the submitted data is close enough to the median value, data providers and their delegators are rewarded . Rewards are accumulated in reward epochs , which last 3.5 days on the Flare network and 7 days on Songbird, and you can claim them after the epoch finishes. See Rewards below.","title":"Procedure Overview"},{"location":"tech/ftso/#how-results-are-calculated","text":"The following example uses price pairs to show the filtering process that turns all submitted data into a single estimate. See all details in the Flare whitepaper . FTSO price calculation. The contract in charge of each price pair calculates the resulting price for a price epoch using the submissions received from all data providers during that epoch. Price epochs are 3 minutes long. Each submission has a price and a weight . Weight is based on the data provider's vote power , as explained below. The weighted median of the prices is the resulting price for the price epoch. Submissions in the top and bottom 25% range are not rewarded .","title":"How Results are Calculated"},{"location":"tech/ftso/#vote-power","text":"FTSO delegation weight calculation. As explained above, an FTSO data provider's submissions are weighted by its vote power . A data provider's vote power is proportional to the amount of wrapped Flare or Songbird tokens ( $WFLR or $WSGB ) it holds, plus any amount delegated to it . A data provider's influence is limited A vote-power cap limits the influence of individual data providers to 2.5% of the total vote power on both Flare and Songbird. Any vote power above this cap is ignored. If vote power exceeds the limit, consider delegating those $WFLR or $WSGB to a different data provider. A snapshot of each data provider's vote power is taken once per reward epoch, and the resulting weight is then used throughout the next reward epoch . The actual snapshot block is called the vote-power block , and it is randomly chosen from the last blocks of the previous epoch. On Flare, the vote-power block is randomly chosen from roughly the last 50% of the blocks, and on Songbird, it is randomly chosen from roughly the last 25%. The random selection only roughly corresponds to the last 50% or 25% of the time because block production times are not constant. Reward epochs The first reward epoch on Songbird started on Saturday, 18 September 2021 08:41:39 (GMT), 1631954499 in Unix time and repeats every 7 days. Therefore, all Songbird reward epochs start on Saturday morning (GMT) . The first reward epoch on Flare started on Thursday, 21 July 2022 19:00:05 (GMT), 1658430005 in Unix time and repeats every 3.5 days. Therefore, all Flare reward epochs start on Thursday evening (GMT) and Monday morning (GMT) .","title":"Vote Power"},{"location":"tech/ftso/#delegation","text":"If you hold $FLR or $SGB tokens, you can delegate them to an FTSO data provider to increase its vote power and earn a share of its rewards , resulting in a mutually beneficial arrangement . When you delegate your vote power, you not only earn rewards but also support reliable data providers, which strengthens the stability of the FTSO and the whole ecosystem. Before you can delegate your native $FLR and $SGB tokens, you must wrap these tokens into ERC-20 $WFLR and $WSGB tokens, an operation you can reverse at any time. After you wrap your tokens, you will have the vote power that is equivalent to the wrapped token balance, and you can delegate 100% of this vote power to 1 or 2 data providers. Delegating 100% of your vote power to reliable data providers committed to providing accurate data maximizes your rewards and enhances the stability of the ecosystem. The reward rate (for advanced users) As you explore data providers, consider the expected reward rate each one offers. The reward rate describes how many tokens were earned by a data provider during a reward epoch for every 100 tokens delegated. The reward rate is calculated as \\(total\\_reward / vote\\_power * (100 - fee)\\) , where: \\(total\\_reward\\) : All accumulated rewards for the data provider and its delegators in the reward epoch. \\(vote\\_power\\) : All the data provider's $WFLR and all the $WFLR delegated to it in the vote-power block selected for the reward epoch. \\(fee\\) : The amount kept by the data provider as compensation for the service it provides. The value is specified as a percentage. For example, if the data provider's fee is 21.3%, specify 21.3 to calculate the reward rate. Because rewards are distributed in units of $FLR , the reward rate is calculated in units of $FLR . For the duration of the delegation, you will earn rewards that are commensurate with vote power and the performance of the chosen data providers. Rewards accumulate, and they become claimable for each reward epoch that is finalized. Inflation is distributed to everyone who participates in the FTSO system, which includes data providers and entities that delegate their vote power to the data providers. Delegated tokens are not locked , meaning that they remain in the user's control and the delegation can be removed at any time. Any $WFLR or $WSGB that is newly wrapped, sent, or received will automatically update your actual delegated vote power. However, if you receive native tokens, you must wrap them before you contribute to existing delegations.","title":"Delegation"},{"location":"tech/ftso/#immediate-delegation-revocation","text":"Sometimes, a data provider might maliciously attack the FTSO system to skew the reported data. If this type of attack occurs, the vote power of a data provider can be revoked immediately instead of in the next reward epoch. In this situation, an off-chain process, such as a Twitter storm, calls for users to revoke vote power from the data provider that has attacked the system. When vote power is revoked, the revocation occurs immediately. Learn how to perform this operation from the block explorer.","title":"Immediate Delegation Revocation"},{"location":"tech/ftso/#effects-of-the-vote-power-block-snapshot-on-delegations","text":"The following table shows when new, changed, and revoked delegations take effect in relation to the vote-power block snapshot. Delegation Type Before or After Vote-Power Block Snapshot When Delegation Takes Effect New or changed Before In the next reward epoch After After the next reward epoch ends Revoked N/A Immediately","title":"Effects of the Vote-Power Block Snapshot on Delegations"},{"location":"tech/ftso/#delegation-procedure","text":"You can delegate your tokens using the Flare Portal , a supported wallet like Bifrost , or a dapp . Some FTSO data providers have already started providing these dapps as a convenience. Take a look at flaremetrics.io and pick the one you prefer. If you are an advanced user, you can delegate manually by interacting directly with the FTSO smart contracts.","title":"Delegation Procedure"},{"location":"tech/ftso/#rewards","text":"A percentage of the annual network inflation is reserved to reward FTSO data providers and distributed uniformly among the year's reward epochs. The mechanism that distributes rewards to data providers consists of several bands: Primary reward band : This band rewards 50% of submitted data, weighted by vote power and centered around the median price . That is, the primary reward band fixes the rewarded vote power at 50%, which makes the width of the primary reward band in each epoch variable. Secondary reward band : This band rewards submitted data that falls within a fixed percentage around the calculated median . That is, the width of the secondary reward band is fixed, which makes the rewarded vote power in each epoch variable. Submitted data in each reward epoch belongs to one of the following: Primary reward band Primary and secondary reward band Neither reward band On Flare, reward epochs are 3.5 days. On Songbird, reward epochs are 7 days. In each reward epoch, rewards are distributed to providers whose submission falls within the primary or secondary reward bands. Because the secondary reward band is wider, it rewards more data providers than the primary band. However, submissions still must be close enough to the median to be included. If a submission falls within both bands, it receives both rewards because each reward band is independent. The secondary reward band receives 30% of all FTSO rewards, and the primary reward band receives the remaining 70%. As the FTSO system evolves, these reward percentages might be revised later, in accordance with an accepted proposal that requests changes to the secondary reward band. After the band rewards are distributed, each provider can take an optional, configurable fee , which is set to 20% by default, and distributes the rest of the reward among all contributors to its vote power , i.e., itself and all its delegators, according to the delegated amounts. If you delegated to a data provider, the amount of your rewards depends on multiple factors: The percentage of vote power you delegated The data providers to which you delegated your vote power The performance of those data providers The fee charged by those data providers Whether the total vote power of one or both of those data providers exceeded the vote power cap You can claim your rewards at the end of each reward epoch. You must claim your rewards within 90 days of their availability. After 90 days, unclaimed rewards on Flare are burned, and on Songbird, they are reallocated.","title":"Rewards"},{"location":"tech/ftso/#reward-claiming-procedure","text":"FTSO rewards are not automatically transferred to their recipients. Instead, the amounts are accumulated in a contract, as described in the System Architecture , and must be claimed once the reward epoch is finished . You can claim your rewards using the Flare Portal , a supported wallet like Bifrost , or a dapp . Take a look at flaremetrics.io and pick the one you prefer. If you are an advanced user, you can claim manually by interacting directly with the FTSO smart contracts. To save on gas costs, rewards from multiple reward epochs are claimed simultaneously when you use the Portal. However, be aware that rewards expire after 90 days . Moreover, you probably want to claim soon, to redelegate the received amount and obtain compounded rewards. It is also worth noting that: Rewards are paid in the network's native currency. On Flare, the native token is $FLR , and on Songbird, the native token is $SGB . Data providers and their delegators must claim independently.","title":"Reward-Claiming Procedure"},{"location":"tech/ftso/#technical-details","text":"This section is aimed at developers.","title":"Technical Details"},{"location":"tech/ftso/#system-architecture","text":"The FTSO system is composed of multiple smart contracts running on the Flare Network. Using prices as an example, the following diagram shows the flow of data, queries, and rewards through the FTSO system: FTSO component smart contracts. The following list describes the most relevant contracts and their purposes: FTSO : Each data type is handled by its own FTSO contract, including calculation of the filtered feed. To retrieve information about a data type, access this contract. Note If an FTSO contract is redeployed (for example, to fix a bug), its address will change and apps using it will need to be updated. The FTSO Registry contract below tracks this change for you. You can retrieve the addresses of all FTSO contracts using the getAllFtsos method in the FTSO Registry. FTSO Registry : Aggregates the output of each individual FTSO contract and provides a convenient one-stop API to retrieve all data. Price Submitter : This contract is used by the FTSO data providers to submit their data. Although the contract is called PriceSubmitter , data is not limited to prices. Reward Manager : Use this contract to claim your rewards, whether you are a data provider or a delegator. Wrapped Native (WNat) : This contract is not exclusively related to the FTSO system, but it is required to wrap and unwrap native tokens into the $WFLR and $WSGB that delegation requires. Note The Contract Addresses page explains how to securely retrieve each contract's address. Other contracts, like the FTSO Manager or the FTSO Daemon, are only meant for internal use by the FTSO system.","title":"System Architecture"},{"location":"tech/ftso/#manual-delegation-and-claiming","text":"The following graphic shows the delegation process. You can call methods in several different smart contracts to manually delegate vote power and claim rewards . FTSO delegation process summary.","title":"Manual Delegation and Claiming"},{"location":"tech/ftso/#data-submission-process","text":"Data submission uses a commit-and-reveal scheme to prevent providers from viewing each other's submissions until a round is over. To speed up the process, both phases are actually overlapped so: All Commit phases happen continuously in so-called 3-minute Price Epochs . Reveal phases happen during the first half ( first 90 seconds ) of the following Commit phase. The published price information is therefore updated every 3 minutes . Only a hash of the data is submitted during the Commit phase. Next, in the Reveal phase the actual data is sent. If its hash does not match the previous commitment, the data is discarded. The submission API is slightly different for the Flare and Songbird networks: Flare Songbird FTSO data providers submit data through the PriceSubmitter contract . Commit : A single hash is needed for each submission. function submitHash ( uint256 _epochId , bytes32 _hash ) external ; Reveal : After all data is submitted, a single random number must be submitted. function revealPrices ( uint256 _epochId , uint256 [] memory _ftsoIndices , uint256 [] memory _prices , uint256 _random ) external ; FTSO data providers submit data through the PriceSubmitter contract . Commit : A separate hash is needed for each submission. function submitPriceHashes ( uint256 _epochId , uint256 [] memory _ftsoIndices , bytes32 [] memory _hashes ) external ; Reveal : Along with each data submission, a random number must be submitted too. function revealPrices ( uint256 _epochId , uint256 [] memory _ftsoIndices , uint256 [] memory _prices , uint256 [] memory _randoms ) external ;","title":"Data-Submission Process"},{"location":"tech/ftso/#retrieving-data","text":"Data produced by the FTSO is publicly available on the Flare and Songbird networks. All data can be retrieved either through the FtsoRegistry contract or directly through one of the Ftso contracts. In any case, using the getCurrentPriceWithDecimals method is recommended. The following examples show how to use this method to retrieve price data. Retrieve by pair index Retrieve by pair symbol Retrieve directly From the FtsoRegistry contract: function getCurrentPriceWithDecimals ( uint256 _ftsoIndex ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Where _ftsoIndex is one of the allowed indices returned by getSupportedIndices , for example. From the FtsoRegistry contract: function getCurrentPriceWithDecimals ( string memory _symbol ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Where _symbol is one of the allowed symbols returned by getSupportedSymbols , for example. First you need to obtain the address of the Ftso contract managing the price pair you are interested in. You can use getSupportedIndicesSymbolsAndFtsos from the FtsoRegistry , for example. Then call getCurrentPriceWithDecimals on the FTSO directly: function getCurrentPriceWithDecimals ( ) external view returns ( uint256 _price , uint256 _timestamp , uint256 _assetPriceUsdDecimals ); Note Individual FTSO contracts might be updated periodically, which will change their addresses. Instead of caching these addresses, use the FtsoRegistry . GetCurrentPriceWithDecimals returns the requested price (the outcome of the previous 3-minute price epoch) in $USD shifting the comma by the amount of decimal places returned in _assetPriceUsdDecimals . That is, the actual price is _price * 10 - _assetPriceUsdDecimals . For example, a return value of 2603 with _assetPriceUsdDecimals of 5 means a price of 0.02603 USD (There are only 5 significant decimal places). A standard Unix timestamp of the last price update is also returned.","title":"Retrieving Data"},{"location":"tech/ftso/#related-user-guides","text":"Managing delegations Managing rewards Wrapping tokens","title":"Related User Guides"},{"location":"tech/ftso/#related-infrastructure-guides","text":"Operating a Data Provider Working with Whitelists Managing the Ecosystem","title":"Related Infrastructure Guides"},{"location":"tech/glossary/","text":"Glossary # Attestation A data proof provided to the State Connector by a decentralized set of Attestation Providers that confirms the validity or otherwise of any request. Autoclaiming Automatic claiming enables users to appoint an executor to claim rewards on their behalf. Read more... Avalanche An open-source blockchain using the Snow family of consensus protocols and Proof of Stake for Sybil resistance . It is advertised as the fastest smart contract platform. Read more... Block For performance reasons, blockchains do not process transactions one by one. Instead, transactions are grouped together in blocks which are then validated by the consensus algorithm. Block Explorer A tool that enables its users to analyze transactions and interact with addresses on blockchains. Read more... Blockchain Digital ledger storing data and transactions on a distributed network of computers to make it more robust. Cryptography protects against information tampering, and a consensus algorithm ensures that the majority of the network agrees on the stored data even if some of its nodes act maliciously. Bootstrapping Node An observation node associated with a validator node and acting as its bastion: the bootstrapping node exposes a minimum RPC interface, so the validator does not have to. The nodeID and nodeIP returned by the bootstrapping node's RPC allow an external node to connect and peer with the core network of validators. The bootstrapping node also gossips the core network's validators nodeIDs and nodeIPs to the external node to peer to. The main purpose of a bootstrapping node is to allow new nodes to connect to the network (hence the name \"bootstrapping\") while reducing its associated validator node attack surface. Flare offers some public bootstrapping nodes . Byzantine Fault Tolerance Property of a distributed system that is capable of continuous operation even when some of its participants are unreliable. Participants acting against the interest of the whole system, by accident or on purpose, are said to have \u201cgone Byzantine\u201d. Canary Network A network used for testing features under \u201creal fire\u201d conditions, before deploying them on the main network . All users of the canary network are real users, but they are aware of the experimental nature of the platform. The name comes from the time when actual miners used actual canaries to detect the presence of poisonous gas in the mines. Flare's canary network is called Songbird . Consensus Algorithm that makes nodes on a blockchain\u2019s network agree on the validity of a given transaction, even if some of the nodes provide invalid transactions or try to disrupt the network ( Byzantine Fault Tolerance ). Coston The name given to both of Flare's public test networks (Coston and Coston2), in remembrance and celebration of a great inventor, Martha J. Coston (1826-1904). Cross-chain (or inter-ecosystem) interoperability Communication between two or more disparate blockchain ecosystems that are technologically incompatible due to the lack of shared systems, protocols or code (e.g. Ethereum and Solana). DAO A Decentralized Autonomous Organization is an entity with no central authority. Its governance is mandated by rules encoded on a blockchain so it is tamper-proof. Dapp A Decentralized Application is a computer program that makes use of blockchain technology and therefore the information it uses or stores has the same benefits (trustlessness, censorship resistance, geographical redundancy, etc). The dapp itself may or may not be hosted on a blockchain. Data Provider Each of the multiple programs supplying external information to an FTSO running on the Flare network, and getting rewarded for it. Token holders can delegate their stake to a data provider and receive a share of the rewards. DeFi Decentralized Finance is a form of finance that does not rely on a central financial institution. DeFi is commonly based on blockchain technology. Delegate To assign a duty to someone else, so they do it for you. On the Flare network, an address can delegate any fraction of the votes associated with the tokens it holds to another address, for the purpose of FTSO weighting or governance participation. Note that no tokens are transferred. ERC-20 The Ethereum Request for Comments 20, proposed in November 2015, is an Ethereum token standard that implements an API for tokens within smart contracts. It is a standard for fungible (exchangeable) tokens, which have a property that makes each token exactly the same (in type and value) as another token. For example, an ERC-20 token acts just like Ethereum's ETH token, meaning that 1 token is and will always be equal to all the other tokens. Read more... EVM The Ethereum Virtual Machine allows executing smart contracts on the Ethereum network, regardless of the kind of computer that executes it. Multiple blockchain networks, including Flare, support EVM contracts. Read more... Executor Users who do not want to claim rewards themselves can set an executor to claim rewards for them and send them directly to their users' accounts. Read more... Faucet A dapp that distributes test tokens to anyone that requests them. Used only on test networks , obviously. See the Network Configuration page to learn about Flare's faucets. FBA Federated Byzantine Agreement is a form of Byzantine fault tolerance where each node keeps its own list of trusted nodes. It does not require nodes to invest stake or computing power as Proof of Stake or Proof of Work protocols do. FCP The Flare Consensus Protocol is an asynchronous, ordered and leaderless version of Federated Byzantine Agreement ( FBA ) consensus. The whitepaper is already available and it is currently in the process of being implemented. Read more... Flare Token (FLR) The native currency of the Flare's main network . FTSO The Flare Time Series Oracles provide external information to the Flare network in a decentralized manner, by using multiple independent data providers that are rewarded for providing accurate information. Read more... Governance Mechanism to propose, vote and implement changes on a blockchain protocol. On Flare, anybody can propose updates and token holders vote to accept them. Know Your Customer The process an entity completes to verify the identities of its users to comply with global requirements. Layer 1 An L1 is a blockchain in the classical sense, in that it comprises a network of nodes that exchange information to guarantee the integrity of a shared ledger and offer functionality like token exchange and programmability. Compare it to an L2, which is built on top of an existing L1. Layer 2 An L2 is a blockchain built on top of an existing L1 making use of its programmability. L2 chains add extra functionality to the L1, like scalability. Ledger Historically, a book where financial transactions are recorded. In blockchain technology, a ledger can contain any kind of information, which has multiple copies distributed among several computers, kept in sync by a consensus algorithm. Light Client Relay A simplified communication mechanism built for speed that only queries the header data of any transaction and therefore lacks the security that comes from querying a full node with full history (e.g. SPV ). Liquidity Pool A collection of funds locked in a smart contract for the purpose of facilitating trading, lending and other functionality in a decentralized manner. Main Network (MAINNET) The computer network that supports a blockchain in its production stage, i.e., the real thing (instead of a Canary or Test network). Metaverse An old concept, at times called Virtual Reality or Cyberspace, that translates human interaction to virtual (i.e. non-physical) worlds. Currently in vogue again because blockchain technology promises to link the physical and the virtual worlds and thus bring a degree of reality to the latter. Multi-chain (or intra-ecosystem) interoperability Communication between two or more technologically compatible blockchains that exist within the same ecosystem and share systems, protocols and code (e.g. Polkadot Parachains , Cosmos Tendermint chains or Ethereum layer 2 protocols). NFT Non-Fungible Tokens are digital representations of assets which are unique and therefore non-mergeable (non-fungible), made impossible to copy by blockchain technology. Common use cases are certificates of authenticity or ownership, or limited edition collectibles. Most NFT tokens are built on the Ethereum network using standards ERC-721 and ERC-1155 . Oracle A mechanism to provide external information to a blockchain, so that it can be used by smart contracts , for example. Flare oracles are called FTSO . Proof of Stake A kind of Sybil resistance based on staking assets to participate in consensus. The rationale is that a participant investing enough assets will not be interested in attacking the network that supports such assets. Moreover, if malicious behavior is detected part of the assets can be taken as punishment. Proof of Work A kind of Sybil resistance based on spending computer power to participate in consensus. The rationale is that attacking the network becomes prohibitively expensive in terms of computer power. Pruning A blockchain database reduction technique, which keeps the state of all addresses (like their balance) and the transactions that led to that state, but removes any old transaction that does not impact the current state anymore. Quantum Resistance The ability of a cryptographic algorithm (and therefore of a blockchain) to resist an attack from a theoretical quantum computer. Quorum Set of participants on a consensus algorithm that must agree on a result for the whole network to accept that result. On a blockchain, once consensus is reached about a block , it is added to the ledger and the next block is processed. Quorum Slice In FBA consensus each node has multiple lists of other nodes which it voluntarily decides to trust, forming its quorum slices. All nodes in a quorum slice agreeing on a result are enough to convince the node of that result. If the quorum slices are correctly built, global quorum emerges from these local quorum slices. RPC Remote Procedure Call is a protocol that allows a program executing on a computer to request a service from another program, typically running on a different computer. Flare offers some public and private nodes with RPC capabilities . Smart Contract Computer program running on a blockchain, typically one based on the EVM . The blockchain\u2019s immutability ensures that the contract is not tampered with, and running it on several machines bound together by a consensus algorithm ensures faithful execution. Smart contracts are said to be self-enforcing. Songbird Flare's canary network , launched in September 2021. State Connector Piece of the Flare network that keeps track of the state of other networks, facilitating the implementation of advanced mechanisms like the FAssets. The State Connector uses several independent Attestation Providers that are rewarded for providing correct information. Read more... Sybil Resistance The ability of a distributed system to overcome a Sybil attack, in which a malicious actor creates multiple identities to gain voting or mining power. Resistance is typically gained by making voting or mining too costly for the attack to be worth it (as in Proof of Work or Proof of Stake ) or by requiring new entities to be approved by existing actors (as in FBA ). Test Network (TESTNET) The computer network that supports a blockchain in its development stage. It is intended for testing purposes and should not store valuable assets, as its contents might be deleted (purposely or by accident) at any time. Among other facilities, testnets typically provide faucets . Compare to a Canary or a Main network. Flare's testnets are Coston for Songbird and Coston2 for Flare. Transaction A request to add information to the blockchain, which is then analyzed by the network and accepted when consensus is reached about its validity. It can be a movement of funds between two accounts, or the execution of a contract, for example. Transaction Fee Amount of cryptocurrency that must be paid by anybody submitting a transaction for inclusion on a blockchain. These fees reward block producers for their work processing transactions, and typically vary depending on network congestion. Token A digital representation of an asset. Fungible tokens are indistinguishable from one another so they can be merged together (e.g. a cryptocurrency). Non-fungible tokens ( NFT ) are unique and therefore cannot be merged. Turing-completeness The ability of a machine to solve any computational problem, no matter how complex, given the necessary steps and enough time and memory. This is a mandatory feature of any general-purpose processor like a CPU or the EVM . Validator A validator node is a machine connected to a blockchain network that verifies transactions and emits a vote. When there is a quorum among all validators regarding a given block of transactions, they are accepted into the blockchain. Voting Power Weight proportional to the tokens held by an address plus the tokens delegated to it. This weight is used during FTSO operation and governance votes, for example. Wen flare The war cry of all the impatient that would like to see the Flare network launch before it is fully tested. Pay no heed to them. Zero address A special address represented as 0x0000000000000000000000000000 . Also known as the null address, it is typically used as a return value from functions to indicate an error condition. /*Glossary links from within the glossary page*/ a[href^=\"#\"] { text-decoration-style: dotted; text-decoration-thickness: 1px; } /*Separating line for the glossary nav link from within the glossary page*/ .md-nav__link.md-nav__link--active { border-top: solid 1px var(--md-default-fg-color--lightest); padding-top: 8px; }","title":"Glossary"},{"location":"tech/glossary/#glossary","text":"Attestation A data proof provided to the State Connector by a decentralized set of Attestation Providers that confirms the validity or otherwise of any request. Autoclaiming Automatic claiming enables users to appoint an executor to claim rewards on their behalf. Read more... Avalanche An open-source blockchain using the Snow family of consensus protocols and Proof of Stake for Sybil resistance . It is advertised as the fastest smart contract platform. Read more... Block For performance reasons, blockchains do not process transactions one by one. Instead, transactions are grouped together in blocks which are then validated by the consensus algorithm. Block Explorer A tool that enables its users to analyze transactions and interact with addresses on blockchains. Read more... Blockchain Digital ledger storing data and transactions on a distributed network of computers to make it more robust. Cryptography protects against information tampering, and a consensus algorithm ensures that the majority of the network agrees on the stored data even if some of its nodes act maliciously. Bootstrapping Node An observation node associated with a validator node and acting as its bastion: the bootstrapping node exposes a minimum RPC interface, so the validator does not have to. The nodeID and nodeIP returned by the bootstrapping node's RPC allow an external node to connect and peer with the core network of validators. The bootstrapping node also gossips the core network's validators nodeIDs and nodeIPs to the external node to peer to. The main purpose of a bootstrapping node is to allow new nodes to connect to the network (hence the name \"bootstrapping\") while reducing its associated validator node attack surface. Flare offers some public bootstrapping nodes . Byzantine Fault Tolerance Property of a distributed system that is capable of continuous operation even when some of its participants are unreliable. Participants acting against the interest of the whole system, by accident or on purpose, are said to have \u201cgone Byzantine\u201d. Canary Network A network used for testing features under \u201creal fire\u201d conditions, before deploying them on the main network . All users of the canary network are real users, but they are aware of the experimental nature of the platform. The name comes from the time when actual miners used actual canaries to detect the presence of poisonous gas in the mines. Flare's canary network is called Songbird . Consensus Algorithm that makes nodes on a blockchain\u2019s network agree on the validity of a given transaction, even if some of the nodes provide invalid transactions or try to disrupt the network ( Byzantine Fault Tolerance ). Coston The name given to both of Flare's public test networks (Coston and Coston2), in remembrance and celebration of a great inventor, Martha J. Coston (1826-1904). Cross-chain (or inter-ecosystem) interoperability Communication between two or more disparate blockchain ecosystems that are technologically incompatible due to the lack of shared systems, protocols or code (e.g. Ethereum and Solana). DAO A Decentralized Autonomous Organization is an entity with no central authority. Its governance is mandated by rules encoded on a blockchain so it is tamper-proof. Dapp A Decentralized Application is a computer program that makes use of blockchain technology and therefore the information it uses or stores has the same benefits (trustlessness, censorship resistance, geographical redundancy, etc). The dapp itself may or may not be hosted on a blockchain. Data Provider Each of the multiple programs supplying external information to an FTSO running on the Flare network, and getting rewarded for it. Token holders can delegate their stake to a data provider and receive a share of the rewards. DeFi Decentralized Finance is a form of finance that does not rely on a central financial institution. DeFi is commonly based on blockchain technology. Delegate To assign a duty to someone else, so they do it for you. On the Flare network, an address can delegate any fraction of the votes associated with the tokens it holds to another address, for the purpose of FTSO weighting or governance participation. Note that no tokens are transferred. ERC-20 The Ethereum Request for Comments 20, proposed in November 2015, is an Ethereum token standard that implements an API for tokens within smart contracts. It is a standard for fungible (exchangeable) tokens, which have a property that makes each token exactly the same (in type and value) as another token. For example, an ERC-20 token acts just like Ethereum's ETH token, meaning that 1 token is and will always be equal to all the other tokens. Read more... EVM The Ethereum Virtual Machine allows executing smart contracts on the Ethereum network, regardless of the kind of computer that executes it. Multiple blockchain networks, including Flare, support EVM contracts. Read more... Executor Users who do not want to claim rewards themselves can set an executor to claim rewards for them and send them directly to their users' accounts. Read more... Faucet A dapp that distributes test tokens to anyone that requests them. Used only on test networks , obviously. See the Network Configuration page to learn about Flare's faucets. FBA Federated Byzantine Agreement is a form of Byzantine fault tolerance where each node keeps its own list of trusted nodes. It does not require nodes to invest stake or computing power as Proof of Stake or Proof of Work protocols do. FCP The Flare Consensus Protocol is an asynchronous, ordered and leaderless version of Federated Byzantine Agreement ( FBA ) consensus. The whitepaper is already available and it is currently in the process of being implemented. Read more... Flare Token (FLR) The native currency of the Flare's main network . FTSO The Flare Time Series Oracles provide external information to the Flare network in a decentralized manner, by using multiple independent data providers that are rewarded for providing accurate information. Read more... Governance Mechanism to propose, vote and implement changes on a blockchain protocol. On Flare, anybody can propose updates and token holders vote to accept them. Know Your Customer The process an entity completes to verify the identities of its users to comply with global requirements. Layer 1 An L1 is a blockchain in the classical sense, in that it comprises a network of nodes that exchange information to guarantee the integrity of a shared ledger and offer functionality like token exchange and programmability. Compare it to an L2, which is built on top of an existing L1. Layer 2 An L2 is a blockchain built on top of an existing L1 making use of its programmability. L2 chains add extra functionality to the L1, like scalability. Ledger Historically, a book where financial transactions are recorded. In blockchain technology, a ledger can contain any kind of information, which has multiple copies distributed among several computers, kept in sync by a consensus algorithm. Light Client Relay A simplified communication mechanism built for speed that only queries the header data of any transaction and therefore lacks the security that comes from querying a full node with full history (e.g. SPV ). Liquidity Pool A collection of funds locked in a smart contract for the purpose of facilitating trading, lending and other functionality in a decentralized manner. Main Network (MAINNET) The computer network that supports a blockchain in its production stage, i.e., the real thing (instead of a Canary or Test network). Metaverse An old concept, at times called Virtual Reality or Cyberspace, that translates human interaction to virtual (i.e. non-physical) worlds. Currently in vogue again because blockchain technology promises to link the physical and the virtual worlds and thus bring a degree of reality to the latter. Multi-chain (or intra-ecosystem) interoperability Communication between two or more technologically compatible blockchains that exist within the same ecosystem and share systems, protocols and code (e.g. Polkadot Parachains , Cosmos Tendermint chains or Ethereum layer 2 protocols). NFT Non-Fungible Tokens are digital representations of assets which are unique and therefore non-mergeable (non-fungible), made impossible to copy by blockchain technology. Common use cases are certificates of authenticity or ownership, or limited edition collectibles. Most NFT tokens are built on the Ethereum network using standards ERC-721 and ERC-1155 . Oracle A mechanism to provide external information to a blockchain, so that it can be used by smart contracts , for example. Flare oracles are called FTSO . Proof of Stake A kind of Sybil resistance based on staking assets to participate in consensus. The rationale is that a participant investing enough assets will not be interested in attacking the network that supports such assets. Moreover, if malicious behavior is detected part of the assets can be taken as punishment. Proof of Work A kind of Sybil resistance based on spending computer power to participate in consensus. The rationale is that attacking the network becomes prohibitively expensive in terms of computer power. Pruning A blockchain database reduction technique, which keeps the state of all addresses (like their balance) and the transactions that led to that state, but removes any old transaction that does not impact the current state anymore. Quantum Resistance The ability of a cryptographic algorithm (and therefore of a blockchain) to resist an attack from a theoretical quantum computer. Quorum Set of participants on a consensus algorithm that must agree on a result for the whole network to accept that result. On a blockchain, once consensus is reached about a block , it is added to the ledger and the next block is processed. Quorum Slice In FBA consensus each node has multiple lists of other nodes which it voluntarily decides to trust, forming its quorum slices. All nodes in a quorum slice agreeing on a result are enough to convince the node of that result. If the quorum slices are correctly built, global quorum emerges from these local quorum slices. RPC Remote Procedure Call is a protocol that allows a program executing on a computer to request a service from another program, typically running on a different computer. Flare offers some public and private nodes with RPC capabilities . Smart Contract Computer program running on a blockchain, typically one based on the EVM . The blockchain\u2019s immutability ensures that the contract is not tampered with, and running it on several machines bound together by a consensus algorithm ensures faithful execution. Smart contracts are said to be self-enforcing. Songbird Flare's canary network , launched in September 2021. State Connector Piece of the Flare network that keeps track of the state of other networks, facilitating the implementation of advanced mechanisms like the FAssets. The State Connector uses several independent Attestation Providers that are rewarded for providing correct information. Read more... Sybil Resistance The ability of a distributed system to overcome a Sybil attack, in which a malicious actor creates multiple identities to gain voting or mining power. Resistance is typically gained by making voting or mining too costly for the attack to be worth it (as in Proof of Work or Proof of Stake ) or by requiring new entities to be approved by existing actors (as in FBA ). Test Network (TESTNET) The computer network that supports a blockchain in its development stage. It is intended for testing purposes and should not store valuable assets, as its contents might be deleted (purposely or by accident) at any time. Among other facilities, testnets typically provide faucets . Compare to a Canary or a Main network. Flare's testnets are Coston for Songbird and Coston2 for Flare. Transaction A request to add information to the blockchain, which is then analyzed by the network and accepted when consensus is reached about its validity. It can be a movement of funds between two accounts, or the execution of a contract, for example. Transaction Fee Amount of cryptocurrency that must be paid by anybody submitting a transaction for inclusion on a blockchain. These fees reward block producers for their work processing transactions, and typically vary depending on network congestion. Token A digital representation of an asset. Fungible tokens are indistinguishable from one another so they can be merged together (e.g. a cryptocurrency). Non-fungible tokens ( NFT ) are unique and therefore cannot be merged. Turing-completeness The ability of a machine to solve any computational problem, no matter how complex, given the necessary steps and enough time and memory. This is a mandatory feature of any general-purpose processor like a CPU or the EVM . Validator A validator node is a machine connected to a blockchain network that verifies transactions and emits a vote. When there is a quorum among all validators regarding a given block of transactions, they are accepted into the blockchain. Voting Power Weight proportional to the tokens held by an address plus the tokens delegated to it. This weight is used during FTSO operation and governance votes, for example. Wen flare The war cry of all the impatient that would like to see the Flare network launch before it is fully tested. Pay no heed to them. Zero address A special address represented as 0x0000000000000000000000000000 . Also known as the null address, it is typically used as a return value from functions to indicate an error condition. /*Glossary links from within the glossary page*/ a[href^=\"#\"] { text-decoration-style: dotted; text-decoration-thickness: 1px; } /*Separating line for the glossary nav link from within the glossary page*/ .md-nav__link.md-nav__link--active { border-top: solid 1px var(--md-default-fg-color--lightest); padding-top: 8px; }","title":"Glossary"},{"location":"tech/governance/","text":"Governance # Introduction # Flare governance gives everyone in the ecosystem the opportunity to collaborate on decision-making on the Flare and Songbird networks, making governance an important element of decentralization. This process enables the Flare Foundation and Flare and Songbird community members to: Propose policy changes. Vote on them. Execute them if accepted. The following sections detail the different kinds of proposals Flare allows and the process for each of them. If you are already familiar with Flare's governance and just need to know how to cast your vote through the Flare Portal, check the Voting User Guide . Flare's Governance # Excluding the testnets Coston and Coston2, Flare currently has two networks: Flare and Songbird. Moreover, two kinds of proposals are planned, depending on who initiates them: those proposed by the community and those proposed by the Flare Foundation. This situation leads to four types of proposals, of which only two are currently supported and detailed next. Flare Improvement Proposals and Songbird Test Proposals # Flare Improvement Proposals (FIPs) and Songbird Test Proposals (STPs) are initiated by the Flare Foundation and are aimed at improving the Flare and Songbird networks. Community-initiated proposals will be supported later. To increase its stability, FIPs are rejected by default, meaning that they are accepted only if enough votes are cast in their favor. To increase the swiftness at which new proposals can be tested on Songbird, STPs are accepted by default, meaning that they are rejected only if enough votes are cast against them. See Voting Outcomes below for more details. Who Votes # To vote on a proposal on a network, you must have the valid wrapped token: Network Proposal Type Token Wrapped Token Flare FIP $FLR $WFLR Songbird STP $SGB $WSGB Important Available votes depend on the amount of valid wrapped tokens you have, not the native tokens. Therefore, remember to wrap your tokens . Don't wrap all your tokens. Keep some of them to pay for transaction fees . To vote with your tokens, they must be wrapped before the proposal is submitted. The Flare Foundation announces proposals in advance, so that users can read them and wrap their tokens if they have to. Vote Transfer Votes can be transferred to another account while the wrapped tokens remain in your possession. Being able to transfer votes is useful, for example, if you have wrapped tokens in multiple self-custody wallets, because voting can then be simplified by transferring all the votes to a single wallet and voting from there. Votes can only be transferred to one address, but it can receive votes from multiple addresses. Received votes cannot be transferred again to a third address. Once activated, vote transfers always send 100% of an account's votes to the selected address and remain active until they are canceled. As an example, if you have 100 $WSGB before a proposal and you activate the transfer, you will transfer 100 votes. If you later add 100 more $WSGB , for the next proposal you will automatically transfer 200 votes, since the transfer remains active until you cancel it. The following is a more complex example, showing the changes produced by vote transfers, and token wrapping and unwrapping on Songbird: Changes in the number of votes on Songbird. Note Transferring votes has no connection with FTSO delegation: Wrapped tokens can be delegated to an FTSO data provider and at the same time the votes they grant can be transferred to a different address. The Vote Count Block # Since the amount of wrapped tokens an account holds varies over time, a snapshot of all accounts is taken before each voting period starts. The amount of wrapped tokens held by an account at the snapshot then dictates the number of votes available later. The block at which the snapshot is taken is called the vote count block . To encourage users to use their tokens and keep them in the network, instead of just acquiring them for voting and then disposing of them, the vote count block is randomly selected. The next section details when this happens. Voting Process # The image in this section shows the voting process, which includes several conditions: Threshold condition : A minimum quorum must be reached, meaning that enough votes must be cast, or no minimum quorum is required. Majority condition : More than 50% of the votes cast, must be for or against the proposal. Voting process. Announcement : The Flare Foundation publishes the proposal online and announces it through social media channels (linked on the footer of this page) and the Flare website . Notice period : Once the proposal is published, the Flare Foundation allows a notice period before voting can start, typically lasting one week. During this time the proposal can be discussed, clarified, commented on, and even cancelled if serious issues are found with it. For security reasons only, the Foundation may reduce the timeframe of this period. Block selection period : The vote count block is selected at a random time during this period. The duration of this period is also random. Warning If you need to wrap tokens, do so before this period starts since tokens wrapped after the selected vote count block will not result in additional votes. Voting period : The proposal is submitted to the Flare Portal , and it is immediately available for voting. Voting concludes after a week, and final results are presented on the portal. Voting Outcomes # FIPs # Voting on FIPs is acceptance-based. For an FIP to be accepted, a simple majority of the votes cast must be in favor of it. No minimum quorum is required. Therefore, an FIP will be rejected only if less than half of the cast votes are for it. STPs # Voting on STPs is rejection-based. For an STP to be rejected, both of the following conditions must be true: Threshold condition : The minimum quorum is at least 75% of all $SGB tokens circulation (excluding the Flare Foundation's tokens) at the vote count block . Note that the quorum is specified as a fraction of the circulating native $SGB tokens instead of the wrapped tokens $WSGB used for voting. This measure tries, again, to encourage users to wrap their tokens and use them in the network. Majority condition : More than 50% of the votes cast, must be against the proposal. Therefore, an STP will be accepted if the quorum threshold is not reached or if less than half of the cast votes are against it. Execution # Once a proposal is accepted, Flare's governance contracts allow for its automatic execution via a contract call. However, some proposals might require changes that are not implementable through a smart contract and therefore automatic execution is disabled for them. Both FIPs and STPs are manually executed by the Flare Foundation. Related User Guides # Voting","title":"Governance"},{"location":"tech/governance/#governance","text":"","title":"Governance"},{"location":"tech/governance/#introduction","text":"Flare governance gives everyone in the ecosystem the opportunity to collaborate on decision-making on the Flare and Songbird networks, making governance an important element of decentralization. This process enables the Flare Foundation and Flare and Songbird community members to: Propose policy changes. Vote on them. Execute them if accepted. The following sections detail the different kinds of proposals Flare allows and the process for each of them. If you are already familiar with Flare's governance and just need to know how to cast your vote through the Flare Portal, check the Voting User Guide .","title":"Introduction"},{"location":"tech/governance/#flares-governance","text":"Excluding the testnets Coston and Coston2, Flare currently has two networks: Flare and Songbird. Moreover, two kinds of proposals are planned, depending on who initiates them: those proposed by the community and those proposed by the Flare Foundation. This situation leads to four types of proposals, of which only two are currently supported and detailed next.","title":"Flare's Governance"},{"location":"tech/governance/#flare-improvement-proposals-and-songbird-test-proposals","text":"Flare Improvement Proposals (FIPs) and Songbird Test Proposals (STPs) are initiated by the Flare Foundation and are aimed at improving the Flare and Songbird networks. Community-initiated proposals will be supported later. To increase its stability, FIPs are rejected by default, meaning that they are accepted only if enough votes are cast in their favor. To increase the swiftness at which new proposals can be tested on Songbird, STPs are accepted by default, meaning that they are rejected only if enough votes are cast against them. See Voting Outcomes below for more details.","title":"Flare Improvement Proposals and Songbird Test Proposals"},{"location":"tech/governance/#who-votes","text":"To vote on a proposal on a network, you must have the valid wrapped token: Network Proposal Type Token Wrapped Token Flare FIP $FLR $WFLR Songbird STP $SGB $WSGB Important Available votes depend on the amount of valid wrapped tokens you have, not the native tokens. Therefore, remember to wrap your tokens . Don't wrap all your tokens. Keep some of them to pay for transaction fees . To vote with your tokens, they must be wrapped before the proposal is submitted. The Flare Foundation announces proposals in advance, so that users can read them and wrap their tokens if they have to. Vote Transfer Votes can be transferred to another account while the wrapped tokens remain in your possession. Being able to transfer votes is useful, for example, if you have wrapped tokens in multiple self-custody wallets, because voting can then be simplified by transferring all the votes to a single wallet and voting from there. Votes can only be transferred to one address, but it can receive votes from multiple addresses. Received votes cannot be transferred again to a third address. Once activated, vote transfers always send 100% of an account's votes to the selected address and remain active until they are canceled. As an example, if you have 100 $WSGB before a proposal and you activate the transfer, you will transfer 100 votes. If you later add 100 more $WSGB , for the next proposal you will automatically transfer 200 votes, since the transfer remains active until you cancel it. The following is a more complex example, showing the changes produced by vote transfers, and token wrapping and unwrapping on Songbird: Changes in the number of votes on Songbird. Note Transferring votes has no connection with FTSO delegation: Wrapped tokens can be delegated to an FTSO data provider and at the same time the votes they grant can be transferred to a different address.","title":"Who Votes"},{"location":"tech/governance/#the-vote-count-block","text":"Since the amount of wrapped tokens an account holds varies over time, a snapshot of all accounts is taken before each voting period starts. The amount of wrapped tokens held by an account at the snapshot then dictates the number of votes available later. The block at which the snapshot is taken is called the vote count block . To encourage users to use their tokens and keep them in the network, instead of just acquiring them for voting and then disposing of them, the vote count block is randomly selected. The next section details when this happens.","title":"The Vote Count Block"},{"location":"tech/governance/#voting-process","text":"The image in this section shows the voting process, which includes several conditions: Threshold condition : A minimum quorum must be reached, meaning that enough votes must be cast, or no minimum quorum is required. Majority condition : More than 50% of the votes cast, must be for or against the proposal. Voting process. Announcement : The Flare Foundation publishes the proposal online and announces it through social media channels (linked on the footer of this page) and the Flare website . Notice period : Once the proposal is published, the Flare Foundation allows a notice period before voting can start, typically lasting one week. During this time the proposal can be discussed, clarified, commented on, and even cancelled if serious issues are found with it. For security reasons only, the Foundation may reduce the timeframe of this period. Block selection period : The vote count block is selected at a random time during this period. The duration of this period is also random. Warning If you need to wrap tokens, do so before this period starts since tokens wrapped after the selected vote count block will not result in additional votes. Voting period : The proposal is submitted to the Flare Portal , and it is immediately available for voting. Voting concludes after a week, and final results are presented on the portal.","title":"Voting Process"},{"location":"tech/governance/#voting-outcomes","text":"","title":"Voting Outcomes"},{"location":"tech/governance/#fips","text":"Voting on FIPs is acceptance-based. For an FIP to be accepted, a simple majority of the votes cast must be in favor of it. No minimum quorum is required. Therefore, an FIP will be rejected only if less than half of the cast votes are for it.","title":"FIPs"},{"location":"tech/governance/#stps","text":"Voting on STPs is rejection-based. For an STP to be rejected, both of the following conditions must be true: Threshold condition : The minimum quorum is at least 75% of all $SGB tokens circulation (excluding the Flare Foundation's tokens) at the vote count block . Note that the quorum is specified as a fraction of the circulating native $SGB tokens instead of the wrapped tokens $WSGB used for voting. This measure tries, again, to encourage users to wrap their tokens and use them in the network. Majority condition : More than 50% of the votes cast, must be against the proposal. Therefore, an STP will be accepted if the quorum threshold is not reached or if less than half of the cast votes are against it.","title":"STPs"},{"location":"tech/governance/#execution","text":"Once a proposal is accepted, Flare's governance contracts allow for its automatic execution via a contract call. However, some proposals might require changes that are not implementable through a smart contract and therefore automatic execution is disabled for them. Both FIPs and STPs are manually executed by the Flare Foundation.","title":"Execution"},{"location":"tech/governance/#related-user-guides","text":"Voting","title":"Related User Guides"},{"location":"tech/personal-delegation-account/","text":"Personal Delegation Accounts # Flare token holders are eligible to receive a number of rewards, for example through FTSO Delegation . The Flare network offers the option to set up Personal Delegation Accounts (PDAs) to temporarily receive and store rewards to track which funds are from rewards, for example, for personal or tax purposes. In certain jurisdictions, delaying the realization of earnings for a specified time can lead to a reduced tax rate. Each Flare address can be associated with one PDA, which behaves like a regular account in many respects. For example, it can receive funds from any address. Like regular accounts, it is under control of the owner and can perform functions such as delegation and claiming. Here are some of the differences from a regular account: A PDA cannot have another PDA of its own. PDA addresses cannot participate in governance directly, but their owners can transfer all their votes to another address (their main account or someone else's). A PDA automatically converts any $FLR tokens transferred to it to wrapped Flare tokens ( $WFLR ), which are more useful for functions such as delegation. Only the owner of the main account can transfer funds from the PDA and only to the main account. When an executor is configured, it will claim rewards both from the main account and the PDA, and send them to the PDA. Warning The Flare Foundation is not liable for any damages, especially pertaining to tax related issues when using this service. Check your local tax laws. Developing PDA functionality For information on how to develop a PDA, or how to write an application that supports a PDA, see Personal Delegation Accounts in the Developer section. Related User Guides # Managing your PDA Related Developer Docs # Managing PDAs in applications","title":"Personal Delegation Accounts"},{"location":"tech/personal-delegation-account/#personal-delegation-accounts","text":"Flare token holders are eligible to receive a number of rewards, for example through FTSO Delegation . The Flare network offers the option to set up Personal Delegation Accounts (PDAs) to temporarily receive and store rewards to track which funds are from rewards, for example, for personal or tax purposes. In certain jurisdictions, delaying the realization of earnings for a specified time can lead to a reduced tax rate. Each Flare address can be associated with one PDA, which behaves like a regular account in many respects. For example, it can receive funds from any address. Like regular accounts, it is under control of the owner and can perform functions such as delegation and claiming. Here are some of the differences from a regular account: A PDA cannot have another PDA of its own. PDA addresses cannot participate in governance directly, but their owners can transfer all their votes to another address (their main account or someone else's). A PDA automatically converts any $FLR tokens transferred to it to wrapped Flare tokens ( $WFLR ), which are more useful for functions such as delegation. Only the owner of the main account can transfer funds from the PDA and only to the main account. When an executor is configured, it will claim rewards both from the main account and the PDA, and send them to the PDA. Warning The Flare Foundation is not liable for any damages, especially pertaining to tax related issues when using this service. Check your local tax laws. Developing PDA functionality For information on how to develop a PDA, or how to write an application that supports a PDA, see Personal Delegation Accounts in the Developer section.","title":"Personal Delegation Accounts"},{"location":"tech/personal-delegation-account/#related-user-guides","text":"Managing your PDA","title":"Related User Guides"},{"location":"tech/personal-delegation-account/#related-developer-docs","text":"Managing PDAs in applications","title":"Related Developer Docs"},{"location":"tech/state-connector/","text":"State Connector # Introduction # The State Connector is a smart contract running on the Flare network that allows anyone to query non-changing, verifiable information (such as blockchain or geographic data) from outside the Flare network . Data that changes, such as the latest BTC to USD conversion rate, and non-verifiable data, such as data behind a paywall, are not available through the State Connector. The State Connector accesses data in a decentralized manner (no single party is in control of the process) and securely (it takes a lot of effort to disrupt the process). This is accomplished by using a set of independent attestation providers which fetch the required information from the world and deliver it to the Flare network. The State Connector smart contract then checks if there is enough consensus among the received answers and publishes the results if so. As an added security measure, individual validators can also define local attestation providers which, when in disagreement with the rest, cause the validator to branch into an idle, safe state while the situation is resolved. The State Connector. The State Connector can, for instance, check whether a deposit has been made on another blockchain , opening the door to more advanced mechanisms like the FAsset or the Layer Cake bridges. This page gives technical details about the whole procedure, the different security and scalability measures that have been taken into account in its design and the kind of queries that can be performed. Procedure Overview # This is how user queries are processed. The following sections contain more details. State Connector procedure overview. 1. Request # Anybody, be it a smart contract running on Flare or an application, can request the attestation of a specific event from the State Connector. Requests are yes/no questions regarding things that happened outside the Flare network, for example, \"Has transaction 0xABC been confirmed on the Bitcoin network enough times?\". The answers, though, might contain any kind of additional data attached, like the content of transaction 0xABC, for example. Requests must adhere to one of the available request types , which have been designed to be strictly decidable , i.e., the answers are objective and cannot be argued. Otherwise, queries like \"What is the weather like in Paris?\" would have a hard time reaching consensus among the different attestation providers. Section Adding New Attestation Types below contains more details. Making a request (for App developers) Make your requests using the requestAttestations method (#2) of the StateConnector contract : function requestAttestations ( bytes calldata data ) external ; The requestAttestations method has a single parameter, data , which is a byte array with a content that depends on the desired request type . You can learn how to build this array in the state-connector-attestation-types repository . 2. Request forwarding # The State Connector simply forwards the request to all connected attestation providers through an EVM event. Therefore, the request is not stored on the blockchain and its gas cost is very low for the requester. 3. Data retrieval # Attestation providers fetch the requested data by means that depend on the type of attestation, for example, retrieving data from another blockchain or public API. Keep in mind that attestation providers are not controlled by Flare in any way. Anybody can listen to the request events and provide answers using any combination of hardware, software, and code they see fit. 4. Attestation # To prevent attestation providers from peeking at each other's answers, these are submitted in a \"Commit and Reveal\" fashion called the CCCR protocol and detailed below. Submitting an attestation (For attestation provider developers) Attestation providers use the submitAttestation method (#3) of the StateConnector contract : function submitAttestation ( uint256 _bufferNumber , bytes32 _commitHash , bytes32 _merkleRoot , bytes32 _randomNumber ) external returns ( bool _isInitialBufferSlot ); Keep reading to understand the meaning of the parameters. More information in the Attestation Client repository . 5. Consensus # If at least 50% of the attestation providers submitted the same answer, it is made public. Otherwise, no consensus is achieved : requests remain unanswered and must be issued again. The answers are stored in the State Connector smart contract for a week , where anybody can read them, including the original requester. Retrieving your request's answer (for App developers) To retrieve the stored answers just read the merkleRoots public array (#8) in the StateConnector contract . More information on how to retrieve a particular answer in the State Connector contract source code . As shown below, multiple answers are actually packed into a single Merkle root. The Attestation Packing section explains how to retrieve an individual answer. Attestation Protocols # For simplicity, the above description omitted two very important mechanisms , reviewed here. The main one is Attestation packing , which decouples the number of requests from the number of answers, effectively providing unbounded scalability. It requires requests to be first collected and then answered all at once , so a protocol called CCCR is used. Overlapped CCCR Protocol # Requests and answers are submitted sequentially in attestation rounds . Each attestation round has 4 consecutive phases, called Collect, Choose, Commit and Reveal. Phases happen in 90-second windows, and the Choose and Commit phases share the same window, so a whole attestation round takes 4.5 minutes. The Collect-Choose-Commit-Reveal (CCCR) protocol. Collect phase : Users send their requests to the State Connector contract which forwards them to every attestation provider. Choose phase : Attestation Providers vote on which requests they will be able to answer in the current round. Commit phase : Attestation providers send obfuscated answers to the State Connector, so they cannot cheat by peeking at each other's submissions. Reveal phase : Attestation providers send the deobfuscation key so their previous answers are revealed. When all data is available, answers are made public if there is enough consensus. The CCCR protocol is akin to making submissions in a closed envelope which is not opened until all submissions are received. Results are available at the end of the Reveal phase, so the answer to a particular request can take anywhere from 3 to 4.5 minutes , depending on the time in which the request was made inside the Collect phase. Furthermore, the phases of the CCCR protocol are actually overlapped , so while requests are being collected for round \\((n+2)\\) , answers are being simultaneously committed for the previous round \\((n+1)\\) , and revealed for the round prior to that \\((n)\\) . The CCCR protocol with overlapped phases. This means that new requests can be made without waiting for the previous ones to be completed. Attestation Packing # Each round, attestation providers build a Merkle tree with the hashes of all valid answers to the requests that were agreed upon during the \"Choose\" phase . The obtained Merkle root is then called the Attestation Proof , since it is proof of the presence of each individual answer. Finally, the attestation proof is submitted to the State Connector for consensus evaluation. Attestation Proof packing using a Merkle tree. This allows any number of requests to be answered with a single hash , greatly improving scalability . Furthermore, the gas cost for attestation providers is constant each round, no matter how many requests they are answering. A request is only valid (and therefore added to the proof) if it is well-formed and it matches reality . Different providers might have different views on what reality is, and this is why the State Connector runs a consensus algorithm on the received answers. Additionally, the allowed request types are carefully designed to minimize the probability of contention . For example, requiring some time for transactions to settle before inquiring about them, and forcing requests to include the hash of a later block that confirms the transaction. Attestation providers keep the actual retrieved data for a week, in case it contains additional information beyond the yes/no result. Users can request this data directly from the providers through the Proof API . Note Please note that this data is safe to use even though it is obtained directly from the provider, because its hash is consistent with the Attestation Proof agreed upon by the State Connector's consensus. See the \"Proof unpacking\" box below to learn how to verify the data. Additional points worth noting: If two attestation providers observe a different validity for any of the requests in the round, they will submit a completely different Attestation Proof. Attestation providers must answer all agreed-upon queries in the round or abstain from participating in the round , otherwise, their Merkle tree root will not match other providers and will probably be discarded by consensus. Hashes are sorted before being added to the tree, just to have a consistent ordering (albeit arbitrary). The exact way in which the root hash is calculated can be changed without impacting the State Connector contract, which will continue to vote only on the hash value. Proof Unpacking (for App developers) The procedure for apps to check whether the State Connector answered yes or no to their request is detailed in the Attestation Client repository . What follows is an illustrative summary. The basic idea is that you must retrieve all data (both requests and answers) for the round from an attestation provider. You then rebuild the Merkle tree with this data and check that it matches the Attestation Proof provided by the State Connector. Proof unpacking. In the attestation round after you made the request (3 attestation phases, so from 3 to 4.5 minutes) the Attestation Proof for the round should be available in the State Connector. Retrieve it using method getAttestation (#7) of the StateConnector contract . Select any attestation provider you want and use the Proof API path api/proof/votes-for-round/{roundId} to retrieve all data for the round . Rebuild the Merkle tree for the retrieved data. There are tools to help you, like the MerkleTree.ts library. Check that the tree's root matches the Attestation Proof from step 1. If it does not match, this provider did not submit the answer agreed by the majority. Choose another provider in step 2. Conversely, you can use the api/proof/get-specific-proof API in step 2 which does steps 2, 3 and 4 for you. This API returns the JSON response data, including the attestation proof, if the attestation request was successfully verified in the given round. Now that you know that the retrieved data has been agreed upon by the consensus, you can use it. Look for your request inside the returned data . If it is not present, your request was deemed invalid (for example, the queried transaction was not present). Otherwise, your request is valid and you can find any extra information about it in the data array. Branching Protocol # Besides the consensus algorithm that runs on all received attestations, the State Connector provides one further security mechanism : the ability of any individual validator node to fork and halt execution if attestation providers specially trusted by it disagree with the majority. Attestation Provider Sets # To achieve this, two sets of attestation providers are defined: Default attestation providers set Anybody can submit attestations to the State Connector, but the contract will only accept submissions from attestation providers in the default set . Every validator node in the Flare network relies on this set. Local attestation providers set Additionally, each node operator can provide a list of local attestation providers to be accepted besides the ones from the default set. Local providers are the same kind of nodes as default providers, and they are treated exactly the same by the State Connector. Furthermore, providers can belong to both sets. Default and Local attestation providers. Then, for an attestation round to succeed these three conditions must be met: The default set must agree on a result (50% consensus inside the set). The local set must agree on a result too (50% consensus inside the set). Both results must match . Otherwise, the round is undecided and no answer is made public. This gives local attestation providers the capacity to stop results from being approved if they don't agree with their own observations. Ideally, local providers are managed by the same entity controlling the validator node using them, so they can be trusted implicitly . As a consequence of different validators using different attestation providers, sometimes State Connector queries can get different results on some validators, which naturally leads to chain forks . Typically, blockchains allow every branch in a fork to coexist and grow independently , until the discrepancy is detected and resolved. At that point, any branches deemed invalid are removed and all the validators that were following them experience a rollback : All transactions that happened after the fork are reverted and the state of those validators is synchronized with the rest of the network. When dealing with forks caused by the State Connector, the Flare network implements an extra security measure : Validators whose local attestation providers disagree with the default set halt execution after the fork , ensuring that they will not suffer any rollback once the fork is resolved. In other words, these validators remain in a safe state in which the disputed query is undecided and therefore no action is taken based on it. Example State Connector forks. In the example picture , all validator nodes use the attestation providers from the default set (not shown), but validators on the rightmost column, additionally, employ local providers . One of them returns a different answer for one of the queries, which leads to a fork of the chain since that validator's state does not match the rest of the network (the divergent ledger, depicted in red). The next section shows how forks are resolved and halted nodes restarted. Branch Resolution # The two states of the branching protocol. The picture above shows the state of the network after a fork. The default network state is the one followed by validators which only use the default set of attestation providers . The alternate network state is where validators go if they use local attestation providers , and they disagree with the default set. In the alternate state no queries are answered and no blocks are produced , so it is a safe state for validators to wait for forks to be resolved. This resolution must come from operators when they are alerted that a validator node has stopped. To understand how to do this, note that attestations are designed to be objectively decidable , meaning that in the event of a fork one branch matches reality and the other does not . There are therefore only two ways to resolve a fork: When local providers are wrong : The operator of the separated validator needs to find out why the local attestation providers failed and either fix them or remove them from the local set of the validator. Once this is fixed, the node simply rewinds its state to where it split and quickly fast-forward to rejoin the default state. Fork resolution when local providers are wrong. Note that no transactions need to be rolled back , on either branch. In the event of this kind of fork, dapps depending on information from a separated validator just have to wait longer to get their result. When the default set is wrong : First off, this is a very delicate situation and it should be rare . The default set uses consensus among attestation providers which have been chosen due to their merits as FTSO data providers. The fact that more than 50% of them are reporting data inconsistent with reality can be considered a 51% attack . The operator of the separated validator, upon convincing themselves that their branch is the correct one (it matches reality) they need to bring the fork to the attention of the misbehaving attestation providers' operators. All validators in the default state then need to roll back to the last correct state (reverting transactions) and continue from there on the forked branch, which becomes the new default state. Fork resolution when the default set is wrong. Note that stopped nodes can resume now, and they never had to roll back any transaction . In summary, validators using at least one reliable local attestation provider do not have to worry about rollbacks, even in the face of 51% attacks . Attestation Types # Some attestation types are already defined. Attestation providers provide attestations for these types of defined requests: Payment : Whether a payment transaction occurred in which funds were sent from one address to another address. Balance-decreasing transaction : Whether a transaction that might have decreased a balance occurred. This type allows for several possibilities: During a transaction, funds, including fees, were deducted from the balance at an address. As a result, the final balance at the address is less than the balance was before the transaction. During a transaction, funds to pay for fees were deducted from the balance at an address at the same time as more funds arrived. As a result, the balance at the address experienced a decrease, but the final balance is more than the balance was before the transaction. Confirmed block height : Whether a block on a certain height exists and was confirmed. Referenced payment nonexistence : Whether an account did not receive funds from a different account by a specific deadline. This type can serve as proof that a user's payment obligations to a DeFi protocol have been breached, considering the following cases: The required transaction was not confirmed on time. The required transaction was confirmed on time but failed because of an error made by the sender. Adding New Attestation Types # New real-world event-type integrations are introduced to the State Connector via acceptance by the default attestation providers, without requiring any changes to the core voting or branching protocols described above. This enables rapid deployment of new use-cases without any validator-level code changes. See the state-connector-attestation-types repository for more information.","title":"State Connector"},{"location":"tech/state-connector/#state-connector","text":"","title":"State Connector"},{"location":"tech/state-connector/#introduction","text":"The State Connector is a smart contract running on the Flare network that allows anyone to query non-changing, verifiable information (such as blockchain or geographic data) from outside the Flare network . Data that changes, such as the latest BTC to USD conversion rate, and non-verifiable data, such as data behind a paywall, are not available through the State Connector. The State Connector accesses data in a decentralized manner (no single party is in control of the process) and securely (it takes a lot of effort to disrupt the process). This is accomplished by using a set of independent attestation providers which fetch the required information from the world and deliver it to the Flare network. The State Connector smart contract then checks if there is enough consensus among the received answers and publishes the results if so. As an added security measure, individual validators can also define local attestation providers which, when in disagreement with the rest, cause the validator to branch into an idle, safe state while the situation is resolved. The State Connector. The State Connector can, for instance, check whether a deposit has been made on another blockchain , opening the door to more advanced mechanisms like the FAsset or the Layer Cake bridges. This page gives technical details about the whole procedure, the different security and scalability measures that have been taken into account in its design and the kind of queries that can be performed.","title":"Introduction"},{"location":"tech/state-connector/#procedure-overview","text":"This is how user queries are processed. The following sections contain more details. State Connector procedure overview.","title":"Procedure Overview"},{"location":"tech/state-connector/#1-request","text":"Anybody, be it a smart contract running on Flare or an application, can request the attestation of a specific event from the State Connector. Requests are yes/no questions regarding things that happened outside the Flare network, for example, \"Has transaction 0xABC been confirmed on the Bitcoin network enough times?\". The answers, though, might contain any kind of additional data attached, like the content of transaction 0xABC, for example. Requests must adhere to one of the available request types , which have been designed to be strictly decidable , i.e., the answers are objective and cannot be argued. Otherwise, queries like \"What is the weather like in Paris?\" would have a hard time reaching consensus among the different attestation providers. Section Adding New Attestation Types below contains more details. Making a request (for App developers) Make your requests using the requestAttestations method (#2) of the StateConnector contract : function requestAttestations ( bytes calldata data ) external ; The requestAttestations method has a single parameter, data , which is a byte array with a content that depends on the desired request type . You can learn how to build this array in the state-connector-attestation-types repository .","title":"1. Request"},{"location":"tech/state-connector/#2-request-forwarding","text":"The State Connector simply forwards the request to all connected attestation providers through an EVM event. Therefore, the request is not stored on the blockchain and its gas cost is very low for the requester.","title":"2. Request forwarding"},{"location":"tech/state-connector/#3-data-retrieval","text":"Attestation providers fetch the requested data by means that depend on the type of attestation, for example, retrieving data from another blockchain or public API. Keep in mind that attestation providers are not controlled by Flare in any way. Anybody can listen to the request events and provide answers using any combination of hardware, software, and code they see fit.","title":"3. Data retrieval"},{"location":"tech/state-connector/#4-attestation","text":"To prevent attestation providers from peeking at each other's answers, these are submitted in a \"Commit and Reveal\" fashion called the CCCR protocol and detailed below. Submitting an attestation (For attestation provider developers) Attestation providers use the submitAttestation method (#3) of the StateConnector contract : function submitAttestation ( uint256 _bufferNumber , bytes32 _commitHash , bytes32 _merkleRoot , bytes32 _randomNumber ) external returns ( bool _isInitialBufferSlot ); Keep reading to understand the meaning of the parameters. More information in the Attestation Client repository .","title":"4. Attestation"},{"location":"tech/state-connector/#5-consensus","text":"If at least 50% of the attestation providers submitted the same answer, it is made public. Otherwise, no consensus is achieved : requests remain unanswered and must be issued again. The answers are stored in the State Connector smart contract for a week , where anybody can read them, including the original requester. Retrieving your request's answer (for App developers) To retrieve the stored answers just read the merkleRoots public array (#8) in the StateConnector contract . More information on how to retrieve a particular answer in the State Connector contract source code . As shown below, multiple answers are actually packed into a single Merkle root. The Attestation Packing section explains how to retrieve an individual answer.","title":"5. Consensus"},{"location":"tech/state-connector/#attestation-protocols","text":"For simplicity, the above description omitted two very important mechanisms , reviewed here. The main one is Attestation packing , which decouples the number of requests from the number of answers, effectively providing unbounded scalability. It requires requests to be first collected and then answered all at once , so a protocol called CCCR is used.","title":"Attestation Protocols"},{"location":"tech/state-connector/#overlapped-cccr-protocol","text":"Requests and answers are submitted sequentially in attestation rounds . Each attestation round has 4 consecutive phases, called Collect, Choose, Commit and Reveal. Phases happen in 90-second windows, and the Choose and Commit phases share the same window, so a whole attestation round takes 4.5 minutes. The Collect-Choose-Commit-Reveal (CCCR) protocol. Collect phase : Users send their requests to the State Connector contract which forwards them to every attestation provider. Choose phase : Attestation Providers vote on which requests they will be able to answer in the current round. Commit phase : Attestation providers send obfuscated answers to the State Connector, so they cannot cheat by peeking at each other's submissions. Reveal phase : Attestation providers send the deobfuscation key so their previous answers are revealed. When all data is available, answers are made public if there is enough consensus. The CCCR protocol is akin to making submissions in a closed envelope which is not opened until all submissions are received. Results are available at the end of the Reveal phase, so the answer to a particular request can take anywhere from 3 to 4.5 minutes , depending on the time in which the request was made inside the Collect phase. Furthermore, the phases of the CCCR protocol are actually overlapped , so while requests are being collected for round \\((n+2)\\) , answers are being simultaneously committed for the previous round \\((n+1)\\) , and revealed for the round prior to that \\((n)\\) . The CCCR protocol with overlapped phases. This means that new requests can be made without waiting for the previous ones to be completed.","title":"Overlapped CCCR Protocol"},{"location":"tech/state-connector/#attestation-packing","text":"Each round, attestation providers build a Merkle tree with the hashes of all valid answers to the requests that were agreed upon during the \"Choose\" phase . The obtained Merkle root is then called the Attestation Proof , since it is proof of the presence of each individual answer. Finally, the attestation proof is submitted to the State Connector for consensus evaluation. Attestation Proof packing using a Merkle tree. This allows any number of requests to be answered with a single hash , greatly improving scalability . Furthermore, the gas cost for attestation providers is constant each round, no matter how many requests they are answering. A request is only valid (and therefore added to the proof) if it is well-formed and it matches reality . Different providers might have different views on what reality is, and this is why the State Connector runs a consensus algorithm on the received answers. Additionally, the allowed request types are carefully designed to minimize the probability of contention . For example, requiring some time for transactions to settle before inquiring about them, and forcing requests to include the hash of a later block that confirms the transaction. Attestation providers keep the actual retrieved data for a week, in case it contains additional information beyond the yes/no result. Users can request this data directly from the providers through the Proof API . Note Please note that this data is safe to use even though it is obtained directly from the provider, because its hash is consistent with the Attestation Proof agreed upon by the State Connector's consensus. See the \"Proof unpacking\" box below to learn how to verify the data. Additional points worth noting: If two attestation providers observe a different validity for any of the requests in the round, they will submit a completely different Attestation Proof. Attestation providers must answer all agreed-upon queries in the round or abstain from participating in the round , otherwise, their Merkle tree root will not match other providers and will probably be discarded by consensus. Hashes are sorted before being added to the tree, just to have a consistent ordering (albeit arbitrary). The exact way in which the root hash is calculated can be changed without impacting the State Connector contract, which will continue to vote only on the hash value. Proof Unpacking (for App developers) The procedure for apps to check whether the State Connector answered yes or no to their request is detailed in the Attestation Client repository . What follows is an illustrative summary. The basic idea is that you must retrieve all data (both requests and answers) for the round from an attestation provider. You then rebuild the Merkle tree with this data and check that it matches the Attestation Proof provided by the State Connector. Proof unpacking. In the attestation round after you made the request (3 attestation phases, so from 3 to 4.5 minutes) the Attestation Proof for the round should be available in the State Connector. Retrieve it using method getAttestation (#7) of the StateConnector contract . Select any attestation provider you want and use the Proof API path api/proof/votes-for-round/{roundId} to retrieve all data for the round . Rebuild the Merkle tree for the retrieved data. There are tools to help you, like the MerkleTree.ts library. Check that the tree's root matches the Attestation Proof from step 1. If it does not match, this provider did not submit the answer agreed by the majority. Choose another provider in step 2. Conversely, you can use the api/proof/get-specific-proof API in step 2 which does steps 2, 3 and 4 for you. This API returns the JSON response data, including the attestation proof, if the attestation request was successfully verified in the given round. Now that you know that the retrieved data has been agreed upon by the consensus, you can use it. Look for your request inside the returned data . If it is not present, your request was deemed invalid (for example, the queried transaction was not present). Otherwise, your request is valid and you can find any extra information about it in the data array.","title":"Attestation Packing"},{"location":"tech/state-connector/#branching-protocol","text":"Besides the consensus algorithm that runs on all received attestations, the State Connector provides one further security mechanism : the ability of any individual validator node to fork and halt execution if attestation providers specially trusted by it disagree with the majority.","title":"Branching Protocol"},{"location":"tech/state-connector/#attestation-provider-sets","text":"To achieve this, two sets of attestation providers are defined: Default attestation providers set Anybody can submit attestations to the State Connector, but the contract will only accept submissions from attestation providers in the default set . Every validator node in the Flare network relies on this set. Local attestation providers set Additionally, each node operator can provide a list of local attestation providers to be accepted besides the ones from the default set. Local providers are the same kind of nodes as default providers, and they are treated exactly the same by the State Connector. Furthermore, providers can belong to both sets. Default and Local attestation providers. Then, for an attestation round to succeed these three conditions must be met: The default set must agree on a result (50% consensus inside the set). The local set must agree on a result too (50% consensus inside the set). Both results must match . Otherwise, the round is undecided and no answer is made public. This gives local attestation providers the capacity to stop results from being approved if they don't agree with their own observations. Ideally, local providers are managed by the same entity controlling the validator node using them, so they can be trusted implicitly . As a consequence of different validators using different attestation providers, sometimes State Connector queries can get different results on some validators, which naturally leads to chain forks . Typically, blockchains allow every branch in a fork to coexist and grow independently , until the discrepancy is detected and resolved. At that point, any branches deemed invalid are removed and all the validators that were following them experience a rollback : All transactions that happened after the fork are reverted and the state of those validators is synchronized with the rest of the network. When dealing with forks caused by the State Connector, the Flare network implements an extra security measure : Validators whose local attestation providers disagree with the default set halt execution after the fork , ensuring that they will not suffer any rollback once the fork is resolved. In other words, these validators remain in a safe state in which the disputed query is undecided and therefore no action is taken based on it. Example State Connector forks. In the example picture , all validator nodes use the attestation providers from the default set (not shown), but validators on the rightmost column, additionally, employ local providers . One of them returns a different answer for one of the queries, which leads to a fork of the chain since that validator's state does not match the rest of the network (the divergent ledger, depicted in red). The next section shows how forks are resolved and halted nodes restarted.","title":"Attestation Provider Sets"},{"location":"tech/state-connector/#branch-resolution","text":"The two states of the branching protocol. The picture above shows the state of the network after a fork. The default network state is the one followed by validators which only use the default set of attestation providers . The alternate network state is where validators go if they use local attestation providers , and they disagree with the default set. In the alternate state no queries are answered and no blocks are produced , so it is a safe state for validators to wait for forks to be resolved. This resolution must come from operators when they are alerted that a validator node has stopped. To understand how to do this, note that attestations are designed to be objectively decidable , meaning that in the event of a fork one branch matches reality and the other does not . There are therefore only two ways to resolve a fork: When local providers are wrong : The operator of the separated validator needs to find out why the local attestation providers failed and either fix them or remove them from the local set of the validator. Once this is fixed, the node simply rewinds its state to where it split and quickly fast-forward to rejoin the default state. Fork resolution when local providers are wrong. Note that no transactions need to be rolled back , on either branch. In the event of this kind of fork, dapps depending on information from a separated validator just have to wait longer to get their result. When the default set is wrong : First off, this is a very delicate situation and it should be rare . The default set uses consensus among attestation providers which have been chosen due to their merits as FTSO data providers. The fact that more than 50% of them are reporting data inconsistent with reality can be considered a 51% attack . The operator of the separated validator, upon convincing themselves that their branch is the correct one (it matches reality) they need to bring the fork to the attention of the misbehaving attestation providers' operators. All validators in the default state then need to roll back to the last correct state (reverting transactions) and continue from there on the forked branch, which becomes the new default state. Fork resolution when the default set is wrong. Note that stopped nodes can resume now, and they never had to roll back any transaction . In summary, validators using at least one reliable local attestation provider do not have to worry about rollbacks, even in the face of 51% attacks .","title":"Branch Resolution"},{"location":"tech/state-connector/#attestation-types","text":"Some attestation types are already defined. Attestation providers provide attestations for these types of defined requests: Payment : Whether a payment transaction occurred in which funds were sent from one address to another address. Balance-decreasing transaction : Whether a transaction that might have decreased a balance occurred. This type allows for several possibilities: During a transaction, funds, including fees, were deducted from the balance at an address. As a result, the final balance at the address is less than the balance was before the transaction. During a transaction, funds to pay for fees were deducted from the balance at an address at the same time as more funds arrived. As a result, the balance at the address experienced a decrease, but the final balance is more than the balance was before the transaction. Confirmed block height : Whether a block on a certain height exists and was confirmed. Referenced payment nonexistence : Whether an account did not receive funds from a different account by a specific deadline. This type can serve as proof that a user's payment obligations to a DeFi protocol have been breached, considering the following cases: The required transaction was not confirmed on time. The required transaction was confirmed on time but failed because of an error made by the sender.","title":"Attestation Types"},{"location":"tech/state-connector/#adding-new-attestation-types","text":"New real-world event-type integrations are introduced to the State Connector via acceptance by the default attestation providers, without requiring any changes to the core voting or branching protocols described above. This enables rapid deployment of new use-cases without any validator-level code changes. See the state-connector-attestation-types repository for more information.","title":"Adding New Attestation Types"},{"location":"tech/the-flaredrop/","text":"The FlareDrop # The FlareDrop, previously called the Delegation Incentive Pool in the FIP.01 , is a distribution method for the 24.25B remaining $FLR tokens after the original airdrop . It will last for 36 months and is destined for any holder of wrapped $FLR ( $WFLR ) that participates in the network as per the FIP.01. If you enabled your PDA and it contains $WFLR , it is also eligible to receive the FlareDrop distribution. Make sure to check both your Main Account and your Delegation Account for FlareDrop to claim. How Is the FlareDrop Distributed? # The FlareDrop is distributed monthly over 36 30-day bank months to those that wrap their $FLR tokens. Each of the first 35 monthly allocations constitute 2.37% of the total FlareDrop, and the last one 2.05%. The total amount of $WFLR is calculated each month, and the monthly allocation is distributed among all $WFLR holders proportionally to the sampled average of their $WFLR balance. Users then receive an amount equal to their month's sampled $WFLR holdings divided by the month's total $WFLR , multiplied by the monthly allocation. Calculating an address's sampled average balance As each bank month passes, the FlareDrop receives a trigger to choose 3 random blocks in the previous 23 days. The FlareDrop smart contract then finds the average of the total $WFLR reported in those blocks and determines each address's percentage of the FlareDrop. 3-week average of wrapped $FLR . Upon claiming, the entitlement is sent directly to the account you claimed from. It is sent as $FLR to your Main Account and as $WFLR to your Personal Delegation Account (PDA) . Each distribution expires two bank months and a week (67 days) after it becomes claimable and expired tokens are burned. To ensure having no effect on the amount of $FLR that each claiming address receives, Flare Foundation and team addresses opt out of the FlareDrop distribution. Two steps to ensure receiving all your $FLR ! You must: Wrap $FLR to receive it. Rewards are proportional to the $WFLR balance, not $FLR , so always wrap as much $FLR as you can! Wrapping has no downside: Wrapped tokens continue to be available for delegation and governance voting , for example, and they can be unwrapped at any time. Claim before the distribution expires. After the distribution becomes claimable, it expires in two bank months and a week (67 days). You can also enable automatic claiming to make sure you don't miss any FlareDrop! Autoclaiming will claim for both your main account and your PDA if you enabled it. Related User Guides # Claiming the FlareDrop Wrapping tokens Related Developer Docs # The FlareDrop","title":"The FlareDrop"},{"location":"tech/the-flaredrop/#the-flaredrop","text":"The FlareDrop, previously called the Delegation Incentive Pool in the FIP.01 , is a distribution method for the 24.25B remaining $FLR tokens after the original airdrop . It will last for 36 months and is destined for any holder of wrapped $FLR ( $WFLR ) that participates in the network as per the FIP.01. If you enabled your PDA and it contains $WFLR , it is also eligible to receive the FlareDrop distribution. Make sure to check both your Main Account and your Delegation Account for FlareDrop to claim.","title":"The FlareDrop"},{"location":"tech/the-flaredrop/#how-is-the-flaredrop-distributed","text":"The FlareDrop is distributed monthly over 36 30-day bank months to those that wrap their $FLR tokens. Each of the first 35 monthly allocations constitute 2.37% of the total FlareDrop, and the last one 2.05%. The total amount of $WFLR is calculated each month, and the monthly allocation is distributed among all $WFLR holders proportionally to the sampled average of their $WFLR balance. Users then receive an amount equal to their month's sampled $WFLR holdings divided by the month's total $WFLR , multiplied by the monthly allocation. Calculating an address's sampled average balance As each bank month passes, the FlareDrop receives a trigger to choose 3 random blocks in the previous 23 days. The FlareDrop smart contract then finds the average of the total $WFLR reported in those blocks and determines each address's percentage of the FlareDrop. 3-week average of wrapped $FLR . Upon claiming, the entitlement is sent directly to the account you claimed from. It is sent as $FLR to your Main Account and as $WFLR to your Personal Delegation Account (PDA) . Each distribution expires two bank months and a week (67 days) after it becomes claimable and expired tokens are burned. To ensure having no effect on the amount of $FLR that each claiming address receives, Flare Foundation and team addresses opt out of the FlareDrop distribution. Two steps to ensure receiving all your $FLR ! You must: Wrap $FLR to receive it. Rewards are proportional to the $WFLR balance, not $FLR , so always wrap as much $FLR as you can! Wrapping has no downside: Wrapped tokens continue to be available for delegation and governance voting , for example, and they can be unwrapped at any time. Claim before the distribution expires. After the distribution becomes claimable, it expires in two bank months and a week (67 days). You can also enable automatic claiming to make sure you don't miss any FlareDrop! Autoclaiming will claim for both your main account and your PDA if you enabled it.","title":"How Is the FlareDrop Distributed?"},{"location":"tech/the-flaredrop/#related-user-guides","text":"Claiming the FlareDrop Wrapping tokens","title":"Related User Guides"},{"location":"tech/the-flaredrop/#related-developer-docs","text":"The FlareDrop","title":"Related Developer Docs"},{"location":"tech/validators/","text":"Validator Nodes # Blockchain Validation # Validator nodes are online servers running a blockchain's client software. They all keep their own copy of the ledger and are constantly talking to other nodes to make sure the copies are consistent with each other as new data is added. A network of validator nodes, each one with an identical copy of the ledger. The fact that the ledger is not under control of a single entity but distributed among a network of independent validators is what makes blockchains: Require less trust than traditional options. Censorship resistant. Byzantine fault-tolerant . Validators agree on the state of the ledger using a consensus algorithm that varies for each blockchain. For example, Flare uses the Snowman++ consensus protocol from Avalanche . Snowman++ During each round, a validator is randomly selected to act as the leader and propose new blocks to be added to the ledger, which are then validated by the rest of nodes. To provide Sybil resistance , the probability that a node is elected the leader is proportional to the node's stake , effectively enacting a proof-of-stake consensus. With its vision to be the blockchain for data, Flare adds the FTSO Data provider and Attestation Provider roles to validators, creating a single infrastructure entity . When fully operational, these decentralized infrastructure entities are responsible for: Securing the network through proof-of-stake consensus. Providing continuous data to the FTSO system. Answering the State Connector's queries for attestations. In this way, the stake required to operate these entities secures all three functions. Infrastructure entities are rewarded for each one of these roles, a process that involves staking on the P-chain and rewards that are calculated on smart contracts running on the C-chain . Deployment Phases # Deployment will occur in different phases for a number of reasons: Infrastructure entities will be onboarded progressively, to ensure the uninterrupted working of the network. Current FTSO data providers need to build a minimum stake to act as validators. Current validators need to upgrade their capabilities to act as data providers. Each phase will increasingly relinquish control, so more network validation will happen independently of the Flare Foundation. Initial State # Upon network launch on July 14th 2022, a set of 20 validators had their node IDs hard-coded into the client software, so no other validators could participate. The Flare Foundation managed these nodes and gradually reassigned 16 of them to 4 external entities to achieve greater decentralization. These entities, known as professional validators, are infrastructure providers with experience managing blockchain nodes. During this period FTSO data providers operated completely independently of validators. The State Connector protocol was still being developed, so no attestation providers were available. Phase 1 # On July 2023 a network fork enabled Avalanche's proof-of-stake mechanism. From this moment, validation was open to everybody. At the same time, all the stake from the original validators expired. The Flare Foundation loaned all the stake for the initial validators, so the distribution of validation power remained the same while proof-of-stake was being tested. Later, after some FTSO data providers went through a KYC process, the Flare Foundation loaned enough funds to them to deploy validation nodes and act as validators. Because staking happens on the P-chain , staked tokens cannot access the rewards managed by smart contracts running on the C-chain . To solve this problem, a communication mechanism between the two chains is being developed. All staking rewards are manually calculated off-chain, and then distributed on-chain. The calculations will initially be private while they are fine-tuned, and the script will be made public in phase 2 so that anybody can verify them. Phase 2 # Once FTSO data providers have gathered enough stake to ensure the network's continued working, all stake loaned by the Flare Foundation to the validators in the initial state will be withdrawn. Professional validators are expected to cease operating at this point, unless they provide their own stake. The Flare Foundation might delegate stake to FTSO data providers that went through the KYC process, to help kick-start the system. This is known as stake boosting and will run only for a limited amount of time. Staked funds can earn FlareDrops and participate in governance , but not earn FTSO rewards . Staking rewards will: Take into account validator uptime, which can be publicly monitored. Take into account staked amount. Require that the validator is also an FTSO data provider that is being constantly rewarded for providing good enough prices. Be manually calculated off-chain using a public script, and then distributed on-chain. Phase 3 # After secure communication between the P- and C-chains is available, staking rewards will be managed entirely on-chain. The goal is that funds staked on the P-chain will have the same rights as wrapped $FLR on the C-chain, opening the possibility to earn FTSO rewards , FlareDrops and participate in governance . Summary # Launch Phase 1 Phase 2 Phase 3 Validation open to everybody \u2718 \u2714 \u2714 \u2714 Validators must provide own stake \u2718 \u2718 \u2714 \u2714 Validators must be data providers to earn rewards \u2718 \u2718 \u2714 \u2714 Locked stake can earn staking rewards \u2718 \u2718 \u2714 \u2714 Staking rewards are handled on-chain \u2718 \u2718 \u2718 \u2714 Same rights for staked and wrapped tokens \u2718 \u2718 \u2718 \u2714 Related Infrastructure Guides # Deploying a Validator Node const btables = document.getElementsByClassName('boolean-table'); if (btables) { for (var i=0; i + + + https://docs.flare.network/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/AddressUpdatable/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/AddressUpdater/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/CheckPointable/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/ClaimSetupManager/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/CleanupBlockNumberManager/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/CloneFactory/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/Delegatable/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/FlareContractRegistry/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/FlareDaemon/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/Ftso/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/FtsoManager/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/FtsoRegistry/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/FtsoRewardManager/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/GovernanceSettings/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/GovernanceVotePower/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/Governed/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/GovernedAndFlareDaemonized/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/GovernedAtGenesis/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/GovernedBase/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IClaimSetupManager/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IFlareContractRegistry/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IFlareDaemonize/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IFtso/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IFtsoGenesis/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IFtsoManager/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IFtsoManagerGenesis/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IFtsoRegistry/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IFtsoRegistryGenesis/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IFtsoRewardManager/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IGovernanceSettings/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IGovernanceVotePower/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IIAddressUpdatable/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IIAddressUpdater/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IIClaimSetupManager/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IICleanable/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IIFtso/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IIFtsoManager/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IIFtsoRegistry/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IIFtsoRewardManager/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IIGovernanceVotePower/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IIInflationReceiver/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IIPriceSubmitter/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IITokenPool/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IIVPContract/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IIVPToken/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IIVoterWhitelister/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IInflationGenesis/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IPriceSubmitter/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IVPContractEvents/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IVPToken/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IVoterWhitelister/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/IWNat/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/Inflation/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/PriceSubmitter/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/RevertErrorTracking/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/VPContract/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/VPToken/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/VoterWhitelister/ + 2023-10-04 + daily + + + https://docs.flare.network/apis/smart-contracts/WNat/ + 2023-10-04 + daily + + + https://docs.flare.network/dev/ + 2023-10-04 + daily + + + https://docs.flare.network/dev/external-resources/ + 2023-10-04 + daily + + + https://docs.flare.network/dev/tools/ + 2023-10-04 + daily + + + https://docs.flare.network/dev/getting-started/ + 2023-10-04 + daily + + + https://docs.flare.network/dev/getting-started/contract-addresses/ + 2023-10-04 + daily + + + https://docs.flare.network/dev/getting-started/setup/ + 2023-10-04 + daily + + + https://docs.flare.network/dev/getting-started/setup/foundry/ + 2023-10-04 + daily + + + https://docs.flare.network/dev/getting-started/setup/hardhat/ + 2023-10-04 + daily + + + https://docs.flare.network/dev/getting-started/setup/remix/ + 2023-10-04 + daily + + + https://docs.flare.network/dev/getting-started/setup/truffle/ + 2023-10-04 + daily + + + https://docs.flare.network/dev/reference/ + 2023-10-04 + daily + + + https://docs.flare.network/dev/reference/automatic-claiming/ + 2023-10-04 + daily + + + https://docs.flare.network/dev/reference/explorers-and-indexers/ + 2023-10-04 + daily + + + https://docs.flare.network/dev/reference/network-config/ + 2023-10-04 + daily + + + https://docs.flare.network/dev/reference/personal-delegation-account/ + 2023-10-04 + daily + + + https://docs.flare.network/dev/reference/the-flaredrop/ + 2023-10-04 + daily + + + https://docs.flare.network/dev/reference/wallets/ + 2023-10-04 + daily + + + https://docs.flare.network/dev/tutorials/ + 2023-10-04 + daily + + + https://docs.flare.network/dev/tutorials/ftso/ + 2023-10-04 + daily + + + https://docs.flare.network/dev/tutorials/ftso/getting-data-feeds/ + 2023-10-04 + daily + + + https://docs.flare.network/dev/tutorials/network-access/ + 2023-10-04 + daily + + + https://docs.flare.network/dev/tutorials/network-access/obtaining-revert-reason/ + 2023-10-04 + daily + + + https://docs.flare.network/dev/tutorials/network-access/reliable-event-reading/ + 2023-10-04 + daily + + + https://docs.flare.network/dev/tutorials/network-access/transaction-finalization/ + 2023-10-04 + daily + + + https://docs.flare.network/exchange/ + 2023-10-04 + daily + + + https://docs.flare.network/exchange/architecture/ + 2023-10-04 + daily + + + https://docs.flare.network/exchange/delegation/ + 2023-10-04 + daily + + + https://docs.flare.network/exchange/troubleshooting/ + 2023-10-04 + daily + + + https://docs.flare.network/infra/ + 2023-10-04 + daily + + + https://docs.flare.network/infra/attestation/ + 2023-10-04 + daily + + + https://docs.flare.network/infra/attestation/operating/ + 2023-10-04 + daily + + + https://docs.flare.network/infra/data/ + 2023-10-04 + daily + + + https://docs.flare.network/infra/data/operating/ + 2023-10-04 + daily + + + https://docs.flare.network/infra/data/whitelisting/ + 2023-10-04 + daily + + + https://docs.flare.network/infra/data/managing-ecosystem/ + 2023-10-04 + daily + + + https://docs.flare.network/infra/data/managing-ecosystem/exploring-collusion/ + 2023-10-04 + daily + + + https://docs.flare.network/infra/data/managing-ecosystem/monitoring-price-history/ + 2023-10-04 + daily + + + https://docs.flare.network/infra/observation/ + 2023-10-04 + daily + + + https://docs.flare.network/infra/observation/deploying/ + 2023-10-04 + daily + + + https://docs.flare.network/infra/observation/faq/ + 2023-10-04 + daily + + + https://docs.flare.network/infra/validation/ + 2023-10-04 + daily + + + https://docs.flare.network/infra/validation/deploying/ + 2023-10-04 + daily + + + https://docs.flare.network/infra/validation/staking-cli/ + 2023-10-04 + daily + + + https://docs.flare.network/tech/ + 2023-10-04 + daily + + + https://docs.flare.network/tech/api-portal/ + 2023-10-04 + daily + + + https://docs.flare.network/tech/automatic-claiming/ + 2023-10-04 + daily + + + https://docs.flare.network/tech/flare-beta/ + 2023-10-04 + daily + + + https://docs.flare.network/tech/flare/ + 2023-10-04 + daily + + + https://docs.flare.network/tech/ftso/ + 2023-10-04 + daily + + + https://docs.flare.network/tech/glossary/ + 2023-10-04 + daily + + + https://docs.flare.network/tech/governance/ + 2023-10-04 + daily + + + https://docs.flare.network/tech/personal-delegation-account/ + 2023-10-04 + daily + + + https://docs.flare.network/tech/state-connector/ + 2023-10-04 + daily + + + https://docs.flare.network/tech/the-flaredrop/ + 2023-10-04 + daily + + + https://docs.flare.network/tech/validators/ + 2023-10-04 + daily + + + https://docs.flare.network/tech/archive/ + 2023-10-04 + daily + + + https://docs.flare.network/tech/archive/flare-launch-process/ + 2023-10-04 + daily + + + https://docs.flare.network/user/ + 2023-10-04 + daily + + + https://docs.flare.network/user/automatic-claiming/ + 2023-10-04 + daily + + + https://docs.flare.network/user/claiming-the-flaredrop/ + 2023-10-04 + daily + + + https://docs.flare.network/user/personal-delegation-account/ + 2023-10-04 + daily + + + https://docs.flare.network/user/wrapping-tokens/ + 2023-10-04 + daily + + + https://docs.flare.network/user/block-explorers/ + 2023-10-04 + daily + + + https://docs.flare.network/user/block-explorers/finding-reward-epoch/ + 2023-10-04 + daily + + + https://docs.flare.network/user/block-explorers/managing-delegations/ + 2023-10-04 + daily + + + https://docs.flare.network/user/block-explorers/managing-rewards/ + 2023-10-04 + daily + + + https://docs.flare.network/user/block-explorers/user-interface/ + 2023-10-04 + daily + + + https://docs.flare.network/user/block-explorers/verifying-vote-power-block/ + 2023-10-04 + daily + + + https://docs.flare.network/user/block-explorers/viewing-nfts/ + 2023-10-04 + daily + + + https://docs.flare.network/user/block-explorers/viewing-token-balances/ + 2023-10-04 + daily + + + https://docs.flare.network/user/block-explorers/viewing-token-transfers/ + 2023-10-04 + daily + + + https://docs.flare.network/user/block-explorers/viewing-transactions/ + 2023-10-04 + daily + + + https://docs.flare.network/user/delegation/ + 2023-10-04 + daily + + + https://docs.flare.network/user/delegation/managing-delegations/ + 2023-10-04 + daily + + + https://docs.flare.network/user/delegation/managing-rewards/ + 2023-10-04 + daily + + + https://docs.flare.network/user/governance/ + 2023-10-04 + daily + + + https://docs.flare.network/user/governance/voting/ + 2023-10-04 + daily + + + https://docs.flare.network/user/wallets/ + 2023-10-04 + daily + + + https://docs.flare.network/user/wallets/bifrost-wallet/ + 2023-10-04 + daily + + + https://docs.flare.network/user/wallets/brave-wallet/ + 2023-10-04 + daily + + + https://docs.flare.network/user/wallets/dcent-wallet/ + 2023-10-04 + daily + + + https://docs.flare.network/user/wallets/enkrypt-wallet/ + 2023-10-04 + daily + + + https://docs.flare.network/user/wallets/how-to-access-flare-network-with-a-ledger-device/ + 2023-10-04 + daily + + + https://docs.flare.network/user/wallets/how-to-access-flare-network-with-a-trezor-device/ + 2023-10-04 + daily + + + https://docs.flare.network/user/wallets/how-to-access-flare-network-with-metamask/ + 2023-10-04 + daily + + + https://docs.flare.network/user/wallets/safepal-s1-wallet/ + 2023-10-04 + daily + + \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz new file mode 100644 index 000000000..9f5e546ad Binary files /dev/null and b/sitemap.xml.gz differ diff --git a/tech-icon.svg b/tech-icon.svg new file mode 100644 index 000000000..f14eacf80 --- /dev/null +++ b/tech-icon.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tech/api-portal/index.html b/tech/api-portal/index.html new file mode 100644 index 000000000..8185ff7f7 --- /dev/null +++ b/tech/api-portal/index.html @@ -0,0 +1,3830 @@ + + + + + + + + + + + + + + + + + + Flare API Portal - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Flare API Portal#

    +

    Flare's API Portal is a paid product that gives developers access to a number of private nodes running on different blockchains, including Flare, Songbird and Coston, but also other networks like Bitcoin or XRPL.

    +

    These nodes are not rate-limited, so it is typically more convenient to connect your apps to them than to deploy your own nodes, or connect to public nodes.

    +

    This is one more step towards Flare's goal to connect all blockchains.

    + +
    +

    Visit the API Portal's FAQ if you are having authentication issues!

    +
    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tech/archive/flare-launch-process/index.html b/tech/archive/flare-launch-process/index.html new file mode 100644 index 000000000..3db0bb7c2 --- /dev/null +++ b/tech/archive/flare-launch-process/index.html @@ -0,0 +1,4176 @@ + + + + + + + + + + + + + + + + + + Flare Launch Process - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + + + + +
    +
    + + + + + + + + + + +

    Flare Launch Process#

    +

    The Flare launch included a rather large airdrop, a community vote, and the deployment of a novel meritocratic consensus system. +Because of its complexity, it was divided into a series of sequential phases with clearly-defined triggers that signaled each transition.

    +

    The following information was intended to remove any confusion around the launch process by clearly describing the purpose of each phase and what happened in them.

    +

    + + Click on a phase to navigate to its description. + + + + + + + + + + + + + + + + + + + + + + + + +

    +

    Definitions#

    +

    The following definitions make the rest of this page clear and unambiguous.

    +
      +
    • +

      FIP.01: A governance proposal that, among other things, changed the initial token distributions as explained below. +This proposal needed to be voted on according to the schedule described in this page.

      +
    • +
    • +

      Flare Airdrop for XRP Holders: Certain holders of XRP tokens on Dec 12, 2020, were eligible to register for the FLR token distribution (then called Spark tokens) once the Flare network launched.

      +

      The FIP.01 proposal modified the way in which the airdrop worked.

      +
    • +
    • +

      Original Airdrop: 28.53B FLR tokens, which in the original distribution plan went to those who registered for the distribution.

      +
    • +
    • +

      New Airdrop: 4.28B FLR tokens destined for those that registered for the distribution.

      +
    • +
    • +

      Delegation Incentive Pool (DIP): 24.25B FLR tokens destined for any Flare holder that participated in the network over 36 months as per the FIP.01 distribution plan.

      +

      Note that the New Airdrop plus the DIP match the Original Airdrop.

      +
    • +
    • +

      Token Distribution Event (TDE): The moment when the initial $FLR tokens were distributed to those who registered for the $FLR token distribution. +These tokens were minted and locked when the network was created, and they were released when it was sufficiently decentralized.

      +
    • +
    +

    Token Distribution Plans#

    +

    The following distribution plans were offered. The FIP.01 Distribution Plan was implemented after FIP.01 was approved.

    +
      +
    • +

      Original Distribution Plan:

      +
        +
      • 15% of the original airdrop would have been sent to those who registered for the $FLR distribution upon the TDE, and the rest would have been delivered monthly over the subsequent 36 months.
      • +
      • Inflation would have been 10% of the fully diluted supply, per annum.
      • +
      +
    • +
    • +

      FIP.01 Distribution Plan:

      +
        +
      • The new airdrop was sent to those who registered for the $FLR distribution upon the TDE, and the DIP was distributed to all $FLR token holders (actually, wrapped $FLR holders) over 36 months. Flare employees and companies were excluded.
      • +
      • Inflation is 10% of available supply in the first year, then 7% the following year, 5% the year after and in perpetuity, except that from year 3 onwards inflation is capped at 5bn $FLR per year.
      • +
      • Inflation distribution: 70% to FTSO rewards, 20% to validator rewards and 10% to the default Attestation Provider Set of the state connector.
      • +
      +
    • +
    +

    Launch Phases#

    +

    Private Observation Mode#

    +
    +

    Trigger: The Flare network launches

    +
    +

    On July 14, 2022, the network started centralized, with only 21 validators, run by the Flare Foundation.

    +

    Flare validator source code was not available yet.

    +

    FTSO data providers:

    + +
    +

    Public Observation Mode#

    +
    +

    Trigger: The Flare validator source code becomes publicly available

    +
    +

    During this mode, professional validators started onboarding, so the network started to become decentralized.

    +

    FTSO data providers:

    + +
    +

    Initial Distribution Period#

    +
    +

    Trigger: 66% of validator power is independent of Flare,
    AND
    Exchanges agree to distribute the $FLR token to their customers within a few days of the TDE

    +
    +
    +

    Token Distribution Event (TDE) happens

    +

    The new airdrop was sent to the Flare addresses provided by $XRP token holders when they claimed.

    +

    Part of the airdrop went to Exchange accounts, which distributed it to the users that originally claimed (the intended recipients).

    +
    +

    During this period, Flare monitored how many of the airdrop tokens reached the intended recipients, by following the Exchange's communication channels.

    +

    FTSO data providers:

    + +

    FTSO and validator rewards were enabled. +Inflation was not burned anymore.

    +
    +

    FIP.01 Notice Period#

    +
    +

    Trigger: 66% of the new airdrop reaches its intended recipients

    +
    +

    FIP.01 proposed to modify how the rest of the tokens (after the TDE) would be distributed, so it required the community to vote. +Users voted with their $FLR token stake, so voting could not start until enough tokens had reached the intended recipients.

    +

    After 66% of the FLR tokens distributed during the TDE reached these users, a 1-week notice period began.

    +

    Flare announced to the community that enough tokens were distributed and the notice period had started.

    +
    +

    FIP.01 Voting Period#

    +
    +

    Trigger: 1 week after Notice Period starts

    +
    +

    All $FLR token holders (obtained either from the new airdrop or bought at Exchanges) could vote on FIP.01 using a voting front-end.

    +

    Flare announced to the community that the Voting Period had started and relayed instructions about how to vote.

    +

    Voting Period lasted 1 week.

    +
    +

    Regular Operation (Beta)#

    +
    +

    Trigger: FIP.01 is approved after 1 week of voting

    +
    +

    The changes proposed in FIP.01 were implemented. +The DIP will be distributed to ALL holders of FLR during 37 months.

    +

    Flare Beta is still in operation, but community-run validators are gradually gaining more power.

    +
    +

    Regular Operation#

    +
    +

    Trigger: Community-run FTSO validators are deemed reliable enough

    +
    +

    Flare Beta will end.

    +

    FTSO validators' validation power is not artificially reduced anymore and validator rewards (20% of inflation) will be distributed equally among all validators according to their performance and stake.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tech/archive/index.html b/tech/archive/index.html new file mode 100644 index 000000000..75699457b --- /dev/null +++ b/tech/archive/index.html @@ -0,0 +1,3858 @@ + + + + + + + + + + + + + + + + + + Archive - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    + + + + + + + + + +

    Archive#

    +

    This section archives old information.

    +

    Select one of the topics below:

    + + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tech/automatic-claiming/index.html b/tech/automatic-claiming/index.html new file mode 100644 index 000000000..9dd70299c --- /dev/null +++ b/tech/automatic-claiming/index.html @@ -0,0 +1,4102 @@ + + + + + + + + + + + + + + + + + + Automatic Claiming - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Automatic Claiming#

    +

    Automatic claiming enables users to appoint an executor to claim rewards on their behalf.

    +

    Introduction#

    +

    The Flare network rewards users that contribute to it, for example, by delegating to an FTSO data provider.

    +

    Delegation rewards accrue every 3.5 days when users have delegated wrapped Flare tokens (WFLR) to FTSO data providers. +These rewards must be claimed periodically by users, since rewards expire after a few months.

    +

    For users, claiming rewards can be inconvenient and can risk losing rewards and compound interest if overlooked. +If users are claiming rewards from a cold wallet, they can expose the wallet more often than necessary.

    +

    Instead, users can enlist the services of executors to claim for them, putting the responsibility of remembering to claim on the executor. +Automatic claiming through an executor saves user time and inconvenience, optimizes the opportunity for compound interest, and avoids unnecessary exposure of users' cold wallets.

    +

    Automatic claiming is secure because the executor cannot claim to any address but the ones the user provides. +It is trustless (does not require trust) because it is managed by a smart contract, not the executor.

    +

    For executors, automatic claiming is an opportunity to earn a fee for performing claiming as a service to users.

    +

    How Automatic Claiming Works#

    +

    Without an executor, users need to claim twice a week if they want to benefit from the rewards as soon as possible.

    +
    +

    Claiming Process without Executor +

    +
    The claiming process without an executor.
    +
    +

    With an executor, a third party can claim for users, for an optional fee.

    +
    +

    Claiming Process with Executor +

    +
    The claiming process with an executor.
    +
    +

    There are two ways to claim with an executor: manual and registered. +They both provide "automatic claiming" for the user in the sense that claiming rewards requires no intervention from the user once the executor takes over. +However, when the executor does not register, several parts of the process are not automated, such as finding each other and paying the fee. +The "manual" version is less automated. +The registered version is highly automated.

    +

    Manual Claiming Process#

    +

    If an executor account is not registered, claiming is said to be Manual.

    +

    With Manual claiming users only need to provide the executor's address, which authorizes the executor to claim on the user's behalf. +How the user discovers the executor's address and whether they will pay a service fee can only be settled off-chain.

    +
    +

    Example

    +

    For example, executors could create a dapp where users pay a fee (in fiat or spot) and sign the transaction that sets the executor's address.

    +
    +

    Only reward claiming remains automated, whereby rewards are sent directly to the user's address. +Executors do not receive a fee automatically.

    +

    Here is how the process works when executor claiming is manual:

    +
      +
    1. Users who have accrued rewards and want an executor to claim on their behalf can identify an executor known to them off-chain.
    2. +
    3. These users then make an off-chain agreement with the executor and they exchange addresses.
    4. +
    5. Agreeing to a fee is optional and off-chain. + If they do agree to a fee, they pay manually.
    6. +
    7. Executors claim rewards for one or more users. + Their fees are not automatically deducted from the claimed rewards.
    8. +
    9. Executors notify users off-chain if they discontinue providing this service.
    10. +
    +

    Registered Claiming Process#

    +

    On the other hand, the process can be simplified if the executor address is Registered. +Registration allows accounts to list themselves on-chain as registered executors and post their service fees. +Registration simplifies both the user task of finding a suitable executor and the executor's task, since its fee is automatically transferred when user rewards are claimed. +The users pay a fee to set an executor to claim their rewards and their rewards are claimed automatically, i.e., without their intervention. +With a registered executor, all agreements happen on-chain.

    +

    Here is how the registered claiming process works, with applications performing these actions on behalf of executors and users:

    +
      +
    1. Executors who want to make themselves publicly available to users register as executors, paying a registration fee. +The fee to register as an executor is burned.
    2. +
    3. Registered executors post their fee for claiming rewards.
    4. +
    5. Users who have accrued rewards and want an executor to claim on their behalf can choose from the list of registered executors.
    6. +
    7. These users pay a setup fee to enable a registered executor to claim their rewards. + The fee to enable a registered executor is sent to the executor.
    8. +
    9. Executors claim rewards for one or more users, and their fees are automatically deducted from the claimed rewards.
    10. +
    11. Executors notify users off-chain if they discontinue providing this service.
    12. +
    +

    Throughout the process:

    +
      +
    • Users and executors can see reports on which addresses executors are claiming for and which executors are registered.
    • +
    • Registered executors can change fees or unregister, and users can change the registered executors claiming on their behalf or disable automatic claiming.
    • +
    +

    Other Use Cases#

    +

    Cold Wallets#

    +

    Many users claim from a cold wallet because they can reap the most rewards where they store the greatest share of their holdings. +When they claim from a cold wallet, they are exposing it online. +Setting an executor can protect the cold wallet, as the executor would claim the rewards and pass them on to the user's account automatically without putting the cold wallet online.

    +

    Your Own Executor#

    +

    If a user has multiple addresses, it may be convenient to designate one of their own addresses as an executor, and claim for all of them from it. +Additionally, this avoids the fee that a public executor will typically charge.

    +
    +

    Warning

    +

    By using the automatic claiming feature, neither Flare Foundation nor any of the contracts published on the Flare network guarantee that the selected executor will actually claim any or all of the user’s rewards. +This agreement is solely between the user and the selected executor. +The Flare network offers only the possibility of setting up an automatic execution service and is not liable for any damages if this service is not performed. +For more information, see FLARE TERMS OF SERVICE & PRIVACY POLICY.

    +
    +
    +

    Developing autoclaiming functionality

    +

    For information on how to develop an executor, or how to write an application that supports autoclaiming, see Automatic Claiming in the Developer section.

    +
    + + + + + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tech/flare-beta/index.html b/tech/flare-beta/index.html new file mode 100644 index 000000000..b77647de5 --- /dev/null +++ b/tech/flare-beta/index.html @@ -0,0 +1,3893 @@ + + + + + + + + + + + + + + + + + + Flare Beta - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Flare Beta#

    +

    Decentralization will be achieved by moving the transaction validation duty from the Flare Foundation to community-run FTSO data providers, but this will not happen instantly.

    +

    Instead, to ensure a safe transition, a number of professional validators were initially enabled and continue to be employed.

    +

    The professional validators were chosen among companies with proven experience running blockchain infrastructure and at first held most of the validation power. +This power, though, will be progressively shifted onto the community-run validators until they run the network on their own.

    +

    This initial period is called Flare Beta, and it will span several launch phases.

    +

    Flare Beta Details#

    +

    The Flare Beta began at the same time as the token distribution event (TDE).

    +

    During this period:

    +
      +
    • +

      20 total validators with equal validation power (20K FLR each, initially) are enabled.

      +
        +
      • 4 run by the Flare Foundation.
      • +
      • 16 run by 4 professional validators.
      • +
      +
    • +
    • +

      Each FTSO running an observation node will be a candidate to become a validator node later. These nodes are regularly scanned to ensure they meet security standards. If they meet the security standards, they enable the node operators to receive rewards.

      +
    • +
    • +

      Validator rewards are split 50% for the professional validators and 50% for the FTSOs running observation nodes.

      +
    • +
    • +

      Estimated duration: 6 - 9 months, depending on the evolution of the network.

      +
    • +
    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tech/flare-launch-process/index.html b/tech/flare-launch-process/index.html new file mode 100644 index 000000000..f86f1cef3 --- /dev/null +++ b/tech/flare-launch-process/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tech/flare/index.html b/tech/flare/index.html new file mode 100644 index 000000000..31a0f0780 --- /dev/null +++ b/tech/flare/index.html @@ -0,0 +1,3956 @@ + + + + + + + + + + + + + + + + + + What Is Flare? - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    What Is Flare?#

    +
    +

    Flare logo

    +
    +

    Flare is the blockchain for data. +It is a layer 1, EVM smart contract platform designed to expand the utility of blockchain.

    +

    Flare's aim is to provide data as a public good, meaning that data is not controlled by a centralized entity and is available to all. +The infrastructure providers, which perform doubly as validators and data providers, enable two native oracles, the FTSO and the State Connector. +This native processing provides developers on Flare with efficient access to large amounts of data and data proofs at minimal cost.

    +

    By giving developers trustless access to the broadest range of data, Flare can advance the development of more blockchain use cases where data is important, such as in DeFi, gaming, NFT, music, and social networks.

    +

    Flare Protocols#

    +

    Flare has the following native data acquisition protocols at these stages of development:

    +
      +
    • The Flare Time-Series Oracle (FTSO) provides continuous estimations of changing data, such as price pairs.
    • +
    • The State Connector allows querying of verifiable, non-changing data from other chains and the internet.
    • +
    • Flare LayerCake is being developed by Flare Labs to provide a decentralized, trustless bridging system between smart contract networks. For an overview of trustless bridges, see LayerCake.
    • +
    +

    Developing on Flare#

    +

    Flare developers can work in a familiar Ethereum-like environment. +It offers the same API and uses the Ethereum Virtual Machine (EVM), so Ethereum's Solidity smart contracts can be used directly. +Like Ethereum, Flare supports other assets, such as NFTs. +See Developer Docs.

    +

    The Flare native currency, $FLR, works the same as $ETH on the Ethereum blockchain. +For those contracts that can only work with ERC-20 tokens, $FLR can be easily wrapped as $WFLR, which is an ERC-20 representation of $FLR. +Flare's FTSO delegation and Flare governance are examples of such apps.

    +

    Common blockchain tools like wallets, a token management portal, and block explorers are available on Flare.

    +

    Flare is actively seeking developers eager to discover what new utility can be brought to the blockchain industry when acquiring data is possible in a decentralized way. +To start, since Flare is EVM-compatible, you can migrate Ethereum smart-contract dapps to Flare. +Then consider, for example, creating DeFi, gaming, NFT, music, or social network dapps. +See Start Building, for more information.

    +

    Flare Networks#

    +

    Flare has 4 networks with different purposes:

    +
      +
    • Flare is the main network, where $FLR is the native currency.
    • +
    • Songbird is the canary network, where $SGB is the native currency. Created with users in mind, it is meant for testing features under "real fire" conditions, before deploying them on the main network.
    • +
    • Coston is Songbird's public test network, created with developers in mind.
    • +
    • Coston2 is Flare's public test network, created with developers in mind.
    • +
    +
    +

    The Flare networks

    +
    General feature adoption flow.
    +
    +

    Flare Chains#

    +

    Flare uses two chains and is developing a built-in interoperability mechanism between them.

    +
      +
    • C-Chain: The contract chain that is used for smart contracts. It is where the Ethereum Virtual Machine operates, and is the chain where the vast bulk of the community currently interact.
    • +
    • P-Chain: The platform chain that accommodates staking and provides rewards to its validators.
    • +
    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tech/ftso/index.html b/tech/ftso/index.html new file mode 100644 index 000000000..09aa85c44 --- /dev/null +++ b/tech/ftso/index.html @@ -0,0 +1,4515 @@ + + + + + + + + + + + + + + + + + + FTSO - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + + + + +
    +
    + + + + + + + + + + +

    FTSO#

    +

    The Flare Time Series Oracle (FTSO) is a smart contract running on the Flare network that provides continuous estimations for different types of data. It does so in a decentralized manner (no single party is in control of the process) and securely (it takes a lot of effort to disrupt the process).

    +

    To achieve a secure, decentralized system, a set of independent data providers retrieves data from external sources, like centralized and decentralized exchanges, and supplies the data to the FTSO system. Then, this information is weighted according to each provider's vote power, and a median is calculated to produce the final estimate.

    +
    +

    Important

    +

    When FTSOs were initially designed, they supported only cryptocurrency price pairs. Now, they support all types of data. However, contract names and methods still refer to prices and price epochs, and price pairs are used in the following information to show how FTSOs work.

    +
    +

    The following diagram shows how price pairs are submitted to and filtered by the FTSO system.

    +
    +

    FTSO summary +

    +
    FTSO summary.
    +
    +

    Data providers that supply useful information, such as price pairs that are not removed as outliers because they are too far away from the median value, are rewarded, and the resulting data estimates are finally published on-chain.

    +

    The following information describes:

    + +

    Procedure Overview#

    +

    Using price data as an example, the procedure in the following diagram runs continuously. It produces new data estimates during every price epoch, which is 3 minutes long.

    +
    +

    FTSO workflow +

    +
    FTSO workflow.
    +
    +
      +
    1. +

      Any user with an account (address) on the Flare network can act as an FTSO data provider, submit data, and collect rewards.

      +

      During each epoch, only submissions from the 100 data providers with the most vote power are considered. +An account's vote power is based on its wrapped $FLR or $SGB balance and the delegations made to it (see Vote Power below).

      +

      Submitted data must be the current price (in $USD) for one or more of the supported price pairs, currently: $ADA, $ALGO, $ARB, $AVAX, $BNB, $BTC, $DOGE, $ETH, $FIL, $FLR, $LTC, $MATIC, $SOL, $USDC, $USDT, $XDC, $XLM, and $XRP. +On Songbird, replace $FLR with $SGB.

      +

      More general data types might be added in the future.

      +
    2. +
    3. +

      FTSO data providers submit data in rounds in a commit-and-reveal process, so they cannot see each other's submissions until a round is over.

      +

      This process is like submitting data in a closed envelope, and when the round is over, all envelopes are opened.

      +

      During a 3-minute price epoch, providers fetch the information, run their algorithms, and submit a hash of the data (commit). +Then, during the first half of the following price epoch (1.5 minutes), providers submit the actual data (reveal).

      +

      See technical details about the data-submission process below.

      +
    4. +
    5. +

      The FTSO system calculates the resulting median, taking into account each provider's vote power (see How Results are Calculated below).

      +

      Results are publicly available for 5 price epochs for any app or contract to read. +Previous epochs can always be retrieved from an archival node.

      +
    6. +
    7. +

      For each price epoch in which the submitted data is close enough to the median value, data providers and their delegators are rewarded.

      +

      Rewards are accumulated in reward epochs, which last 3.5 days on the Flare network and 7 days on Songbird, and you can claim them after the epoch finishes.

      +

      See Rewards below.

      +
    8. +
    +

    How Results are Calculated#

    +

    The following example uses price pairs to show the filtering process that turns all submitted data into a single estimate. +See all details in the Flare whitepaper.

    +
    +

    FTSO price calculation +

    +
    FTSO price calculation.
    +
    +
      +
    • +

      The contract in charge of each price pair calculates the resulting price for a price epoch using the submissions received from all data providers during that epoch. + Price epochs are 3 minutes long.

      +
    • +
    • +

      Each submission has a price and a weight. + Weight is based on the data provider's vote power, as explained below.

      +
    • +
    • +

      The weighted median of the prices is the resulting price for the price epoch.

      +
    • +
    • +

      Submissions in the top and bottom 25% range are not rewarded.

      +
    • +
    +

    Vote Power#

    +
    +

    FTSO delegation weight calculation +

    +
    FTSO delegation weight calculation.
    +
    +
      +
    • +

      As explained above, an FTSO data provider's submissions are weighted by its vote power. + A data provider's vote power is proportional to the amount of wrapped Flare or Songbird tokens ($WFLR or $WSGB) it holds, plus any amount delegated to it.

      +
      +

      A data provider's influence is limited

      +

      A vote-power cap limits the influence of individual data providers to 2.5% of the total vote power on both Flare and Songbird.

      +

      Any vote power above this cap is ignored. If vote power exceeds the limit, consider delegating those $WFLR or $WSGB to a different data provider.

      +
      +
    • +
    • +

      A snapshot of each data provider's vote power is taken once per reward epoch, and the resulting weight is then used throughout the next reward epoch.

      +
    • +
    • The actual snapshot block is called the vote-power block, and it is randomly chosen from the last blocks of the previous epoch. + On Flare, the vote-power block is randomly chosen from roughly the last 50% of the blocks, and on Songbird, it is randomly chosen from roughly the last 25%. + The random selection only roughly corresponds to the last 50% or 25% of the time because block production times are not constant.
    • +
    +
    +

    Reward epochs

    +

    The first reward epoch on Songbird started on Saturday, 18 September 2021 08:41:39 (GMT), 1631954499 in Unix time and repeats every 7 days. +Therefore, all Songbird reward epochs start on Saturday morning (GMT).

    +

    The first reward epoch on Flare started on Thursday, 21 July 2022 19:00:05 (GMT), 1658430005 in Unix time and repeats every 3.5 days. +Therefore, all Flare reward epochs start on Thursday evening (GMT) and Monday morning (GMT).

    +
    +

    Delegation#

    +

    If you hold $FLR or $SGB tokens, you can delegate them to an FTSO data provider to increase its vote power and earn a share of its rewards, resulting in a mutually beneficial arrangement. +When you delegate your vote power, you not only earn rewards but also support reliable data providers, which strengthens the stability of the FTSO and the whole ecosystem.

    +

    Before you can delegate your native $FLR and $SGB tokens, you must wrap these tokens into ERC-20 $WFLR and $WSGB tokens, an operation you can reverse at any time.

    +

    After you wrap your tokens, you will have the vote power that is equivalent to the wrapped token balance, and you can delegate 100% of this vote power to 1 or 2 data providers. +Delegating 100% of your vote power to reliable data providers committed to providing accurate data maximizes your rewards and enhances the stability of the ecosystem.

    +
    +

    The reward rate (for advanced users)

    +

    As you explore data providers, consider the expected reward rate each one offers. +The reward rate describes how many tokens were earned by a data provider during a reward epoch for every 100 tokens delegated.

    +

    The reward rate is calculated as \(total\_reward / vote\_power * (100 - fee)\), where:

    +
      +
    • \(total\_reward\): All accumulated rewards for the data provider and its delegators in the reward epoch.
    • +
    • \(vote\_power\): All the data provider's $WFLR and all the $WFLR delegated to it in the vote-power block selected for the reward epoch.
    • +
    • \(fee\): The amount kept by the data provider as compensation for the service it provides. The value is specified as a percentage. For example, if the data provider's fee is 21.3%, specify 21.3 to calculate the reward rate.
    • +
    +

    Because rewards are distributed in units of $FLR, the reward rate is calculated in units of $FLR.

    +
    +

    For the duration of the delegation, you will earn rewards that are commensurate with vote power and the performance of the chosen data providers. +Rewards accumulate, and they become claimable for each reward epoch that is finalized.

    +

    Inflation is distributed to everyone who participates in the FTSO system, which includes data providers and entities that delegate their vote power to the data providers. +Delegated tokens are not locked, meaning that they remain in the user's control and the delegation can be removed at any time.

    +

    Any $WFLR or $WSGB that is newly wrapped, sent, or received will automatically update your actual delegated vote power. +However, if you receive native tokens, you must wrap them before you contribute to existing delegations.

    +

    Immediate Delegation Revocation#

    +

    Sometimes, a data provider might maliciously attack the FTSO system to skew the reported data. If this type of attack occurs, the vote power of a data provider can be revoked immediately instead of in the next reward epoch.

    +

    In this situation, an off-chain process, such as a Twitter storm, calls for users to revoke vote power from the data provider that has attacked the system. +When vote power is revoked, the revocation occurs immediately.

    +

    Learn how to perform this operation from the block explorer.

    +

    Effects of the Vote-Power Block Snapshot on Delegations#

    +

    The following table shows when new, changed, and revoked delegations take effect in relation to the vote-power block snapshot.

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    Delegation TypeBefore or After Vote-Power Block SnapshotWhen Delegation Takes Effect
    New or changedBeforeIn the next reward epoch
    AfterAfter the next reward epoch ends
    RevokedN/AImmediately
    +

    Delegation Procedure#

    +

    You can delegate your tokens using the Flare Portal, a supported wallet like Bifrost, or a dapp. +Some FTSO data providers have already started providing these dapps as a convenience. +Take a look at flaremetrics.io and pick the one you prefer.

    +

    If you are an advanced user, you can delegate manually by interacting directly with the FTSO smart contracts.

    +

    Rewards#

    +

    A percentage of the annual network inflation is reserved to reward FTSO data providers and distributed uniformly among the year's reward epochs. +The mechanism that distributes rewards to data providers consists of several bands:

    + +

    Submitted data in each reward epoch belongs to one of the following:

    +
      +
    • Primary reward band
    • +
    • Primary and secondary reward band
    • +
    • Neither reward band
    • +
    +

    On Flare, reward epochs are 3.5 days. +On Songbird, reward epochs are 7 days. +In each reward epoch, rewards are distributed to providers whose submission falls within the primary or secondary reward bands.

    +

    Because the secondary reward band is wider, it rewards more data providers than the primary band. However, submissions still must be close enough to the median to be included. +If a submission falls within both bands, it receives both rewards because each reward band is independent.

    +

    The secondary reward band receives 30% of all FTSO rewards, and the primary reward band receives the remaining 70%. +As the FTSO system evolves, these reward percentages might be revised later, in accordance with an accepted proposal that requests changes to the secondary reward band.

    +

    After the band rewards are distributed, each provider can take an optional, configurable fee, which is set to 20% by default, and distributes the rest of the reward among all contributors to its vote power, i.e., itself and all its delegators, according to the delegated amounts.

    +

    If you delegated to a data provider, the amount of your rewards depends on multiple factors:

    +
      +
    • The percentage of vote power you delegated
    • +
    • The data providers to which you delegated your vote power
    • +
    • The performance of those data providers
    • +
    • The fee charged by those data providers
    • +
    • Whether the total vote power of one or both of those data providers exceeded the vote power cap
    • +
    +

    You can claim your rewards at the end of each reward epoch.

    +

    You must claim your rewards within 90 days of their availability. +After 90 days, unclaimed rewards on Flare are burned, and on Songbird, they are reallocated.

    +

    Reward-Claiming Procedure#

    +

    FTSO rewards are not automatically transferred to their recipients. +Instead, the amounts are accumulated in a contract, as described in the System Architecture, and must be claimed once the reward epoch is finished.

    +

    You can claim your rewards using the Flare Portal, a supported wallet like Bifrost, or a dapp. +Take a look at flaremetrics.io and pick the one you prefer.

    +

    If you are an advanced user, you can claim manually by interacting directly with the FTSO smart contracts.

    +

    To save on gas costs, rewards from multiple reward epochs are claimed simultaneously when you use the Portal. However, be aware that rewards expire after 90 days. +Moreover, you probably want to claim soon, to redelegate the received amount and obtain compounded rewards.

    +

    It is also worth noting that:

    +
      +
    • Rewards are paid in the network's native currency. On Flare, the native token is $FLR, and on Songbird, the native token is $SGB.
    • +
    • Data providers and their delegators must claim independently.
    • +
    +

    Technical Details#

    +
    +

    This section is aimed at developers.

    +
    +

    System Architecture#

    +

    The FTSO system is composed of multiple smart contracts running on the Flare Network.

    +

    Using prices as an example, the following diagram shows the flow of data, queries, and rewards through the FTSO system:

    +
    +

    FTSO component smart contracts +

    +
    FTSO component smart contracts.
    +
    +

    The following list describes the most relevant contracts and their purposes:

    +
      +
    • +

      FTSO: Each data type is handled by its own FTSO contract, including calculation of the filtered feed.

      +

      To retrieve information about a data type, access this contract.

      +
      +

      Note

      +

      If an FTSO contract is redeployed (for example, to fix a bug), its address will change and apps using it will need to be updated. +The FTSO Registry contract below tracks this change for you.

      +
      +

      You can retrieve the addresses of all FTSO contracts using the getAllFtsos method in the FTSO Registry.

      +
    • +
    • +

      FTSO Registry: Aggregates the output of each individual FTSO contract and provides a convenient one-stop API to retrieve all data.

      +
    • +
    • +

      Price Submitter: This contract is used by the FTSO data providers to submit their data. Although the contract is called PriceSubmitter, data is not limited to prices.

      +
    • +
    • +

      Reward Manager: Use this contract to claim your rewards, whether you are a data provider or a delegator.

      +
    • +
    • +

      Wrapped Native (WNat): This contract is not exclusively related to the FTSO system, but it is required to wrap and unwrap native tokens into the $WFLR and $WSGB that delegation requires.

      +
    • +
    +
    +

    Note

    +

    The Contract Addresses page explains how to securely retrieve each contract's address.

    +
    +

    Other contracts, like the FTSO Manager or the FTSO Daemon, are only meant for internal use by the FTSO system.

    +

    Manual Delegation and Claiming#

    +

    The following graphic shows the delegation process. You can call methods in several different smart contracts to manually delegate vote power and claim rewards.

    +
    +

    Delegation process summary +

    +
    FTSO delegation process summary.
    +
    +

    Data-Submission Process#

    +

    Data submission uses a commit-and-reveal scheme to prevent providers from viewing each other's submissions until a round is over. +To speed up the process, both phases are actually overlapped so:

    +
      +
    • +

      All Commit phases happen continuously in so-called 3-minute Price Epochs.

      +
    • +
    • +

      Reveal phases happen during the first half (first 90 seconds) of the following Commit phase.

      +
    • +
    • +

      The published price information is therefore updated every 3 minutes.

      +
    • +
    +

    Only a hash of the data is submitted during the Commit phase. +Next, in the Reveal phase the actual data is sent. +If its hash does not match the previous commitment, the data is discarded.

    +

    The submission API is slightly different for the Flare and Songbird networks:

    +
    +
    +
    +

    FTSO data providers submit data through the PriceSubmitter contract.

    +
      +
    • +

      Commit: A single hash is needed for each submission.

      +
      function submitHash(
      +    uint256 _epochId,
      +    bytes32 _hash
      +) external;
      + 
      +
      +
    • +
    • +

      Reveal: After all data is submitted, a single random number must be submitted.

      +
      function revealPrices(
      +    uint256 _epochId,
      +    uint256[] memory _ftsoIndices,
      +    uint256[] memory _prices,
      +    uint256 _random
      +) external;
      +
      +
    • +
    +
    +
    +

    FTSO data providers submit data through the PriceSubmitter contract.

    +
      +
    • +

      Commit: A separate hash is needed for each submission.

      +
      function submitPriceHashes(
      +    uint256 _epochId,
      +    uint256[] memory _ftsoIndices,
      +    bytes32[] memory _hashes
      +) external;
      +
      +
    • +
    • +

      Reveal: Along with each data submission, a random number must be submitted too.

      +
      function revealPrices(
      +    uint256 _epochId,
      +    uint256[] memory _ftsoIndices,
      +    uint256[] memory _prices,
      +    uint256[] memory _randoms
      +) external;
      +
      +
    • +
    +
    +
    +
    +

    Retrieving Data#

    +

    Data produced by the FTSO is publicly available on the Flare and Songbird networks.

    +

    All data can be retrieved either through the FtsoRegistry contract or directly through one of the Ftso contracts. +In any case, using the getCurrentPriceWithDecimals method is recommended. +The following examples show how to use this method to retrieve price data.

    +
    +
    +
    +

    From the FtsoRegistry contract:

    +
    function getCurrentPriceWithDecimals(
    +    uint256 _ftsoIndex
    +) external view returns (
    +    uint256 _price,
    +    uint256 _timestamp,
    +    uint256 _assetPriceUsdDecimals
    +);
    +
    +

    Where _ftsoIndex is one of the allowed indices returned by getSupportedIndices, for example.

    +
    +
    +

    From the FtsoRegistry contract:

    +
    function getCurrentPriceWithDecimals(
    +    string memory _symbol
    +) external view returns (
    +    uint256 _price,
    +    uint256 _timestamp,
    +    uint256 _assetPriceUsdDecimals
    +);
    +
    +

    Where _symbol is one of the allowed symbols returned by getSupportedSymbols, for example.

    +
    +
    +

    First you need to obtain the address of the Ftso contract managing the price pair you are interested in. +You can use getSupportedIndicesSymbolsAndFtsos from the FtsoRegistry, for example.

    +

    Then call getCurrentPriceWithDecimals on the FTSO directly:

    +
    function getCurrentPriceWithDecimals(
    +) external view returns (
    +    uint256 _price,
    +    uint256 _timestamp,
    +    uint256 _assetPriceUsdDecimals
    +);
    +
    +
    +

    Note

    +

    Individual FTSO contracts might be updated periodically, which will change their addresses. Instead of caching these addresses, use the FtsoRegistry.

    +
    +
    +
    +
    +

    GetCurrentPriceWithDecimals returns the requested price (the outcome of the previous 3-minute price epoch) in $USD shifting the comma by the amount of decimal places returned in _assetPriceUsdDecimals. +That is, the actual price is _price * 10 -_assetPriceUsdDecimals.

    +

    For example, a return value of 2603 with _assetPriceUsdDecimals of 5 means a price of 0.02603 USD (There are only 5 significant decimal places).

    +

    A standard Unix timestamp of the last price update is also returned.

    + + + + + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tech/glossary/index.html b/tech/glossary/index.html new file mode 100644 index 000000000..a4c4e705b --- /dev/null +++ b/tech/glossary/index.html @@ -0,0 +1,3949 @@ + + + + + + + + + + + + + + + + + + Glossary - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Glossary#

    +
    +
    Attestation
    +
    A data proof provided to the State Connector by a decentralized set of Attestation Providers that confirms the validity or otherwise of any request.
    +
    Autoclaiming
    +
    Automatic claiming enables users to appoint an executor to claim rewards on their behalf. Read more...
    +
    Avalanche
    +
    An open-source blockchain using the Snow family of consensus protocols and Proof of Stake for Sybil resistance. It is advertised as the fastest smart contract platform. Read more...
    +
    Block
    +
    For performance reasons, blockchains do not process transactions one by one. Instead, transactions are grouped together in blocks which are then validated by the consensus algorithm.
    +
    Block Explorer
    +
    A tool that enables its users to analyze transactions and interact with addresses on blockchains. Read more...
    +
    Blockchain
    +
    Digital ledger storing data and transactions on a distributed network of computers to make it more robust. Cryptography protects against information tampering, and a consensus algorithm ensures that the majority of the network agrees on the stored data even if some of its nodes act maliciously.
    +
    Bootstrapping Node
    +
    An observation node associated with a validator node and acting as its bastion: the bootstrapping node exposes a minimum RPC interface, so the validator does not have to. The nodeID and nodeIP returned by the bootstrapping node's RPC allow an external node to connect and peer with the core network of validators. The bootstrapping node also gossips the core network's validators nodeIDs and nodeIPs to the external node to peer to. The main purpose of a bootstrapping node is to allow new nodes to connect to the network (hence the name "bootstrapping") while reducing its associated validator node attack surface. Flare offers some public bootstrapping nodes.
    +
    Byzantine Fault Tolerance
    +
    Property of a distributed system that is capable of continuous operation even when some of its participants are unreliable. Participants acting against the interest of the whole system, by accident or on purpose, are said to have “gone Byzantine”.
    +
    Canary Network
    +
    A network used for testing features under “real fire” conditions, before deploying them on the main network. All users of the canary network are real users, but they are aware of the experimental nature of the platform. The name comes from the time when actual miners used actual canaries to detect the presence of poisonous gas in the mines. Flare's canary network is called Songbird.
    +
    Consensus
    +
    Algorithm that makes nodes on a blockchain’s network agree on the validity of a given transaction, even if some of the nodes provide invalid transactions or try to disrupt the network (Byzantine Fault Tolerance).
    +
    Coston
    +
    The name given to both of Flare's public test networks (Coston and Coston2), in remembrance and celebration of a great inventor, Martha J. Coston (1826-1904).
    +
    Cross-chain (or inter-ecosystem) interoperability
    +
    Communication between two or more disparate blockchain ecosystems that are technologically incompatible due to the lack of shared systems, protocols or code (e.g. Ethereum and Solana).
    +
    DAO
    +
    A Decentralized Autonomous Organization is an entity with no central authority. Its governance is mandated by rules encoded on a blockchain so it is tamper-proof.
    +
    Dapp
    +
    A Decentralized Application is a computer program that makes use of blockchain technology and therefore the information it uses or stores has the same benefits (trustlessness, censorship resistance, geographical redundancy, etc). The dapp itself may or may not be hosted on a blockchain.
    +
    Data Provider
    +
    Each of the multiple programs supplying external information to an FTSO running on the Flare network, and getting rewarded for it. Token holders can delegate their stake to a data provider and receive a share of the rewards.
    +
    DeFi
    +
    Decentralized Finance is a form of finance that does not rely on a central financial institution. DeFi is commonly based on blockchain technology.
    +
    Delegate
    +
    To assign a duty to someone else, so they do it for you. On the Flare network, an address can delegate any fraction of the votes associated with the tokens it holds to another address, for the purpose of FTSO weighting or governance participation. Note that no tokens are transferred.
    +
    ERC-20
    +
    The Ethereum Request for Comments 20, proposed in November 2015, is an Ethereum token standard that implements an API for tokens within smart contracts. It is a standard for fungible (exchangeable) tokens, which have a property that makes each token exactly the same (in type and value) as another token. For example, an ERC-20 token acts just like Ethereum's ETH token, meaning that 1 token is and will always be equal to all the other tokens. Read more...
    +
    EVM
    +
    The Ethereum Virtual Machine allows executing smart contracts on the Ethereum network, regardless of the kind of computer that executes it. Multiple blockchain networks, including Flare, support EVM contracts. Read more...
    +
    Executor
    +
    Users who do not want to claim rewards themselves can set an executor to claim rewards for them and send them directly to their users' accounts. Read more...
    +
    Faucet
    +
    A dapp that distributes test tokens to anyone that requests them. Used only on test networks, obviously. See the Network Configuration page to learn about Flare's faucets.
    +
    FBA
    +
    Federated Byzantine Agreement is a form of Byzantine fault tolerance where each node keeps its own list of trusted nodes. It does not require nodes to invest stake or computing power as Proof of Stake or Proof of Work protocols do.
    +
    FCP
    +
    The Flare Consensus Protocol is an asynchronous, ordered and leaderless version of Federated Byzantine Agreement (FBA) consensus. The whitepaper is already available and it is currently in the process of being implemented. Read more...
    +
    Flare Token (FLR)
    +
    The native currency of the Flare's main network.
    +
    FTSO
    +
    The Flare Time Series Oracles provide external information to the Flare network in a decentralized manner, by using multiple independent data providers that are rewarded for providing accurate information. Read more...
    +
    Governance
    +
    Mechanism to propose, vote and implement changes on a blockchain protocol. On Flare, anybody can propose updates and token holders vote to accept them.
    +
    Know Your Customer
    +
    The process an entity completes to verify the identities of its users to comply with global requirements.
    +
    Layer 1
    +
    An L1 is a blockchain in the classical sense, in that it comprises a network of nodes that exchange information to guarantee the integrity of a shared ledger and offer functionality like token exchange and programmability. Compare it to an L2, which is built on top of an existing L1.
    +
    Layer 2
    +
    An L2 is a blockchain built on top of an existing L1 making use of its programmability. L2 chains add extra functionality to the L1, like scalability.
    +
    Ledger
    +
    Historically, a book where financial transactions are recorded. In blockchain technology, a ledger can contain any kind of information, which has multiple copies distributed among several computers, kept in sync by a consensus algorithm.
    +
    Light Client Relay
    +
    A simplified communication mechanism built for speed that only queries the header data of any transaction and therefore lacks the security that comes from querying a full node with full history (e.g. SPV).
    +
    Liquidity Pool
    +
    A collection of funds locked in a smart contract for the purpose of facilitating trading, lending and other functionality in a decentralized manner.
    +
    Main Network (MAINNET)
    +
    The computer network that supports a blockchain in its production stage, i.e., the real thing (instead of a Canary or Test network).
    +
    Metaverse
    +
    An old concept, at times called Virtual Reality or Cyberspace, that translates human interaction to virtual (i.e. non-physical) worlds. Currently in vogue again because blockchain technology promises to link the physical and the virtual worlds and thus bring a degree of reality to the latter.
    +
    Multi-chain (or intra-ecosystem) interoperability
    +
    Communication between two or more technologically compatible blockchains that exist within the same ecosystem and share systems, protocols and code (e.g. Polkadot Parachains, Cosmos Tendermint chains or Ethereum layer 2 protocols).
    +
    NFT
    +
    Non-Fungible Tokens are digital representations of assets which are unique and therefore non-mergeable (non-fungible), made impossible to copy by blockchain technology. Common use cases are certificates of authenticity or ownership, or limited edition collectibles. Most NFT tokens are built on the Ethereum network using standards ERC-721 and ERC-1155.
    +
    Oracle
    +
    A mechanism to provide external information to a blockchain, so that it can be used by smart contracts, for example. Flare oracles are called FTSO.
    +
    Proof of Stake
    +
    A kind of Sybil resistance based on staking assets to participate in consensus. The rationale is that a participant investing enough assets will not be interested in attacking the network that supports such assets. Moreover, if malicious behavior is detected part of the assets can be taken as punishment.
    +
    Proof of Work
    +
    A kind of Sybil resistance based on spending computer power to participate in consensus. The rationale is that attacking the network becomes prohibitively expensive in terms of computer power.
    +
    Pruning
    +
    A blockchain database reduction technique, which keeps the state of all addresses (like their balance) and the transactions that led to that state, but removes any old transaction that does not impact the current state anymore.
    +
    Quantum Resistance
    +
    The ability of a cryptographic algorithm (and therefore of a blockchain) to resist an attack from a theoretical quantum computer.
    +
    Quorum
    +
    Set of participants on a consensus algorithm that must agree on a result for the whole network to accept that result. On a blockchain, once consensus is reached about a block, it is added to the ledger and the next block is processed.
    +
    Quorum Slice
    +
    In FBA consensus each node has multiple lists of other nodes which it voluntarily decides to trust, forming its quorum slices. All nodes in a quorum slice agreeing on a result are enough to convince the node of that result. If the quorum slices are correctly built, global quorum emerges from these local quorum slices.
    +
    RPC
    +
    Remote Procedure Call is a protocol that allows a program executing on a computer to request a service from another program, typically running on a different computer. Flare offers some public and private nodes with RPC capabilities.
    +
    Smart Contract
    +
    Computer program running on a blockchain, typically one based on the EVM. The blockchain’s immutability ensures that the contract is not tampered with, and running it on several machines bound together by a consensus algorithm ensures faithful execution. Smart contracts are said to be self-enforcing.
    +
    Songbird
    +
    Flare's canary network, launched in September 2021.
    +
    State Connector
    +
    Piece of the Flare network that keeps track of the state of other networks, facilitating the implementation of advanced mechanisms like the FAssets. The State Connector uses several independent Attestation Providers that are rewarded for providing correct information. Read more...
    +
    Sybil Resistance
    +
    The ability of a distributed system to overcome a Sybil attack, in which a malicious actor creates multiple identities to gain voting or mining power. Resistance is typically gained by making voting or mining too costly for the attack to be worth it (as in Proof of Work or Proof of Stake) or by requiring new entities to be approved by existing actors (as in FBA).
    +
    Test Network (TESTNET)
    +
    The computer network that supports a blockchain in its development stage. It is intended for testing purposes and should not store valuable assets, as its contents might be deleted (purposely or by accident) at any time. Among other facilities, testnets typically provide faucets. Compare to a Canary or a Main network. Flare's testnets are Coston for Songbird and Coston2 for Flare.
    +
    Transaction
    +
    A request to add information to the blockchain, which is then analyzed by the network and accepted when consensus is reached about its validity. It can be a movement of funds between two accounts, or the execution of a contract, for example.
    +
    Transaction Fee
    +
    Amount of cryptocurrency that must be paid by anybody submitting a transaction for inclusion on a blockchain. These fees reward block producers for their work processing transactions, and typically vary depending on network congestion.
    +
    Token
    +
    A digital representation of an asset. Fungible tokens are indistinguishable from one another so they can be merged together (e.g. a cryptocurrency). Non-fungible tokens (NFT) are unique and therefore cannot be merged.
    +
    Turing-completeness
    +
    The ability of a machine to solve any computational problem, no matter how complex, given the necessary steps and enough time and memory. This is a mandatory feature of any general-purpose processor like a CPU or the EVM.
    +
    Validator
    +
    A validator node is a machine connected to a blockchain network that verifies transactions and emits a vote. When there is a quorum among all validators regarding a given block of transactions, they are accepted into the blockchain.
    +
    Voting Power
    +
    Weight proportional to the tokens held by an address plus the tokens delegated to it. This weight is used during FTSO operation and governance votes, for example.
    +
    Wen flare
    +
    The war cry of all the impatient that would like to see the Flare network launch before it is fully tested. Pay no heed to them.
    +
    Zero address
    +
    A special address represented as 0x0000000000000000000000000000. Also known as the null address, it is typically used as a return value from functions to indicate an error condition.
    +
    + + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tech/governance/index.html b/tech/governance/index.html new file mode 100644 index 000000000..1b93f7c20 --- /dev/null +++ b/tech/governance/index.html @@ -0,0 +1,4189 @@ + + + + + + + + + + + + + + + + + + Governance - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Governance#

    +

    Introduction#

    +

    Flare governance gives everyone in the ecosystem the opportunity to collaborate on decision-making on the Flare and Songbird networks, making governance an important element of decentralization.

    +

    This process enables the Flare Foundation and Flare and Songbird community members to:

    +
      +
    • Propose policy changes.
    • +
    • Vote on them.
    • +
    • Execute them if accepted.
    • +
    +

    The following sections detail the different kinds of proposals Flare allows and the process for each of them.

    +

    If you are already familiar with Flare's governance and just need to know how to cast your vote through the Flare Portal, check the Voting User Guide.

    +

    Flare's Governance#

    +

    Excluding the testnets Coston and Coston2, Flare currently has two networks: Flare and Songbird. +Moreover, two kinds of proposals are planned, depending on who initiates them: those proposed by the community and those proposed by the Flare Foundation.

    +

    This situation leads to four types of proposals, of which only two are currently supported and detailed next.

    +

    Flare Improvement Proposals and Songbird Test Proposals#

    +

    Flare Improvement Proposals (FIPs) and Songbird Test Proposals (STPs) are initiated by the Flare Foundation and are aimed at improving the Flare and Songbird networks. +Community-initiated proposals will be supported later.

    +

    To increase its stability, FIPs are rejected by default, meaning that they are accepted only if enough votes are cast in their favor.

    +

    To increase the swiftness at which new proposals can be tested on Songbird, STPs are accepted by default, meaning that they are rejected only if enough votes are cast against them.

    +

    See Voting Outcomes below for more details.

    +

    Who Votes#

    +

    To vote on a proposal on a network, you must have the valid wrapped token:

    + + + + + + + + + + + + + + + + + + + + + + + +
    NetworkProposal TypeTokenWrapped Token
    FlareFIP$FLR$WFLR
    SongbirdSTP$SGB$WSGB
    +
    +

    Important

    +
      +
    • Available votes depend on the amount of valid wrapped tokens you have, not the native tokens. Therefore, remember to wrap your tokens.
    • +
    • Don't wrap all your tokens. Keep some of them to pay for transaction fees.
    • +
    • To vote with your tokens, they must be wrapped before the proposal is submitted.
    • +
    +
    +

    The Flare Foundation announces proposals in advance, so that users can read them and wrap their tokens if they have to.

    +
    +Vote Transfer +

    Votes can be transferred to another account while the wrapped tokens remain in your possession. +Being able to transfer votes is useful, for example, if you have wrapped tokens in multiple self-custody wallets, because voting can then be simplified by transferring all the votes to a single wallet and voting from there.

    +

    Votes can only be transferred to one address, but it can receive votes from multiple addresses. +Received votes cannot be transferred again to a third address.

    +

    Once activated, vote transfers always send 100% of an account's votes to the selected address and remain active until they are canceled.

    +

    As an example, if you have 100 $WSGB before a proposal and you activate the transfer, you will transfer 100 votes. +If you later add 100 more $WSGB, for the next proposal you will automatically transfer 200 votes, since the transfer remains active until you cancel it.

    +

    The following is a more complex example, showing the changes produced by vote transfers, and token wrapping and unwrapping on Songbird:

    +

    + Changes in number of votes on Songbird +
    Changes in the number of votes on Songbird.
    +

    +
    +

    Note

    +

    Transferring votes has no connection with FTSO delegation: +Wrapped tokens can be delegated to an FTSO data provider and at the same time the votes they grant can be transferred to a different address.

    +
    +
    +

    The Vote Count Block#

    +

    Since the amount of wrapped tokens an account holds varies over time, a snapshot of all accounts is taken before each voting period starts. +The amount of wrapped tokens held by an account at the snapshot then dictates the number of votes available later.

    +

    The block at which the snapshot is taken is called the vote count block.

    +

    To encourage users to use their tokens and keep them in the network, instead of just acquiring them for voting and then disposing of them, the vote count block is randomly selected. +The next section details when this happens.

    +

    Voting Process#

    +

    The image in this section shows the voting process, which includes several conditions:

    +
      +
    • +

      Threshold condition: A minimum quorum must be reached, meaning that enough votes must be cast, or no minimum quorum is required.

      +
    • +
    • +

      Majority condition: More than 50% of the votes cast, must be for or against the proposal.

      +
    • +
    +
    +

    Voting process +

    +
    Voting process.
    +
    +
      +
    • +

      Announcement: The Flare Foundation publishes the proposal online and announces it through social media channels (linked on the footer of this page) and the Flare website.

      +
    • +
    • +

      Notice period: Once the proposal is published, the Flare Foundation allows a notice period before voting can start, typically lasting one week. + During this time the proposal can be discussed, clarified, commented on, and even cancelled if serious issues are found with it.

      +

      For security reasons only, the Foundation may reduce the timeframe of this period.

      +
    • +
    • +

      Block selection period: The vote count block is selected at a random time during this period. + The duration of this period is also random.

      +
      +

      Warning

      +

      If you need to wrap tokens, do so before this period starts since tokens wrapped after the selected vote count block will not result in additional votes.

      +
      +
    • +
    • +

      Voting period: The proposal is submitted to the Flare Portal, and it is immediately available for voting. + Voting concludes after a week, and final results are presented on the portal.

      +
    • +
    +

    Voting Outcomes#

    +

    FIPs#

    +

    Voting on FIPs is acceptance-based. +For an FIP to be accepted, a simple majority of the votes cast must be in favor of it. +No minimum quorum is required.

    +

    Therefore, an FIP will be rejected only if less than half of the cast votes are for it.

    +

    STPs#

    +

    Voting on STPs is rejection-based. +For an STP to be rejected, both of the following conditions must be true:

    +
      +
    • +

      Threshold condition: The minimum quorum is at least 75% of all $SGB tokens circulation (excluding the Flare Foundation's tokens) at the vote count block.

      +

      Note that the quorum is specified as a fraction of the circulating native $SGB tokens instead of the wrapped tokens $WSGB used for voting. +This measure tries, again, to encourage users to wrap their tokens and use them in the network.

      +
    • +
    • +

      Majority condition: More than 50% of the votes cast, must be against the proposal.

      +
    • +
    +

    Therefore, an STP will be accepted if the quorum threshold is not reached or if less than half of the cast votes are against it.

    +

    Execution#

    +

    Once a proposal is accepted, Flare's governance contracts allow for its automatic execution via a contract call.

    +

    However, some proposals might require changes that are not implementable through a smart contract and therefore automatic execution is disabled for them. +Both FIPs and STPs are manually executed by the Flare Foundation.

    + + + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tech/index.html b/tech/index.html new file mode 100644 index 000000000..a2dcf5d37 --- /dev/null +++ b/tech/index.html @@ -0,0 +1,3867 @@ + + + + + + + + + + + + + + + + + + Flare Fundamentals - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    + + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tech/personal-delegation-account/index.html b/tech/personal-delegation-account/index.html new file mode 100644 index 000000000..4c33e92d1 --- /dev/null +++ b/tech/personal-delegation-account/index.html @@ -0,0 +1,3912 @@ + + + + + + + + + + + + + + + + + + Personal Delegation Accounts - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Personal Delegation Accounts#

    +

    Flare token holders are eligible to receive a number of rewards, for example through FTSO Delegation. +The Flare network offers the option to set up Personal Delegation Accounts (PDAs) to temporarily receive and store rewards to track which funds are from rewards, for example, for personal or tax purposes. +In certain jurisdictions, delaying the realization of earnings for a specified time can lead to a reduced tax rate.

    +

    Each Flare address can be associated with one PDA, which behaves like a regular account in many respects. +For example, it can receive funds from any address. +Like regular accounts, it is under control of the owner and can perform functions such as delegation and claiming.

    +

    Here are some of the differences from a regular account:

    +
      +
    • A PDA cannot have another PDA of its own.
    • +
    • PDA addresses cannot participate in governance directly, but their owners can transfer all their votes to another address (their main account or someone else's).
    • +
    • A PDA automatically converts any $FLR tokens transferred to it to wrapped Flare tokens ($WFLR), which are more useful for functions such as delegation.
    • +
    • Only the owner of the main account can transfer funds from the PDA and only to the main account.
    • +
    • When an executor is configured, it will claim rewards both from the main account and the PDA, and send them to the PDA.
    • +
    +
    +

    Warning

    +

    The Flare Foundation is not liable for any damages, especially pertaining to tax related issues when using this service. +Check your local tax laws.

    +
    +
    +

    Developing PDA functionality

    +

    For information on how to develop a PDA, or how to write an application that supports a PDA, see Personal Delegation Accounts in the Developer section.

    +
    + + + + + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tech/state-connector/index.html b/tech/state-connector/index.html new file mode 100644 index 000000000..ad39f186d --- /dev/null +++ b/tech/state-connector/index.html @@ -0,0 +1,4399 @@ + + + + + + + + + + + + + + + + + + State Connector - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + + + + +
    +
    + + + + + + + + + + +

    State Connector#

    +

    Introduction#

    +

    The State Connector is a smart contract running on the Flare network that allows anyone to query non-changing, verifiable information (such as blockchain or geographic data) from outside the Flare network. +Data that changes, such as the latest BTC to USD conversion rate, and non-verifiable data, such as data behind a paywall, are not available through the State Connector.

    +

    The State Connector accesses data in a decentralized manner (no single party is in control of the process) and securely (it takes a lot of effort to disrupt the process). +This is accomplished by using a set of independent attestation providers which fetch the required information from the world and deliver it to the Flare network. +The State Connector smart contract then checks if there is enough consensus among the received answers and publishes the results if so.

    +

    As an added security measure, individual validators can also define local attestation providers which, when in disagreement with the rest, cause the validator to branch into an idle, safe state while the situation is resolved.

    +
    +

    The State Connector +

    +
    The State Connector.
    +
    +

    The State Connector can, for instance, check whether a deposit has been made on another blockchain, opening the door to more advanced mechanisms like the FAsset or the Layer Cake bridges.

    +

    This page gives technical details about the whole procedure, the different security and scalability measures that have been taken into account in its design and the kind of queries that can be performed.

    +

    Procedure Overview#

    +

    This is how user queries are processed. The following sections contain more details.

    +
    +

    State Connector procedure. +

    +
    State Connector procedure overview.
    +
    +

    1. Request#

    +

    Anybody, be it a smart contract running on Flare or an application, can request the attestation of a specific event from the State Connector.

    +

    Requests are yes/no questions regarding things that happened outside the Flare network, for example, "Has transaction 0xABC been confirmed on the Bitcoin network enough times?". +The answers, though, might contain any kind of additional data attached, like the content of transaction 0xABC, for example.

    +

    Requests must adhere to one of the available request types, which have been designed to be strictly decidable, i.e., the answers are objective and cannot be argued. +Otherwise, queries like "What is the weather like in Paris?" would have a hard time reaching consensus among the different attestation providers. +Section Adding New Attestation Types below contains more details.

    +
    +Making a request (for App developers) +

    Make your requests using the requestAttestations method (#2) of the StateConnector contract:

    +
    function requestAttestations(
    +    bytes calldata data
    +) external;
    +
    +

    The requestAttestations method has a single parameter, data, which is a byte array with a content that depends on the desired request type. +You can learn how to build this array in the state-connector-attestation-types repository.

    +
    +

    2. Request forwarding#

    +

    The State Connector simply forwards the request to all connected attestation providers through an EVM event. +Therefore, the request is not stored on the blockchain and its gas cost is very low for the requester.

    +

    3. Data retrieval#

    +

    Attestation providers fetch the requested data by means that depend on the type of attestation, for example, retrieving data from another blockchain or public API.

    +

    Keep in mind that attestation providers are not controlled by Flare in any way. +Anybody can listen to the request events and provide answers using any combination of hardware, software, and code they see fit.

    +

    4. Attestation#

    +

    To prevent attestation providers from peeking at each other's answers, these are submitted in a "Commit and Reveal" fashion called the CCCR protocol and detailed below.

    +
    +Submitting an attestation (For attestation provider developers) +

    Attestation providers use the submitAttestation method (#3) of the StateConnector contract:

    +
    function submitAttestation(
    +    uint256 _bufferNumber,
    +    bytes32 _commitHash,
    +    bytes32 _merkleRoot,
    +    bytes32 _randomNumber
    +) external returns (
    +    bool _isInitialBufferSlot
    +);
    +
    +

    Keep reading to understand the meaning of the parameters. +More information in the Attestation Client repository.

    +
    +

    5. Consensus#

    +

    If at least 50% of the attestation providers submitted the same answer, it is made public. +Otherwise, no consensus is achieved: requests remain unanswered and must be issued again.

    +

    The answers are stored in the State Connector smart contract for a week, where anybody can read them, including the original requester.

    +
    +Retrieving your request's answer (for App developers) +

    To retrieve the stored answers just read the merkleRoots public array (#8) in the StateConnector contract.

    +

    More information on how to retrieve a particular answer in the State Connector contract source code.

    +

    As shown below, multiple answers are actually packed into a single Merkle root. The Attestation Packing section explains how to retrieve an individual answer.

    +
    +

    Attestation Protocols#

    +

    For simplicity, the above description omitted two very important mechanisms, reviewed here.

    +

    The main one is Attestation packing, which decouples the number of requests from the number of answers, effectively providing unbounded scalability. +It requires requests to be first collected and then answered all at once, so a protocol called CCCR is used.

    +

    Overlapped CCCR Protocol#

    +

    Requests and answers are submitted sequentially in attestation rounds. +Each attestation round has 4 consecutive phases, called Collect, Choose, Commit and Reveal.

    +

    Phases happen in 90-second windows, and the Choose and Commit phases share the same window, so a whole attestation round takes 4.5 minutes.

    +
    +

    Collect-Choose-Commit-Reveal protocol +

    +
    The Collect-Choose-Commit-Reveal (CCCR) protocol.
    +
    +
      +
    • Collect phase: Users send their requests to the State Connector contract which forwards them to every attestation provider.
    • +
    • Choose phase: Attestation Providers vote on which requests they will be able to answer in the current round.
    • +
    • Commit phase: Attestation providers send obfuscated answers to the State Connector, so they cannot cheat by peeking at each other's submissions.
    • +
    • Reveal phase: Attestation providers send the deobfuscation key so their previous answers are revealed. + When all data is available, answers are made public if there is enough consensus.
    • +
    +

    The CCCR protocol is akin to making submissions in a closed envelope which is not opened until all submissions are received.

    +

    Results are available at the end of the Reveal phase, so the answer to a particular request can take anywhere from 3 to 4.5 minutes, depending on the time in which the request was made inside the Collect phase.

    +

    Furthermore, the phases of the CCCR protocol are actually overlapped, so while requests are being collected for round \((n+2)\), answers are being simultaneously committed for the previous round \((n+1)\), and revealed for the round prior to that \((n)\).

    +
    +

    Overlapped CCCR protocol +

    +
    The CCCR protocol with overlapped phases.
    +
    +

    This means that new requests can be made without waiting for the previous ones to be completed.

    +

    Attestation Packing#

    +

    Each round, attestation providers build a Merkle tree with the hashes of all valid answers to the requests that were agreed upon during the "Choose" phase. +The obtained Merkle root is then called the Attestation Proof, since it is proof of the presence of each individual answer. +Finally, the attestation proof is submitted to the State Connector for consensus evaluation.

    +
    +

    Attestation Proof packing using a Merkle tree +

    +
    Attestation Proof packing using a Merkle tree.
    +
    +

    This allows any number of requests to be answered with a single hash, greatly improving scalability. +Furthermore, the gas cost for attestation providers is constant each round, no matter how many requests they are answering.

    +

    A request is only valid (and therefore added to the proof) if it is well-formed and it matches reality. +Different providers might have different views on what reality is, and this is why the State Connector runs a consensus algorithm on the received answers.

    +

    Additionally, the allowed request types are carefully designed to minimize the probability of contention. +For example, requiring some time for transactions to settle before inquiring about them, and forcing requests to include the hash of a later block that confirms the transaction.

    +

    Attestation providers keep the actual retrieved data for a week, in case it contains additional information beyond the yes/no result. +Users can request this data directly from the providers through the Proof API.

    +
    +

    Note

    +

    Please note that this data is safe to use even though it is obtained directly from the provider, because its hash is consistent with the Attestation Proof agreed upon by the State Connector's consensus.

    +

    See the "Proof unpacking" box below to learn how to verify the data.

    +
    +

    Additional points worth noting:

    +
      +
    • +

      If two attestation providers observe a different validity for any of the requests in the round, they will submit a completely different Attestation Proof.

      +
    • +
    • +

      Attestation providers must answer all agreed-upon queries in the round or abstain from participating in the round, otherwise, their Merkle tree root will not match other providers and will probably be discarded by consensus.

      +
    • +
    • +

      Hashes are sorted before being added to the tree, just to have a consistent ordering (albeit arbitrary).

      +
    • +
    • +

      The exact way in which the root hash is calculated can be changed without impacting the State Connector contract, which will continue to vote only on the hash value.

      +
    • +
    +
    +Proof Unpacking (for App developers) +

    The procedure for apps to check whether the State Connector answered yes or no to their request is detailed in the Attestation Client repository. What follows is an illustrative summary.

    +

    The basic idea is that you must retrieve all data (both requests and answers) for the round from an attestation provider. +You then rebuild the Merkle tree with this data and check that it matches the Attestation Proof provided by the State Connector.

    +

    + Proof unpacking +
    Proof unpacking.
    +

    +
      +
    1. +

      In the attestation round after you made the request (3 attestation phases, so from 3 to 4.5 minutes) the Attestation Proof for the round should be available in the State Connector. + Retrieve it using method getAttestation (#7) of the StateConnector contract.

      +
    2. +
    3. +

      Select any attestation provider you want and use the Proof API path api/proof/votes-for-round/{roundId} to retrieve all data for the round.

      +
    4. +
    5. +

      Rebuild the Merkle tree for the retrieved data. +There are tools to help you, like the MerkleTree.ts library.

      +
    6. +
    7. +

      Check that the tree's root matches the Attestation Proof from step 1. +If it does not match, this provider did not submit the answer agreed by the majority. +Choose another provider in step 2.

      +

      Conversely, you can use the api/proof/get-specific-proof API in step 2 which does steps 2, 3 and 4 for you. +This API returns the JSON response data, including the attestation proof, if the attestation request was successfully verified in the given round.

      +
    8. +
    9. +

      Now that you know that the retrieved data has been agreed upon by the consensus, you can use it. +Look for your request inside the returned data. +If it is not present, your request was deemed invalid (for example, the queried transaction was not present).

      +

      Otherwise, your request is valid and you can find any extra information about it in the data array.

      +
    10. +
    +
    +

    Branching Protocol#

    +

    Besides the consensus algorithm that runs on all received attestations, the State Connector provides one further security mechanism: +the ability of any individual validator node to fork and halt execution if attestation providers specially trusted by it disagree with the majority.

    +

    Attestation Provider Sets#

    +

    To achieve this, two sets of attestation providers are defined:

    +
      +
    • +

      Default attestation providers set

      +

      Anybody can submit attestations to the State Connector, but the contract will only accept submissions from attestation providers in the default set. +Every validator node in the Flare network relies on this set.

      +
    • +
    • +

      Local attestation providers set

      +

      Additionally, each node operator can provide a list of local attestation providers to be accepted besides the ones from the default set.

      +

      Local providers are the same kind of nodes as default providers, and they are treated exactly the same by the State Connector. +Furthermore, providers can belong to both sets.

      +
    • +
    +
    +

    Default and Local attestation providers +

    +
    Default and Local attestation providers.
    +
    +
    +

    Then, for an attestation round to succeed these three conditions must be met:

    +
      +
    • +

      The default set must agree on a result (50% consensus inside the set).

      +
    • +
    • +

      The local set must agree on a result too (50% consensus inside the set).

      +
    • +
    • +

      Both results must match.

      +
    • +
    +

    Otherwise, the round is undecided and no answer is made public.

    +
    +

    This gives local attestation providers the capacity to stop results from being approved if they don't agree with their own observations. +Ideally, local providers are managed by the same entity controlling the validator node using them, so they can be trusted implicitly.

    +

    As a consequence of different validators using different attestation providers, sometimes State Connector queries can get different results on some validators, which naturally leads to chain forks.

    +

    Typically, blockchains allow every branch in a fork to coexist and grow independently, until the discrepancy is detected and resolved. +At that point, any branches deemed invalid are removed and all the validators that were following them experience a rollback: +All transactions that happened after the fork are reverted and the state of those validators is synchronized with the rest of the network.

    +

    When dealing with forks caused by the State Connector, the Flare network implements an extra security measure: +Validators whose local attestation providers disagree with the default set halt execution after the fork, ensuring that they will not suffer any rollback once the fork is resolved.

    +

    In other words, these validators remain in a safe state in which the disputed query is undecided and therefore no action is taken based on it.

    +
    +

    Example

    +

    + State Connector forks +
    State Connector forks.
    +

    +

    In the example picture, all validator nodes use the attestation providers from the default set (not shown), but validators on the rightmost column, additionally, employ local providers. +One of them returns a different answer for one of the queries, which leads to a fork of the chain since that validator's state does not match the rest of the network (the divergent ledger, depicted in red).

    +
    +

    The next section shows how forks are resolved and halted nodes restarted.

    +

    Branch Resolution#

    +
    +

    Branching +

    +
    The two states of the branching protocol.
    +
    +

    The picture above shows the state of the network after a fork. +The default network state is the one followed by validators which only use the default set of attestation providers. +The alternate network state is where validators go if they use local attestation providers, and they disagree with the default set.

    +

    In the alternate state no queries are answered and no blocks are produced, so it is a safe state for validators to wait for forks to be resolved.

    +

    This resolution must come from operators when they are alerted that a validator node has stopped. +To understand how to do this, note that attestations are designed to be objectively decidable, meaning that in the event of a fork one branch matches reality and the other does not.

    +

    There are therefore only two ways to resolve a fork:

    +
      +
    1. +

      When local providers are wrong:

      +

      The operator of the separated validator needs to find out why the local attestation providers failed and either fix them or remove them from the local set of the validator.

      +

      Once this is fixed, the node simply rewinds its state to where it split and quickly fast-forward to rejoin the default state.

      +

      + Fork resolution when local providers are wrong +
      Fork resolution when local providers are wrong.
      +

      +

      Note that no transactions need to be rolled back, on either branch.

      +

      In the event of this kind of fork, dapps depending on information from a separated validator just have to wait longer to get their result.

      +
    2. +
    3. +

      When the default set is wrong:

      +

      First off, this is a very delicate situation and it should be rare.

      +

      The default set uses consensus among attestation providers which have been chosen due to their merits as FTSO data providers. +The fact that more than 50% of them are reporting data inconsistent with reality can be considered a 51% attack.

      +

      The operator of the separated validator, upon convincing themselves that their branch is the correct one (it matches reality) they need to bring the fork to the attention of the misbehaving attestation providers' operators.

      +

      All validators in the default state then need to roll back to the last correct state (reverting transactions) and continue from there on the forked branch, which becomes the new default state.

      +

      + Fork resolution when the default set is wrong +
      Fork resolution when the default set is wrong.
      +

      +

      Note that stopped nodes can resume now, and they never had to roll back any transaction.

      +
    4. +
    +

    In summary, validators using at least one reliable local attestation provider do not have to worry about rollbacks, even in the face of 51% attacks.

    +

    Attestation Types#

    +

    Some attestation types are already defined. Attestation providers provide attestations for these types of defined requests:

    +
      +
    • Payment: Whether a payment transaction occurred in which funds were sent from one address to another address.
    • +
    • +

      Balance-decreasing transaction: Whether a transaction that might have decreased a balance occurred. This type allows for several possibilities:

      +
        +
      • During a transaction, funds, including fees, were deducted from the balance at an address. +As a result, the final balance at the address is less than the balance was before the transaction.
      • +
      • During a transaction, funds to pay for fees were deducted from the balance at an address at the same time as more funds arrived. +As a result, the balance at the address experienced a decrease, but the final balance is more than the balance was before the transaction.
      • +
      +
    • +
    • +

      Confirmed block height: Whether a block on a certain height exists and was confirmed.

      +
    • +
    • +

      Referenced payment nonexistence: Whether an account did not receive funds from a different account by a specific deadline. +This type can serve as proof that a user's payment obligations to a DeFi protocol have been breached, considering the following cases:

      +
        +
      • The required transaction was not confirmed on time.
      • +
      • The required transaction was confirmed on time but failed because of an error made by the sender.
      • +
      +
    • +
    +

    Adding New Attestation Types#

    +

    New real-world event-type integrations are introduced to the State Connector via acceptance by the default attestation providers, without requiring any changes to the core voting or branching protocols described above. +This enables rapid deployment of new use-cases without any validator-level code changes.

    +

    See the state-connector-attestation-types repository for more information.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tech/the-flaredrop/index.html b/tech/the-flaredrop/index.html new file mode 100644 index 000000000..5149f7f4e --- /dev/null +++ b/tech/the-flaredrop/index.html @@ -0,0 +1,3938 @@ + + + + + + + + + + + + + + + + + + The FlareDrop - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    The FlareDrop#

    +

    The FlareDrop, previously called the Delegation Incentive Pool in the FIP.01, is a distribution method for the 24.25B remaining $FLR tokens after the original airdrop. +It will last for 36 months and is destined for any holder of wrapped $FLR ($WFLR) that participates in the network as per the FIP.01.

    +

    If you enabled your PDA and it contains $WFLR, it is also eligible to receive the FlareDrop distribution. +Make sure to check both your Main Account and your Delegation Account for FlareDrop to claim.

    +

    How Is the FlareDrop Distributed?#

    +

    The FlareDrop is distributed monthly over 36 30-day bank months to those that wrap their $FLR tokens. +Each of the first 35 monthly allocations constitute 2.37% of the total FlareDrop, and the last one 2.05%.

    +

    The total amount of $WFLR is calculated each month, and the monthly allocation is distributed among all $WFLR holders proportionally to the sampled average of their $WFLR balance. +Users then receive an amount equal to their month's sampled $WFLR holdings divided by the month's total $WFLR, multiplied by the monthly allocation.

    +
    +

    Calculating an address's sampled average balance

    +

    As each bank month passes, the FlareDrop receives a trigger to choose 3 random blocks in the previous 23 days. +The FlareDrop smart contract then finds the average of the total $WFLR reported in those blocks and determines each address's percentage of the FlareDrop. +

    +3 Week Average $WFLR +
    3-week average of wrapped $FLR.
    +

    +
    +

    Upon claiming, the entitlement is sent directly to the account you claimed from. +It is sent as $FLR to your Main Account and as $WFLR to your Personal Delegation Account (PDA). +Each distribution expires two bank months and a week (67 days) after it becomes claimable and expired tokens are burned.

    +

    To ensure having no effect on the amount of $FLR that each claiming address receives, Flare Foundation and team addresses opt out of the FlareDrop distribution.

    +
    +

    Two steps to ensure receiving all your $FLR !

    +

    You must:

    +
      +
    1. Wrap $FLR to receive it. +Rewards are proportional to the $WFLR balance, not $FLR, so always wrap as much $FLR as you can! +Wrapping has no downside: Wrapped tokens continue to be available for delegation and governance voting, for example, and they can be unwrapped at any time.
    2. +
    3. Claim before the distribution expires. +After the distribution becomes claimable, it expires in two bank months and a week (67 days).
    4. +
    +
    +

    You can also enable automatic claiming to make sure you don't miss any FlareDrop! Autoclaiming will claim for both your main account and your PDA if you enabled it.

    + + + + + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tech/validators/index.html b/tech/validators/index.html new file mode 100644 index 000000000..6d2033c6c --- /dev/null +++ b/tech/validators/index.html @@ -0,0 +1,4123 @@ + + + + + + + + + + + + + + + + + + Validator Nodes - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Validator Nodes#

    +

    Blockchain Validation#

    +

    Validator nodes are online servers running a blockchain's client software. +They all keep their own copy of the ledger and are constantly talking to other nodes to make sure the copies are consistent with each other as new data is added.

    +
    +

    Validator node network +

    +
    A network of validator nodes, each one with an identical copy of the ledger.
    +
    +

    The fact that the ledger is not under control of a single entity but distributed among a network of independent validators is what makes blockchains:

    + +

    Validators agree on the state of the ledger using a consensus algorithm that varies for each blockchain. +For example, Flare uses the Snowman++ consensus protocol from Avalanche.

    +
    +

    Snowman++

    +

    During each round, a validator is randomly selected to act as the leader and propose new blocks to be added to the ledger, which are then validated by the rest of nodes. +To provide Sybil resistance, the probability that a node is elected the leader is proportional to the node's stake, effectively enacting a proof-of-stake consensus.

    +
    +

    With its vision to be the blockchain for data, Flare adds the FTSO Data provider and Attestation Provider roles to validators, creating a single infrastructure entity.

    +

    When fully operational, these decentralized infrastructure entities are responsible for:

    +
      +
    • Securing the network through proof-of-stake consensus.
    • +
    • Providing continuous data to the FTSO system.
    • +
    • Answering the State Connector's queries for attestations.
    • +
    +

    In this way, the stake required to operate these entities secures all three functions.

    +

    Infrastructure entities are rewarded for each one of these roles, a process that involves staking on the P-chain and rewards that are calculated on smart contracts running on the C-chain.

    +

    Deployment Phases#

    +

    Deployment will occur in different phases for a number of reasons:

    +
      +
    • Infrastructure entities will be onboarded progressively, to ensure the uninterrupted working of the network.
    • +
    • Current FTSO data providers need to build a minimum stake to act as validators.
    • +
    • Current validators need to upgrade their capabilities to act as data providers.
    • +
    +

    Each phase will increasingly relinquish control, so more network validation will happen independently of the Flare Foundation.

    +

    Initial State#

    +

    Upon network launch on July 14th 2022, a set of 20 validators had their node IDs hard-coded into the client software, so no other validators could participate. +The Flare Foundation managed these nodes and gradually reassigned 16 of them to 4 external entities to achieve greater decentralization. +These entities, known as professional validators, are infrastructure providers with experience managing blockchain nodes.

    +

    During this period FTSO data providers operated completely independently of validators. +The State Connector protocol was still being developed, so no attestation providers were available.

    +

    Phase 1#

    +

    On July 2023 a network fork enabled Avalanche's proof-of-stake mechanism. +From this moment, validation was open to everybody. +At the same time, all the stake from the original validators expired.

    +

    The Flare Foundation loaned all the stake for the initial validators, so the distribution of validation power remained the same while proof-of-stake was being tested.

    +

    Later, after some FTSO data providers went through a KYC process, the Flare Foundation loaned enough funds to them to deploy validation nodes and act as validators.

    +

    Because staking happens on the P-chain, staked tokens cannot access the rewards managed by smart contracts running on the C-chain. +To solve this problem, a communication mechanism between the two chains is being developed.

    +

    All staking rewards are manually calculated off-chain, and then distributed on-chain. +The calculations will initially be private while they are fine-tuned, and the script will be made public in phase 2 so that anybody can verify them.

    +

    Phase 2#

    +

    Once FTSO data providers have gathered enough stake to ensure the network's continued working, all stake loaned by the Flare Foundation to the validators in the initial state will be withdrawn. +Professional validators are expected to cease operating at this point, unless they provide their own stake.

    +

    The Flare Foundation might delegate stake to FTSO data providers that went through the KYC process, to help kick-start the system. +This is known as stake boosting and will run only for a limited amount of time.

    +

    Staked funds can earn FlareDrops and participate in governance, but not earn FTSO rewards.

    +

    Staking rewards will:

    +
      +
    • Take into account validator uptime, which can be publicly monitored.
    • +
    • Take into account staked amount.
    • +
    • Require that the validator is also an FTSO data provider that is being constantly rewarded for providing good enough prices.
    • +
    • Be manually calculated off-chain using a public script, and then distributed on-chain.
    • +
    +

    Phase 3#

    +

    After secure communication between the P- and C-chains is available, staking rewards will be managed entirely on-chain. +The goal is that funds staked on the P-chain will have the same rights as wrapped $FLR on the C-chain, opening the possibility to earn FTSO rewards, FlareDrops and participate in governance.

    +

    Summary#

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    LaunchPhase 1Phase 2Phase 3
    Validation open to everybody
    Validators must provide own stake
    Validators must be data providers to earn rewards
    Locked stake can earn staking rewards
    Staking rewards are handled on-chain
    Same rights for staked and wrapped tokens
    +
    + + + + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/technology/glossary/index.html b/technology/glossary/index.html new file mode 100644 index 000000000..89a6d1bcb --- /dev/null +++ b/technology/glossary/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/technology/state-connector/index.html b/technology/state-connector/index.html new file mode 100644 index 000000000..109d47cb7 --- /dev/null +++ b/technology/state-connector/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/delegation-faq/block-explorer-+-metamask/index.html b/tutorials/delegation-faq/block-explorer-+-metamask/index.html new file mode 100644 index 000000000..6eadb7739 --- /dev/null +++ b/tutorials/delegation-faq/block-explorer-+-metamask/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/delegation-faq/index.html b/tutorials/delegation-faq/index.html new file mode 100644 index 000000000..79f677a3b --- /dev/null +++ b/tutorials/delegation-faq/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/delegation/delegation-in-detail/index.html b/tutorials/delegation/delegation-in-detail/index.html new file mode 100644 index 000000000..6a1a60a9e --- /dev/null +++ b/tutorials/delegation/delegation-in-detail/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/delegation/index.html b/tutorials/delegation/index.html new file mode 100644 index 000000000..ce5c84e9b --- /dev/null +++ b/tutorials/delegation/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/developing-on-top-of-flare/important-links/index.html b/tutorials/developing-on-top-of-flare/important-links/index.html new file mode 100644 index 000000000..ca2a185b1 --- /dev/null +++ b/tutorials/developing-on-top-of-flare/important-links/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/developing-on-top-of-flare/index.html b/tutorials/developing-on-top-of-flare/index.html new file mode 100644 index 000000000..06839e9fd --- /dev/null +++ b/tutorials/developing-on-top-of-flare/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/explorer/coston-explorer/index.html b/tutorials/explorer/coston-explorer/index.html new file mode 100644 index 000000000..e239efe04 --- /dev/null +++ b/tutorials/explorer/coston-explorer/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/explorer/songbird-explorer/index.html b/tutorials/explorer/songbird-explorer/index.html new file mode 100644 index 000000000..e239efe04 --- /dev/null +++ b/tutorials/explorer/songbird-explorer/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/price-provider/ftso-price-provider/index.html b/tutorials/price-provider/ftso-price-provider/index.html new file mode 100644 index 000000000..53bd88207 --- /dev/null +++ b/tutorials/price-provider/ftso-price-provider/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/price-provider/ftso-price-provider/price-provider-faq/index.html b/tutorials/price-provider/ftso-price-provider/price-provider-faq/index.html new file mode 100644 index 000000000..302352de2 --- /dev/null +++ b/tutorials/price-provider/ftso-price-provider/price-provider-faq/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/price-provider/ftso-price-provider/whitelisting-a-price-provider/index.html b/tutorials/price-provider/ftso-price-provider/whitelisting-a-price-provider/index.html new file mode 100644 index 000000000..ea96991ff --- /dev/null +++ b/tutorials/price-provider/ftso-price-provider/whitelisting-a-price-provider/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/price-provider/ftso-price-provider/whitelisting-price-provider-faq/index.html b/tutorials/price-provider/ftso-price-provider/whitelisting-price-provider-faq/index.html new file mode 100644 index 000000000..ea96991ff --- /dev/null +++ b/tutorials/price-provider/ftso-price-provider/whitelisting-price-provider-faq/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/price-provider/setting-up-an-observation-node/index.html b/tutorials/price-provider/setting-up-an-observation-node/index.html new file mode 100644 index 000000000..81f790a6d --- /dev/null +++ b/tutorials/price-provider/setting-up-an-observation-node/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/price-provider/setting-up-an-observation-node/observation-node-faq/index.html b/tutorials/price-provider/setting-up-an-observation-node/observation-node-faq/index.html new file mode 100644 index 000000000..ec6e3a5fe --- /dev/null +++ b/tutorials/price-provider/setting-up-an-observation-node/observation-node-faq/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/price-provider/troubleshooting/observation-node/index.html b/tutorials/price-provider/troubleshooting/observation-node/index.html new file mode 100644 index 000000000..ec6e3a5fe --- /dev/null +++ b/tutorials/price-provider/troubleshooting/observation-node/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/price-provider/troubleshooting/price-provider/index.html b/tutorials/price-provider/troubleshooting/price-provider/index.html new file mode 100644 index 000000000..302352de2 --- /dev/null +++ b/tutorials/price-provider/troubleshooting/price-provider/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/price-provider/whitelisting/index.html b/tutorials/price-provider/whitelisting/index.html new file mode 100644 index 000000000..566a3b6c9 --- /dev/null +++ b/tutorials/price-provider/whitelisting/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/reward-claiming/index.html b/tutorials/reward-claiming/index.html new file mode 100644 index 000000000..79f677a3b --- /dev/null +++ b/tutorials/reward-claiming/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/reward-claiming/reward-claiming-in-detail/index.html b/tutorials/reward-claiming/reward-claiming-in-detail/index.html new file mode 100644 index 000000000..287ec7fc3 --- /dev/null +++ b/tutorials/reward-claiming/reward-claiming-in-detail/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/reward-faq/block-explorer-+-metamask/index.html b/tutorials/reward-faq/block-explorer-+-metamask/index.html new file mode 100644 index 000000000..287ec7fc3 --- /dev/null +++ b/tutorials/reward-faq/block-explorer-+-metamask/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/reward-faq/index.html b/tutorials/reward-faq/index.html new file mode 100644 index 000000000..79f677a3b --- /dev/null +++ b/tutorials/reward-faq/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/wallets/bifrost-wallet/index.html b/tutorials/wallets/bifrost-wallet/index.html new file mode 100644 index 000000000..347b324c4 --- /dev/null +++ b/tutorials/wallets/bifrost-wallet/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/wallets/brave-wallet/index.html b/tutorials/wallets/brave-wallet/index.html new file mode 100644 index 000000000..a546d8a74 --- /dev/null +++ b/tutorials/wallets/brave-wallet/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/wallets/dcent-wallet/index.html b/tutorials/wallets/dcent-wallet/index.html new file mode 100644 index 000000000..f80fc6afa --- /dev/null +++ b/tutorials/wallets/dcent-wallet/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/wallets/how-to-access-flare-network-with-a-ledger-device/index.html b/tutorials/wallets/how-to-access-flare-network-with-a-ledger-device/index.html new file mode 100644 index 000000000..f00beb5bb --- /dev/null +++ b/tutorials/wallets/how-to-access-flare-network-with-a-ledger-device/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/wallets/how-to-access-flare-network-with-a-trezor-device/index.html b/tutorials/wallets/how-to-access-flare-network-with-a-trezor-device/index.html new file mode 100644 index 000000000..22247b479 --- /dev/null +++ b/tutorials/wallets/how-to-access-flare-network-with-a-trezor-device/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/wallets/how-to-access-flare-network-with-metamask/index.html b/tutorials/wallets/how-to-access-flare-network-with-metamask/index.html new file mode 100644 index 000000000..7ac4e3da9 --- /dev/null +++ b/tutorials/wallets/how-to-access-flare-network-with-metamask/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/wallets/index.html b/tutorials/wallets/index.html new file mode 100644 index 000000000..bf476b4f7 --- /dev/null +++ b/tutorials/wallets/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/tutorials/wallets/safepal-s1-wallet/index.html b/tutorials/wallets/safepal-s1-wallet/index.html new file mode 100644 index 000000000..521b57f28 --- /dev/null +++ b/tutorials/wallets/safepal-s1-wallet/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/user-icon.svg b/user-icon.svg new file mode 100644 index 000000000..52f385041 --- /dev/null +++ b/user-icon.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/user/automatic-claiming/index.html b/user/automatic-claiming/index.html new file mode 100644 index 000000000..1a070e939 --- /dev/null +++ b/user/automatic-claiming/index.html @@ -0,0 +1,4001 @@ + + + + + + + + + + + + + + + + + + Automatic Claiming - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Automatic Claiming#

    +

    To save time, maximize compound interest, and avoid unnecessary exposure of a cold wallet, you can set an executor to claim rewards for you. +Executors then use automatic claiming to send rewards directly to your account.

    +

    Introduction#

    +

    To set an executor you only need to enter its address in the Flare Portal.

    +

    However, the Flare Portal does not help you find executor addresses, so you must find them in different ways, depending on whether they are manual or registered:

    +
      +
    • Manual executors are ones that you locate yourself. + Whether they charge a fee or not and how you pay it is between you and the executor.
    • +
    • Registered executors are listed in a smart contract and can be retrieved, for instance, using the block explorer or third-party applications. + These executors charge a fee when you set them up and every time they claim for you.
    • +
    +
    +

    Overview of autoclaiming functionality

    +

    For an overview of what is available for the entire autoclaiming feature, see Automatic Claiming in the Flare Fundamentals section.

    +
    +

    Prerequisite#

    +

    To enable an executor, obtain its address off-chain or, for registered executors, on-chain.

    +

    The list of registered executors has not been added yet to the Flare Portal, but a manual method is given below using the block explorer (recommended for advanced users).

    +
    +Find a registered executor (using the Block Explorer) +

    To find an executor you will need to use the ClaimSetupManager contract. +See the Contract Addresses page to learn how to find the address of this contract.

    +
      +
    1. In the Block Explorer, paste the address of the ClaimSetupManager contract and scroll down to select the Read Contract tab.
    2. +
    3. To get the available executors' addresses, scroll down to getRegisteredExecutors and enter a range of how many addresses to check, for example, 0 in the _start field and 10 in the _end field.
    4. +
    5. Click Query. The Block Explorer returns the addresses and the total number available, so you can know if you've gotten them all.
    6. +
    7. To get the executor's fee, copy one address at a time and enter it in the executor field for getExecutorCurrentFeeValue.
    8. +
    9. Click Query. +In the future, there will be more criteria to help with making this decision.
    10. +
    11. Choose an executor and copy its address.
    12. +
    +
    +

    Enabling Automatic Claiming#

    +

    Now that you have your desired executor's address, you can set it as the executor for your account.

    +
      +
    1. Open the Flare Portal.
    2. +
    3. Click Connect to Wallet and log into your wallet. + The interface to your Main Account opens. +
      + Flare Portal Main Account +
      Flare Portal Main Account interface.
      +
    4. +
    5. In the Executor section, click Add or Change.
    6. +
    7. Paste the executor's address. + A message confirms the executor's fee, whether it is a registered executor, and whether rewards go to your Main Account or your Personal Delegation Account (PDA). +
      + Set an executor +
      Set an executor.
      +
    8. +
    9. To set this executor, click Confirm. + Your wallet opens with the details of the transaction.
    10. +
    11. Review the transaction and confirm it.
    12. +
    +

    If you confirm the executor, the Flare Portal displays the executor address you have selected, whether it is registered, and its fee. +Note also that the Add button now reads Change, enabling you to remove or change the executor any time you choose.

    +
    +

    The executor is confirmed

    +
    The executor is confirmed.
    +
    +
    +

    Reward must be high enough to pay the executor's fee

    +

    If the reward amount is too low to accommodate the fee, automatic claims won't occur, so you may see small amounts of unclaimed rewards even if you have autoclaiming set up.

    +
    +

    Disabling Automatic Claiming#

    +

    To disable automatic claiming and stop paying the executor fees, go through the above process again and clear the Executor address field in Step 4. +This is, confirm an empty address.

    +

    Once you confirm the transaction in your wallet, automatic claiming will be disabled.

    +

    Checking for Accrued Rewards#

    +

    To check if you have accrued rewards, go to the Flare Portal:

    +
      +
    1. Click Connect to Wallet and log into your wallet.
    2. +
    3. Select your Main Account or Delegation Account, if you have enabled a PDA.
    4. +
    5. At the bottom of the screen, see the Claim x FLR button, where x is the number of $FLR rewards you can claim.
    6. +
    +
    +

    Note

    +

    If the configured executor is doing its job correctly, you should never see any pending rewards.

    +
    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/block-explorers/finding-reward-epoch/index.html b/user/block-explorers/finding-reward-epoch/index.html new file mode 100644 index 000000000..4885b6cd9 --- /dev/null +++ b/user/block-explorers/finding-reward-epoch/index.html @@ -0,0 +1,3842 @@ + + + + + + + + + + + + + + + + + + Finding the Reward Epoch - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Finding the Reward Epoch#

    +
    +

    This page is for advanced users.

    +
    +

    Reward epochs are periods during which delegations rewards are accrued. Use the block explorer to find the current reward epoch, which you can use to find the epoch for which you can claim rewards and to determine the vote-power block for the next epoch.

    +
      +
    1. Open a block explorer for the appropriate network. + The block explorer dashboard is displayed.
    2. +
    3. From the block explorer, follow the Retrieval from Blockchain procedure to find and open the FtsoManager contract. + The Contract Address Details page is displayed.
    4. +
    5. +

      Click the Read Contract tab, and locate the getCurrentRewardEpoch method. + The current reward epoch number is already displayed beside the function, as shown in the following example:

      +

      +Current Reward Epoch +
      Current Reward Epoch.
      +

      +

      In this example, the FTSO reward epoch is 80.

      +
    6. +
    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/block-explorers/index.html b/user/block-explorers/index.html new file mode 100644 index 000000000..c50184497 --- /dev/null +++ b/user/block-explorers/index.html @@ -0,0 +1,3848 @@ + + + + + + + + + + + + + + + + + + Block Explorers - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Block Explorers#

    +

    Block explorers enable you to analyze transactions and interact with addresses on blockchains.

    +

    Flare provides a block explorer for each of the networks in its ecosystem:

    + +

    Topics#

    + + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/block-explorers/managing-delegations/index.html b/user/block-explorers/managing-delegations/index.html new file mode 100644 index 000000000..65b9e5ff2 --- /dev/null +++ b/user/block-explorers/managing-delegations/index.html @@ -0,0 +1,4049 @@ + + + + + + + + + + + + + + + + + + Managing Delegations - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Managing Delegations Using the Block Explorer#

    +
    +

    This page is for advanced users.

    +
    +

    When you make delegations to FTSO data providers, you increase their vote power, reinforce the stability of the FTSO ecosystem, and earn monetary rewards.

    +

    Use the following information to manage your vote-power delegations with the the block explorer, which provides many options but is more complex. +Alternatively, if you prefer a simpler interface, use the Flare Portal.

    +

    Prerequisites#

    +

    Before you delegate your vote power, you must:

    + +

    Delegating Your Vote Power#

    +
      +
    1. After you choose your data provider from the list of data providers, locate its address beneath its name, and copy it.
    2. +
    3. +

      To verify the address of the data provider, open a block explorer, paste the address in the search field, and click the same address displayed as the result.

      +

      On the Transactions tab, a list of recently submitted SubmitHash and RevealPrices transactions are displayed to confirm that the data provider is operating.

      +
    4. +
    5. +

      Open a block explorer for the appropriate network. + The block explorer dashboard is displayed.

      +
    6. +
    7. Follow the Retrieval from Blockchain procedure to find and open the WNat contract. + The Contract Address Details page is displayed.
    8. +
    9. +

      Click the Write Contract tab, and then click Connect Wallet, as shown in the following image:

      +

      +Write Contract Tab and Connect Your Wallet +
      Write Contract Tab and Connect Your Wallet.
      +

      +
    10. +
    11. +

      Complete the steps to connect your wallet.

      +
    12. +
    13. +

      Locate the delegate method, and specify values for these parameters:

      +
        +
      • _to(address): The address for the data provider you copied in Step 1.
      • +
      • _bips(uin256): The percentage in basis points. For example, 10000 bips = 100%, and 5000 bips = 50%.
      • +
      +
    14. +
    15. +

      Click Write to run the delegate method.

      +
    16. +
    17. Follow the steps to complete the transaction in your wallet. + Delegation is complete.
    18. +
    +

    In the next reward epoch, your newly delegated tokens will be included in the calculation of your selected data provider's weight. + If the data provider submits useful data and garners any rewards, you will be able to claim your share of the rewards when the reward epoch is over.

    +

    Removing Delegations#

    +
      +
    1. Open a block explorer for the appropriate network. + The block explorer dashboard is displayed.
    2. +
    3. Follow the Retrieval from Blockchain procedure to find and open the WNat contract. + The Contract Address Details page is displayed.
    4. +
    5. +

      Click the Write Contract tab, and then click Connect Wallet, as shown in the following image:

      +

      +Write Contract Tab and Connect Your Wallet +
      Write Contract Tab and Connect Your Wallet.
      +

      +
    6. +
    7. +

      Complete the steps to connect your wallet.

      +
    8. +
    9. Locate the delegate method, change the value of _bips(uin256) for the data provider's address to 0, and click Write to run the method.
    10. +
    11. Follow the steps to complete the transaction in your wallet.
    12. +
    +

    Redelegating Vote Power#

    +
      +
    1. Open a block explorer for the appropriate network. + The block explorer dashboard is displayed.
    2. +
    3. Follow the Retrieval from Blockchain procedure to find and open the WNat contract. + The Contract Address Details page is displayed.
    4. +
    5. +

      Click the Write Contract tab, and then click Connect Wallet, as shown in the following image:

      +

      +Write Contract Tab and Connect Your Wallet +
      Write Contract Tab and Connect Your Wallet.
      +

      +
    6. +
    7. +

      Complete the steps to connect your wallet.

      +
    8. +
    9. Locate the undelegateAll method, and click Write to run the method.
    10. +
    11. Follow the steps to complete the transaction in your wallet. + All your delegations are removed.
    12. +
    13. Delegate to the data providers you've chosen by following the previous set of steps to delegate.
    14. +
    +

    Revoking Vote Power#

    +

    You can immediately revoke your vote power from a malicious data provider.

    +
      +
    1. Open a block explorer for the appropriate network. + The block explorer dashboard is displayed.
    2. +
    3. Follow the Retrieval from Blockchain procedure to find and open the WNat contract. + The Contract Address Details page is displayed.
    4. +
    5. +

      Click the Write Contract tab, and then click Connect Wallet, as shown in the following image:

      +

      +Write Contract Tab and Connect Your Wallet +
      Write Contract Tab and Connect Your Wallet.
      +

      +
    6. +
    7. +

      Complete the steps to connect your wallet.

      +
    8. +
    9. +

      Locate the revokeDelegationAt method, and specify values for the following parameters:

      +
        +
      • _who(address): The address of the data provider from whom you will revoke your delegation.
      • +
      • _blockNumber(uint256): The block number at which your delegation will be revoked.
      • +
      +
    10. +
    11. +

      Click Write to run the method.

      +
    12. +
    13. Follow the steps to complete the transaction in your wallet. + Your delegation is immediately revoked.
    14. +
    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/block-explorers/managing-rewards/index.html b/user/block-explorers/managing-rewards/index.html new file mode 100644 index 000000000..7fdfa6123 --- /dev/null +++ b/user/block-explorers/managing-rewards/index.html @@ -0,0 +1,3967 @@ + + + + + + + + + + + + + + + + + + Managing Rewards - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Managing Rewards Using the Block Explorer#

    +
    +

    This page is for advanced users.

    +
    +

    Rewards are accrued from your delegations to FTSO data providers whose submitted data is close to the calculated median value in a price epoch.

    +

    Use the following information to check your reward balance and claim your rewards with the block explorer, which provides many options but is more complex. +Alternatively, if you prefer a simple interface, use the Flare Portal.

    +

    Checking Your Reward Balance#

    +
      +
    1. Open a block explorer for the appropriate network. + The block explorer dashboard is displayed.
    2. +
    3. Follow the Retrieval from Blockchain procedure to find and open the FtsoRewardManager contract. + The Contract Address Details page is displayed.
    4. +
    5. +

      Click the Read Contract tab, and then click Connect Wallet, as shown in the following image:

      +

      +Read Contract Tab and Connect Your Wallet +
      Read Contract Tab and Connect Your Wallet.
      +

      +
    6. +
    7. +

      Complete the steps to connect your wallet.

      +
    8. +
    9. +

      Locate the getStateOfRewards method, and specify values for the following parameters:

      +
        +
      • _beneficiary(address): The address to check for rewards.
      • +
      • _rewardEpoch(uint256): The epoch in which you want to check the address for rewards. To check rewards for the epoch currently in progress, get the current reward epoch.
      • +
      +
    10. +
    11. +

      Click Query to run the getStateOfRewards method. + The following information is returned:

      +
        +
      • _dataProviders: List of providers to which the address delegated vote power during this epoch.
      • +
      • _rewardAmounts: List of reward amounts from each delegation.
      • +
      • _claimed: List of boolean values indicating whether each of the amounts has already been claimed.
      • +
      • _claimable: Boolean value indicating whether rewards for the address are claimable. Rewards are claimable if they are not expired and the epoch has ended. The value of _claimable is independent of the value of _claimed.
      • +
      +
    12. +
    +

    Claiming Your Rewards#

    +
      +
    1. Open a block explorer for the appropriate network. + The block explorer dashboard is displayed.
    2. +
    3. Follow the Retrieval from Blockchain procedure to find and open the FtsoRewardManager contract. + The Contract Address Details page is displayed.
    4. +
    5. +

      Click the Read Contract tab, and then click Connect Wallet, as shown in the following image:

      +

      +Read Contract Tab and Connect Your Wallet +
      Read Contract Tab and Connect Your Wallet.
      +

      +
    6. +
    7. +

      Complete the steps to connect your wallet. + In the next steps, you will check this wallet for accrued rewards. + You can disconnect this wallet and connect a different wallet as frequently as necessary.

      +
    8. +
    9. Run the getEpochsWithUnclaimedRewards(beneficiary_address) method by clicking Query. + A list of previous epochs with pending rewards to be claimed is returned.
    10. +
    11. +

      On the Write Contract tab, locate the claimReward method, and specify values for the following parameters:

      +
        +
      • _recipient(address): The address to which you want claimed rewards to be sent. +It can be the address you used to connect your wallet to the block explorer or a different address.
      • +
      • _rewardEpochs(uint256[]): One or more epoch numbers retrieved in Step 5. +Specify multiple epoch numbers in a comma-separated list enclosed by square brackets, such as [59,60].
      • +
      +
    12. +
    13. +

      Click Write to run the claimReward method. One of the following results occurs:

      +
        +
      • The claimReward method prompts you to confirm the transaction. + Go to Step 8.
      • +
      • The claimReward method fails. For security reasons, the FtsoRewardManager contract contains a limited amount of tokens and is replenished periodically. +Sometimes, all delegators claim their rewards in a short period of time immediately after the reward epoch ends, and the contract becomes empty. +If you are unable to claim your rewards because the contract is empty, try again the next day.
      • +
      +
    14. +
    15. +

      Follow the steps to confirm the transaction in your wallet. + Your rewards are claimed, and your updated balance of native tokens is displayed.

      +
    16. +
    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/block-explorers/user-interface/index.html b/user/block-explorers/user-interface/index.html new file mode 100644 index 000000000..379c9cee0 --- /dev/null +++ b/user/block-explorers/user-interface/index.html @@ -0,0 +1,3964 @@ + + + + + + + + + + + + + + + + + + Block Explorer Dashboard - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Block Explorer Dashboard#

    +

    Each block explorer provides a dashboard that includes the following elements:

    +
    +

    Block Explorer Dashboard

    +
    Block Explorer Dashboard.
    +
    + + +

    Use the options in the navigation bar to explore the blockchain and toggle light and dark modes.

    +
      +
    • Blocks: View recently created blocks and their constituent transactions.
    • +
    • Transactions: View validated or pending transactions.
    • +
    • Tokens: View a list of all the tokens on the blockchain or the addresses of wallets that hold a specific token.
    • +
    • APIs: For web3 developers to retrieve blockchain data.
    • +
    • Network: View the explorers for other networks in the Flare ecosystem.
    • +
    • Display theme: Toggle between light and dark mode.
    • +
    • Search: Search the blockchain by address, token symbol, token name, transaction hash, or block number.
    • +
    +

    Metrics#

    +

    The metrics section displays the following information:

    +
      +
    • Gas tracker: The average amount of gas required to process a transaction on a Flare network. Gas is denominated in units of gwei, where 1,000,000,000 gwei equals one token on a Flare network.
    • +
    • Average block time: The average time required to confirm a block.
    • +
    • Total transactions: The total amount of verified transactions.
    • +
    • Total blocks: The total amount of confirmed blocks.
    • +
    • Wallet addresses: The total amount of wallets created on the network.
    • +
    +

    Blocks#

    +

    A block is a group of transactions submitted, validated, and recorded on the blockchain. +Each block has a sequential ID and a number of transactions aggregated in the block. +To view details about a block and the transactions it contains, click the block ID. +Alternatively, view a continuous list of confirmed blocks as they occur by clicking View All Blocks.

    +
    +

    Blocks

    +
    Blocks.
    +
    +

    Transactions#

    +

    Transactions are the various actions you can take on a blockchain. +They are categorized by the following types:

    +
      +
    • Standard: Transfers of tokens between two wallets.
    • +
    • Contract: Interactions between two smart contracts or a wallet and a smart contract. + Contract transactions include delegating tokens, transferring tokens, wrapping and unwrapping tokens, and so on. + Interactions between two smart contracts are internal transactions.
    • +
    +
    +

    Transaction Types

    +
    Transaction Types.
    +
    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/block-explorers/verifying-vote-power-block/index.html b/user/block-explorers/verifying-vote-power-block/index.html new file mode 100644 index 000000000..94e3d942f --- /dev/null +++ b/user/block-explorers/verifying-vote-power-block/index.html @@ -0,0 +1,3848 @@ + + + + + + + + + + + + + + + + + + Verifying the Vote-Power Block - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Verifying the Vote-Power Block#

    +
    +

    This page is for advanced users.

    +
    +

    Use the block explorer to verify the vote-power block snapshot for a specific epoch. +The snapshot indicates when your delegations are enacted.

    +
      +
    1. Open a block explorer for the appropriate network. + The block explorer dashboard is displayed.
    2. +
    3. From the block explorer, follow the Retrieval from Blockchain procedure to find and open the FtsoManager contract. + The Contract Address Details page is displayed.
    4. +
    5. Click the Read Contract tab.
    6. +
    7. On the Read Contract tab, locate the getRewardEpochVotePowerBlock method, and specify the epoch number.
    8. +
    9. Click Query to run the getRewardEpochVotePowerBlock method. + The block number that was used to determine the vote power for the next epoch is returned.
    10. +
    11. +

      Copy this block number, paste it into the Search field, and press Enter. + The Block Details page is displayed. + The timestamp is displayed, as shown in the following image:

      +

      +Vote-Power Block Snapshot +
      Vote-Power Block Snapshot.
      +

      +

      The displayed timestamp is the exact date and UTC time when vote power was locked during the epoch you specified.

      +
    12. +
    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/block-explorers/viewing-nfts/index.html b/user/block-explorers/viewing-nfts/index.html new file mode 100644 index 000000000..76bab350d --- /dev/null +++ b/user/block-explorers/viewing-nfts/index.html @@ -0,0 +1,3840 @@ + + + + + + + + + + + + + + + + + + Viewing NFTs - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Viewing NFTs#

    +
    +

    This page is for advanced users.

    +
    +

    Use the block explorer to view NFTs. +Before you begin, ensure the status of the transaction to mint the NFT is Confirmed.

    +
      +
    1. Retrieve the transaction hash for the NFT.
    2. +
    3. Open a block explorer for the appropriate network. + The block explorer dashboard is displayed.
    4. +
    5. Specify the NFT transaction hash from Step 1 in the Search field, and click the result. + The Transaction Details page is displayed.
    6. +
    7. Locate the Tokens Minted section. + The value of the For parameter is the numerical ID for the NFT.
    8. +
    9. Click the ID. The NFT collection page is displayed. + In most cases, your NFT is displayed in the upper-right hand side of the page. + However, if the NFT creator used public IPFS gateways or did not create the NFT according to the ERC-721 or ERC-1155 standards, the NFT might not display.
    10. +
    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/block-explorers/viewing-token-balances/index.html b/user/block-explorers/viewing-token-balances/index.html new file mode 100644 index 000000000..7726526dc --- /dev/null +++ b/user/block-explorers/viewing-token-balances/index.html @@ -0,0 +1,3909 @@ + + + + + + + + + + + + + + + + + + Viewing Token Balances - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Viewing Token Balances#

    +
    +

    This page is for advanced users.

    +
    +

    Use the block explorer to view the list of token balances at an address.

    +
      +
    1. Retrieve the address whose tokens you want to view.
    2. +
    3. Open the block explorer for the appropriate network. The block explorer dashboard is displayed.
    4. +
    5. Insert the address from Step 1 into the Search field. If the address exists, it is highlighted in the results list.
    6. +
    7. Click the highlighted address. The Address Details page is displayed.
    8. +
    9. +

      Click the Tokens tab, as shown in the following image:

      +

      +Tokens +
      Tokens.
      +

      +
    10. +
    +

    The address's $FLR balance and a list of the non-native tokens it contains are displayed. The list can include ERC-20, ERC-721, and ERC-1155 tokens.

    +

    Balance History#

    +

    Use the block explorer to view a historical chart of the native-token balance at the address.

    +
      +
    1. Retrieve the address whose tokens you want to view.
    2. +
    3. Open the block explorer for the network appropriate network. + The block explorer dashboard is displayed.
    4. +
    5. Insert the address from Step 1 into the Search field. + If the address exists, it is highlighted in the results list.
    6. +
    7. Click the highlighted address. The Address Details page is displayed.
    8. +
    9. +

      Click the Coin Balance History tab, as shown in the following image:

      +

      +Coin Balance History +
      Coin Balance History.
      +

      +

      A chart that shows the history of the native token at the address and a list of associated blocks is displayed, as shown in the following image:

      +

      +Coin Balance Chart +
      Coin Balance Chart.
      +

      +
    10. +
    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/block-explorers/viewing-token-transfers/index.html b/user/block-explorers/viewing-token-transfers/index.html new file mode 100644 index 000000000..15cecea72 --- /dev/null +++ b/user/block-explorers/viewing-token-transfers/index.html @@ -0,0 +1,3881 @@ + + + + + + + + + + + + + + + + + + Viewing Token Transfers - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Viewing Token Transfers#

    +
    +

    This page is for advanced users.

    +
    +

    Use the block explorer to view token transfers to and from an address.

    +
      +
    1. Retrieve the address whose token transfers you want to view.
    2. +
    3. Open the block explorer for the appropriate network. + The block explorer dashboard is displayed.
    4. +
    5. Insert the address from Step 1 into the Search field. + If the address exists, it is highlighted in the results list.
    6. +
    7. Click the highlighted address. The Address Details page is displayed.
    8. +
    9. +

      Click the Token Transfers tab, as shown in the following image:

      +

      +Token Transfers +
      Token Transfers.
      +

      +

      The Token Transfers list is displayed.

      +
    10. +
    11. +

      Click the transaction hash for the token transfer you want to view. + The following details about the transfer are displayed:

      +
        +
      • Transaction Hash: A unique identifier that proves a transaction is verified and added to the blockchain.
      • +
      • Result: The state of the transaction. +The state is either Success, Pending, or Failed.
      • +
      • Status: The status of the transaction. +The status is either Confirmed or Unconfirmed.
      • +
      • Block: The number of the block that contains the transaction.
      • +
      • Timestamp: The date and time when the transaction was added to the blockchain and the amount of time required to confirm it.
      • +
      • From: The address of the transaction sender.
      • +
      • Interacted With (To): The address of the contract that handles the transaction.
      • +
      • Tokens Transferred
          +
        • From: The address that initiated the transaction with the contract.
        • +
        • To: The address of the recipient of the token in the transaction.
        • +
        • For: The symbol of the token and its quantity in the transaction.
        • +
        +
      • +
      • Value: The quantity of tokens sent.
      • +
      • Transaction Fee: The total cost of the transaction.
      • +
      • Gas Price: The price per unit of gas specified by the sender. +Units are measured in gwei.
      • +
      • Transaction Type:
      • +
      • Gas Limit: The maximum amount of gas approved for the transaction.
      • +
      • Max Fee Per Gas: The maximum total amount per unit of gas the sender would pay, including the base fee and priority fee.
      • +
      • Max Priority Fee per Gas: The maximum fee per unit of gas specified by the sender to pay a validator to prioritize the transaction. +This fee is also called a tip.
      • +
      • Priority Fee/Tip: The priority fee specified by the sender to pay a validator to prioritize the transaction.
      • +
      • Transaction Burnt Fee: The amount of $FLR burned for the transaction.
      • +
      • Gas Used by Transaction: The actual amount of gas used by the transaction.
      • +
      • Nonce Position: The transaction number from the sender's address. +Each transaction made by an address increases the nonce by one.
      • +
      • Raw Input: The hashed input of a transaction. +This input accompanies the transaction to process it.
      • +
      • Input: The relevant functions that were called and parameters used in the transaction.
      • +
      +
    12. +
    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/block-explorers/viewing-transactions/index.html b/user/block-explorers/viewing-transactions/index.html new file mode 100644 index 000000000..6a65a1dc2 --- /dev/null +++ b/user/block-explorers/viewing-transactions/index.html @@ -0,0 +1,4046 @@ + + + + + + + + + + + + + + + + + + Viewing Transactions - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Viewing Transactions#

    +
    +

    This page is for advanced users.

    +
    +

    Use the block explorer to view transaction details that explain where the transactions exist on the blockchain, when they were processed, how much gas they consumed, and more.

    +
      +
    1. Retrieve the address whose transactions you want to view.
    2. +
    3. Open the block explorer for the appropriate network. + The block explorer dashboard is displayed.
    4. +
    5. Insert the address from Step 1 into the Search field. + If the address exists, it is highlighted in the results list.
    6. +
    7. +

      Click the highlighted address. + The Address Details page is displayed, as shown in the following image. The preselected Transactions tab lists the transactions associated with the address.

      +

      +Transactions +
      Transactions.
      +

      +
    8. +
    9. +

      Click the transaction hash, as shown in the following image, which highlights in sequence a standard transaction and a contract transaction. + The listed transactions were made by the address you specified. Details about a transaction are displayed when you click a transaction hash.

      +

      +Transaction Hash +
      Transaction Hash.
      +

      +

      The Transaction Details page is displayed, as shown in the following image:

      +

      +Transaction Details +
      Transaction Details.
      +

      +
    10. +
    +

    Transaction Details#

    +

    The following transaction information is provided:

    +
      +
    • Transaction Hash: A unique identifier that proves a transaction is verified and added to the blockchain.
    • +
    • Result: The state of the transaction. + The state is either Success, Pending, or Failed.
    • +
    • Status: The status of the transaction. + The status is either Confirmed or Unconfirmed.
    • +
    • Block: The number of the block that contains the transaction.
    • +
    • Timestamp: The date and time when the transaction was added to the blockchain and the amount of time required to confirm it.
    • +
    • From: The address of the transaction sender.
    • +
    • To: The address of the transaction recipient.
    • +
    • Value: The quantity of tokens sent.
    • +
    • Transaction Fee: The total cost of the transaction.
    • +
    • Gas Price: The price per unit of gas specified by the sender. + Units are measured in gwei.
    • +
    • Transaction Type:
    • +
    • Gas Limit: The maximum amount of gas approved for the transaction.
    • +
    • Max Fee Per Gas: The maximum total amount per unit of gas the sender would pay, including the base fee and priority fee.
    • +
    • Max Priority Fee per Gas: The maximum fee per unit of gas specified by the sender to pay a validator to prioritize the transaction. + This fee is also called a tip.
    • +
    • Priority Fee/Tip: The priority fee specified by the sender to pay a validator to prioritize the transaction.
    • +
    • Transaction Burnt Fee: The amount of $FLR burned for the transaction.
    • +
    • Gas Used by Transaction: The actual amount of gas used by the transaction.
    • +
    • Nonce Position: The transaction number from the sender's address. + Each transaction made by an address increases the nonce by one.
    • +
    +

    The following elements are specific to contract transactions:

    +
      +
    • Interacted With (To): The address of the contract that handles the transaction.
    • +
    • Tokens Minted
        +
      • From: The address that initiated the transaction with the contract.
      • +
      • To: The address of the recipient of the token in the transaction.
      • +
      • For: The symbol of the token and its quantity in the transaction.
      • +
      +
    • +
    • Raw Input: The hashed input of a transaction. This input accompanies the transaction to process it.
    • +
    +

    Input#

    +

    The Input section shows the methods that were called and the parameters used in the transaction.

    +

    Internal Transactions#

    +

    Internal transactions occur between multiple smart contracts. +In some cases, tokens are transferred to a smart contract during an internal transaction.

    +
      +
    1. +

      Locate the Internal Transactions tab, as shown in the following image:

      +

      +Internal Transactions +
      Internal Transactions.
      +

      +
    2. +
    3. +

      Click the transaction hash, as shown in the following image:

      +

      +Transaction Hash +
      Transaction Hash.
      +

      +

      The transaction details are displayed.

      +
    4. +
    +

    Logs#

    +

    Transaction logs show events that were trigged by smart contracts during a transaction and information related to those events.

    +

    Click the Logs tab, as shown in the following image:

    +
    +

    Logs

    +
    Logs.
    +
    +

    The logs are displayed.

    +

    Raw Trace#

    +

    The raw trace shows all parameters and data related to a transaction. +If errors occurred during the transaction, this information can be used to debug them.

    +

    Click the Raw Trace tab, as shown in the following image:

    +
    +

    Raw Trace

    +
    Raw Trace.
    +
    +

    The raw trace is displayed in JSON format.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/claiming-the-flaredrop/index.html b/user/claiming-the-flaredrop/index.html new file mode 100644 index 000000000..aed278f22 --- /dev/null +++ b/user/claiming-the-flaredrop/index.html @@ -0,0 +1,3934 @@ + + + + + + + + + + + + + + + + + + Claiming the FlareDrop - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Claiming the FlareDrop#

    +

    Claiming the FlareDrop is available every 30 days and is based on the average balance from the last 23 days of each 30-day month. +Therefore, it is advised that each address claim its funds during the first 7 days of each 30-day round.

    +

    See The FlareDrop concept page for further explanation.

    +
    +

    FlareDrop Distribution Dates

    +
    FlareDrop distribution dates.
    +
    +

    There are several ways to claim. +You can claim:

    + +
    +

    Two steps to ensure receiving all your $FLR !

    +

    You must:

    +
      +
    1. Wrap $FLR to receive it. +Rewards are proportional to the $WFLR balance, not $FLR, so always wrap as much $FLR as you can! +Wrapping has no downside: Wrapped tokens continue to be available for delegation and governance voting, for example, and they can be unwrapped at any time. +See Wrapping Flare Tokens.
    2. +
    3. Claim before the distribution expires. +After the distribution becomes claimable, it expires in two bank months and a week (67 days).
    4. +
    +
    +

    Claiming from the Flare Portal#

    +

    Claim manually from the Flare Portal. +From there, you can see how many $FLR tokens you have to claim and you can claim them.

    +
      +
    1. Go to the Flare Portal.
    2. +
    3. Click Connect to Wallet and log into your wallet.
    4. +
    5. Your Main Account is open by default. + If you enabled a PDA and want to claim for it instead, click Delegation Account.
    6. +
    7. Under Claim your FlareDrop distribution, any $FLR you have to claim displays on the button. +
      + Claim Your FlareDrop Distribution +
      Claim Your FlareDrop Distribution.
      +
    8. +
    9. Click the Claim button to claim your $FLR. + A confirmation dialog opens. +
      + FlareDrop claiming confirmation +
      FlareDrop claiming confirmation.
      +
      + As a convenience, you have the choice to wrap your tokens after claiming them. + In this way they are ready for the next FlareDrop or to be delegated to the FTSO system, for example.
    10. +
    11. Click on the Claim All Distribution button and confirm the transaction on your wallet.
    12. +
    +

    Nominating Executors#

    +

    Alternatively, you can assign an executor to claim the FlareDrop for you. +This is useful for cold wallets but also for any users wishing to reduce their operational burden. +See Automatic Claiming to learn how.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/delegation/delegation-faq/index.html b/user/delegation/delegation-faq/index.html new file mode 100644 index 000000000..6a1a60a9e --- /dev/null +++ b/user/delegation/delegation-faq/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/user/delegation/delegation-in-detail/index.html b/user/delegation/delegation-in-detail/index.html new file mode 100644 index 000000000..6a1a60a9e --- /dev/null +++ b/user/delegation/delegation-in-detail/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/user/delegation/delegation-overview/index.html b/user/delegation/delegation-overview/index.html new file mode 100644 index 000000000..6a1a60a9e --- /dev/null +++ b/user/delegation/delegation-overview/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/user/delegation/index.html b/user/delegation/index.html new file mode 100644 index 000000000..af373b004 --- /dev/null +++ b/user/delegation/index.html @@ -0,0 +1,3818 @@ + + + + + + + + + + + + + + + + + + FTSO Delegation - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    + + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/delegation/managing-delegations/index.html b/user/delegation/managing-delegations/index.html new file mode 100644 index 000000000..28f08ad2a --- /dev/null +++ b/user/delegation/managing-delegations/index.html @@ -0,0 +1,3960 @@ + + + + + + + + + + + + + + + + + + Managing Delegations - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Managing Delegations Using the Flare Portal#

    +

    When you make delegations to data providers, you increase their vote power, reinforce the stability of the FTSO ecosystem, and earn monetary rewards.

    +

    This information explains how to manage your delegations using the Flare Portal. Alternatively, if you have used block explorers for other networks and are competent interacting with smart contracts without a user interface, you can use the block explorer, which provides more options but can be more complex. Using it is intended for advanced users.

    +

    Prerequisites#

    +

    Before you delegate your vote power, you must:

    + +

    Delegating Your Vote Power#

    +
      +
    1. +

      Open the Flare Portal. The home page is displayed.

      +

      +Flare Portal Home +
      Flare Portal home.
      +

      +
    2. +
    3. +

      Click Connect to Wallet and log into your wallet. The interface to your Main Account opens.

      +
    4. +
    5. +

      Ensure you are connected to the network you want. In the following image, the wallet is connected to the Flare network.

      +

      +Flare Portal Main Account +
      Main Account on the Flare network.
      +

      +
    6. +
    7. +

      On the Main Account tab, locate the FTSO provider delegations field, and click Delegate. The Delegate FTSO providers window is displayed.

      +
    8. +
    9. +

      Click the Main provider dropdown menu, click the data provider you want, and drag the slider to select the percentage of your vote power you want to delegate to the data provider.

      +

      + FTSO data providers +
      Delegate FTSO providers window.
      +

      +
    10. +
    11. +

      Optional: If you want to delegate to a second data provider, locate the Second (optional) provider field, and repeat step 3.

      +
    12. +
    13. Click Submit.
    14. +
    15. Follow the steps to confirm the transaction in your wallet.
    16. +
    +

    Removing Delegations#

    +
      +
    1. Open the Flare Portal, connect your wallet, and ensure you are connected to the network you want.
    2. +
    3. On the Main Account tab, locate the FTSO provider delegations field, and click Delegate. The Delegate FTSO providers window is displayed.
    4. +
    5. Drag the slider to 0% for one or both of the data providers, and click Submit.
    6. +
    7. Follow the steps to confirm the transaction in your wallet.
    8. +
    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/delegation/managing-rewards/index.html b/user/delegation/managing-rewards/index.html new file mode 100644 index 000000000..99b1aeda5 --- /dev/null +++ b/user/delegation/managing-rewards/index.html @@ -0,0 +1,3878 @@ + + + + + + + + + + + + + + + + + + Managing Rewards - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Managing Rewards Using the Flare Portal#

    +

    Rewards are accrued from your delegations to FTSO data providers whose submitted data is close to the calculated median value in a price epoch.

    +

    Use this information to claim FTSO delegation rewards by using the Flare Portal. Alternatively, if you have used block explorers for other networks and are competent interacting with smart contracts without a user interface, you can use the block explorer, which provides more options but can be more complex. Using it is intended for advanced users.

    +
      +
    1. +

      Open the Flare Portal. The home page is displayed.

      +

      +Flare Portal Home +
      Flare Portal home.
      +

      +
    2. +
    3. +

      Click Connect to Wallet and log into your wallet. The interface to your Main Account opens.

      +
    4. +
    5. +

      Ensure you are connected to the network you want. In the following image, the wallet is connected to the Flare network.

      +

      +Flare Portal Main Account +
      Main Account on the Flare network.
      +

      +
    6. +
    7. +

      On the Main Account tab, locate the Claim your delegation rewards section to determine whether you have claimable rewards and whether those rewards can currently be claimed:

      +
        +
      • If you have rewards to claim and the reward manager contains enough tokens, the Claim button is enabled and shows the amount of rewards you can claim. Go to Step 5.
      • +
      • +

        If you have rewards to claim, but the reward manager currently does not contain enough tokens, the Claim button shows the amount of rewards you can claim but is disabled.

        +

        For security reasons, a limited amount of tokens is stored at a given time in the reward manager contract. +Sometimes, all delegators claim their rewards in a short period of time immediately after the reward epoch ends, and the token storage is depleted. +The storage is replenished periodically. +If you are currently unable to claim your rewards because the storage is empty, try again the next day.

        +
      • +
      • +

        If you don't have claimable rewards, the Claim button shows 0 and is disabled.

        +
      • +
      +

      The following image shows an account with claimable rewards:

      +

      +Account with claimable rewards +
      An account with claimable rewards.
      +

      +
    8. +
    9. +

      Click the Claim button. The Claim your delegation rewards window is displayed.

      +

      +Claim your delegation rewards +
      Claim your delegation rewards.
      +

      +
    10. +
    11. +

      Optional: If you have enabled your personal delegation account, the option to send your rewards to the PDA is preselected by default. + To send your rewards to the address that you connected to the Portal instead, deselect the option.

      +
    12. +
    13. Click Claim All Rewards to claim all available rewards for the listed epochs.
    14. +
    15. Follow the steps to confirm the transaction in your wallet. Your rewards are claimed, and your updated balance of native tokens is displayed.
    16. +
    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/delegation/manual-delegation/index.html b/user/delegation/manual-delegation/index.html new file mode 100644 index 000000000..a5500764a --- /dev/null +++ b/user/delegation/manual-delegation/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/user/delegation/manual-reward-claiming/index.html b/user/delegation/manual-reward-claiming/index.html new file mode 100644 index 000000000..87b9f6b43 --- /dev/null +++ b/user/delegation/manual-reward-claiming/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/user/delegation/reward-claiming-faq/index.html b/user/delegation/reward-claiming-faq/index.html new file mode 100644 index 000000000..6a1a60a9e --- /dev/null +++ b/user/delegation/reward-claiming-faq/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/user/delegation/reward-claiming-in-detail/index.html b/user/delegation/reward-claiming-in-detail/index.html new file mode 100644 index 000000000..6a1a60a9e --- /dev/null +++ b/user/delegation/reward-claiming-in-detail/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/user/delegation/reward-claiming/index.html b/user/delegation/reward-claiming/index.html new file mode 100644 index 000000000..6a1a60a9e --- /dev/null +++ b/user/delegation/reward-claiming/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/user/governance/index.html b/user/governance/index.html new file mode 100644 index 000000000..41b6851ea --- /dev/null +++ b/user/governance/index.html @@ -0,0 +1,3817 @@ + + + + + + + + + + + + + + + + + + Governance - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Governance#

    +

    This section contains information about participating in governance on the Flare and Songbird networks.

    + + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/governance/voting/index.html b/user/governance/voting/index.html new file mode 100644 index 000000000..2cc5666e3 --- /dev/null +++ b/user/governance/voting/index.html @@ -0,0 +1,4169 @@ + + + + + + + + + + + + + + + + + + Voting - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    + +
    + + +
    +
    + + + + + + + + + + +

    Voting#

    +

    An integral part of the governance process, voting is the way you influence decisions about how Flare and Songbird operate.

    +

    This process can be performed directly through Flare's smart contracts, but the Flare Foundation has developed the Flare Portal to enable you to conveniently cast your vote.

    +

    The following information is about voting on the Flare and Songbird networks. +Ensure you have selected one of these networks in your wallet.

    +

    Governance Process Summary#

    +

    This section summarizes the voting process, which is explained in more detail in the Governance page.

    +

    All changes to the Flare and Songbird networks are determined by the outcomes of votes on Flare Improvement Proposals and Songbird Testing Proposals.

    +

    For now, all proposals are published by the Flare Foundation.

    +

    On each network, each account can cast a number of votes equal to the amount of wrapped tokens it holds. +Since this amount varies over time, a snapshot of all accounts is taken at a block randomly chosen before voting starts. +This block is called the vote count block.

    +

    Before snapshots are taken, a notice period occurs. +If you need to wrap tokens before a voting, wrap them during this notice period so that they are always included in the snapshot.

    +
    +

    Tip

    +

    It is worth noting that you can use the same wrapped tokens to simultaneously vote on proposals and delegate to FTSO data providers.

    +
    +

    Requirements#

    +

    To vote on any proposal, you need an account that contains wrapped tokens. +You can wrap your tokens by using the Flare Portal, as shown in the Getting Wrapped Tokens section below.

    +
    +

    Warning

    +

    Only wrapped tokens held at the vote count block are considered towards your vote count. +Tokens wrapped or received afterwards will not result in additional votes.

    +

    If you need to wrap tokens, always do so during the notice period.

    +
    +

    Guide#

    +

    1. Connecting to the Portal#

    +

    Copy the Flare Portal URL, since you will need it later:

    +
    https://portal.flare.network
    +
    +

    The first step to use the portal is to connect your wallet to it, and the procedure is different for each wallet:

    +

    Bifrost Wallet#

    +
      +
    1. Open Bifrost Wallet, log in, and click the web browser tab indicated by the four gray squares at the bottom of the screen.
    2. +
    3. Paste the Flare Portal URL in the search field at the top of the window, and click Search.
    4. +
    5. Click Connect to Wallet.
    6. +
    7. Select Bifrost Wallet.
    8. +
    9. Ensure either the Flare or Songbird network is selected in the pop-up window, and click Connect.
    10. +
    +

    Your wallet is now connected to the portal.

    +

    MetaMask Mobile#

    +
      +
    1. Open MetaMask, and log in.
    2. +
    3. Click the three-lines menu, and click Browser.
    4. +
    5. Paste the Flare Portal URL in the search field at the top of the window, and click Go.
    6. +
    7. Click Connect to Wallet, and click MetaMask.
    8. +
    +

    Your wallet is now connected to the portal.

    +

    Ledger Nano S/X and Chrome#

    +
      +
    1. Connect to your Ledger device, and unlock it.
    2. +
    3. Log into the MetaMask Chrome extension, and sync your Ledger device.
    4. +
    5. Paste the Flare Portal URL in the search field at the top of the Chrome window, and click Enter.
    6. +
    7. Click Connect to Wallet.
    8. +
    9. Click MetaMask.
    10. +
    +

    Your wallet is now connected to the portal.

    +

    MetaMask or Brave Wallet#

    +
      +
    1. Copy and paste the Flare Portal URL in the search bar at the top of your browser and press Enter.
    2. +
    3. Click Connect to Wallet.
    4. +
    5. Select MetaMask.
    6. +
    7. Ensure the correct account address is selected and press Confirm.
    8. +
    +

    Your wallet is now connected to the portal.

    +

    2. Getting Wrapped Tokens#

    +

    Wrapped tokens are required to vote.

    +

    To wrap your tokens:

    +
      +
    1. On the Account tab in the Flare Portal, ensure you are connected to the network on which the proposal will be voted.
    2. +
    3. Locate your token balance, and click Wrap.
    4. +
    5. +

      Specify the amount you want to wrap, and click Wrap.

      +
      +

      Never wrap all your tokens

      +

      Always leave some unwrapped tokens to pay for transaction fees.

      +
      +
    6. +
    7. +

      Confirm the transaction in your wallet.

      +
    8. +
    +

    Remember to wrap your tokens before voting starts, as explained in the Governance Process Summary section above.

    +

    3. Casting Your Vote#

    +
    +

    Important

    +

    Wrapped tokens are required to vote. +Depending on the network, ensure you have either $FLR or $SGB in the wallet you will use to vote. +For more information, see Getting Wrapped Tokens.

    +
    +
      +
    1. In the Flare Portal, select the Voting tab. + The Governance Proposals page is displayed.
    2. +
    3. Locate your current number of votes in the black box. + If you have fewer votes than you expected, consider the warning in the Requirements section above.
    4. +
    5. In the List of proposals, locate the proposal you want to vote on, and click on it. + The selected proposal is displayed.
    6. +
    7. Review the information in the Proposal info and Voting details sections.
    8. +
    9. +

      Cast your vote. + All your available votes will be assigned to the option you specify:

      +
        +
      • To vote in favor of the proposal, click Vote For.
      • +
      • To vote for the proposal to be rejected, click Vote Against.
      • +
      +
    10. +
    11. +

      After you sign the transaction, your vote is final and cannot be changed. + To sign the transaction and lock your vote, click Confirm.

      +
    12. +
    +

    Your contribution to this proposal is now complete.

    +

    Transferring Votes#

    +

    Votes can be transferred to another account while the wrapped tokens remain in your possession. +This is useful, for example, if you have wrapped tokens in multiple self-custody wallets, since you can simplify your voting process by transferring all the votes to a single wallet.

    +

    You can read all the details about transferring votes in the Governance page.

    +

    By completing the following process, you are crediting another account with votes only; +the tokens themselves stay in the original wallet.

    +
      +
    1. Copy the Flare or Songbird address you want to transfer votes to.
    2. +
    3. On the Voting tab in the Flare Portal, locate your amount of current votes in the black box, and click Transfer votes. + The Information about transferred votes window is displayed.
    4. +
    5. Read the disclaimer, and click Transfer votes. + The Transfer votes window is displayed.
    6. +
    7. In the Transfer all my votes to field, paste the address from Step 1, and click Confirm.
    8. +
    9. Click Confirm on your wallet to sign the transaction. + Your votes are credited to the address you specified. + The tokens themselves stay in the original address.
    10. +
    +
    +

    Canceling vote transfers

    +

    You can stop transferring your votes to another address, if you do so before the snapshot is taken.

    +

    You can do so from the Transfer votes window using the Remove delegation button. +This button is only available when you have previously transferred votes.

    +
    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/index.html b/user/index.html new file mode 100644 index 000000000..a9136ae54 --- /dev/null +++ b/user/index.html @@ -0,0 +1,3850 @@ + + + + + + + + + + + + + + + + + + User Guides - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    + + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/personal-delegation-account/index.html b/user/personal-delegation-account/index.html new file mode 100644 index 000000000..23ffef11f --- /dev/null +++ b/user/personal-delegation-account/index.html @@ -0,0 +1,3951 @@ + + + + + + + + + + + + + + + + + + Personal Delegation Accounts - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Personal Delegation Accounts#

    +

    You can receive $WFLR rewards for making contributions to the Flare community, for example, by delegating your tokens to FTSO data providers.

    +

    A Personal Delegation Account (PDA) allows you to keep these rewards temporarily separate from your main account, so that you can track them, for example, as a personal record or for tax purposes. +In certain jurisdictions, delaying the realization of earnings for a specified time can lead to a reduced tax rate. +See the Concept page for more detail.

    +

    Particularly, the balance of a PDA can still be redelegated to earn compounded interest and the governance votes it grants can be transferred to another address.

    +

    If a PDA is enabled and you configured an executor, it automatically claims rewards for the main account and the PDA, and sends them to the PDA.

    +

    Enabling a PDA#

    +

    You can enable and disable your PDA at any time in the Flare Portal without any ill-effect, except the cost of the transaction fee.

    +
      +
    1. Open the Flare Portal.
    2. +
    3. Click Connect to Wallet and log into your wallet. + The interface to your Main Account opens. +
      + Main Account Opens +
      Main Account opens.
      +
    4. +
    5. To switch from the Main Account to your PDA, click Delegation Account.
    6. +
    7. Click Enable. +
      + Enable a PDA +
      Enable a PDA.
      +
    8. +
    9. A popup appears with a short description of what a PDA is. +
      + Confirm enabling the PDA +
      Confirm enabling the PDA.
      +
    10. +
    11. Click Enable. + Your wallet shows the details of the transaction.
    12. +
    13. Review the transaction and confirm it.
    14. +
    +

    Once the PDA is enabled, the Flare Portal displays the PDA address and the initial 0.0 $WFLR balance. +Your PDA is now ready to receive rewards!

    +
    +

    PDA Enabled

    +
    The PDA address is enabled.
    +
    +

    If a PDA is enabled and you configured an executor, it automatically claims rewards for the main account and the PDA, and sends them to the PDA.

    +

    Operations available in a PDA#

    +

    Other operations available are:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    OperationDescription
    DisableYou can Disable the PDA at any time. Disabling sends all $WFLR back to the main account to your $WFLR balance. Automatic claims from executors will go to the main account as well.
    WithdrawYou can withdraw from your PDA at any time. Click Withdraw, enter the amount of $WFLR to withdraw, and click Withdraw again. The amount is sent to your main account to your $WFLR balance.
    DelegateYou can delegate your rewards to FTSO data providers for compounded rewards.
    Transfer votesA PDA cannot vote on governance proposals directly, but it can transfer its votes to another address, including its main account. Click Transfer votes, click main account or enter an address to transfer to, and click Confirm.
    Claim FLRThe Claim FLR button shows how many rewards you have to claim. Use this button to claim rewards yourself, or configure an executor from the main account tab to do that for you.
    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/wallets/bifrost-wallet/index.html b/user/wallets/bifrost-wallet/index.html new file mode 100644 index 000000000..c4f7188f8 --- /dev/null +++ b/user/wallets/bifrost-wallet/index.html @@ -0,0 +1,3915 @@ + + + + + + + + + + + + + + + + + + Bifrost Wallet - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Bifrost Wallet#

    +

    Bifrost Wallet is a noncustodial mobile wallet available for both Android and iOS. +You can view your portfolio of crypto assets, access decentralized applications through the in-app browser and perform operations on various blockchain networks, including sending, receiving, wrapping and delegating Flare ($FLR) and Songbird ($SGB).

    +

    Getting Started#

    +

    Start by downloading Bifrost Wallet from the Apple App Store or Google Play Store and either create a new wallet or import an existing one from a recovery phrase.

    +

    The official guides in the Bifrost Wallet help center may be of assistance.

    +
    +

    Please make sure you have installed at least version 0.4.5

    +
    +
    +

    XRP Airdrop

    +

    Note that, once $FLR distribution begins, users who imported their Ethereum-style claim address into Bifrost to access the XRP airdrop will automatically see their tokens in the Flare asset row in the COINS section.

    +
    +

    Adding Flare Tokens#

    +

    When your balance of any native or wrapped token on the Flare network or Songbird network is more than 0, Bifrost Wallet automatically displays the balance. No additional action is required.

    +

    Wrap and Delegate#

    +

    When you delegate your vote power to FTSO data providers, you not only support the Flare ecosystem but also earn monetary rewards.

    +

    To wrap and delegate your $FLR or $SGB tokens using Bifrost Wallet, see Bifrost's guide for wrapping and delegating $FLR and guide for wrapping and delegating $SGB.

    +

    Alternatively, wrap and delegate your $FLR or $SGB tokens using the Flare Portal. First, wrap your tokens, and then delegate them.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/wallets/brave-wallet/index.html b/user/wallets/brave-wallet/index.html new file mode 100644 index 000000000..4dcd39e9d --- /dev/null +++ b/user/wallets/brave-wallet/index.html @@ -0,0 +1,4040 @@ + + + + + + + + + + + + + + + + + + + + Brave Wallet - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Brave Wallet#

    +

    Brave Browser now offers a noncustodial software wallet on both Windows and macOS for Ethereum Virtual Machine (EVM) integrated chains such as Flare and Songbird.

    +

    Getting Started#

    +

    To use Brave Wallet with Flare or Songbird, ensure you have:

    +
      +
    • Downloaded Brave Browser to your computer, version 1.42.88 or later.
    • +
    • Initialized a Brave wallet or restored an existing one.
    • +
    • Protected your Brave wallet with a password.
    • +
    • Backed up your crypto wallet with a 12-word recovery phrase.
    • +
    +

    Adding Flare Tokens#

    +

    After your wallet is set up, you need to connect to Flare's networks, which will add each network's native token to your listed assets.

    +
      +
    1. Open Brave browser on your computer.
    2. +
    3. Navigate to Settings, and select Web3 from the list of options.
    4. +
    5. In the box on the right, click Wallet Networks, and then click Add.
    6. +
    7. +

      Complete the following steps to set up the Flare network and Songbird network:

      +
      +
      +
      +
        +
      1. +

        In the Search network field, select 0xe(14) Flare Mainnet, and verify that the displayed values match the values in this table:

        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Network SettingValue
        The id of chain0xe
        The name of chainFlare Mainnet
        Chain's currency nameFlare
        Chain's currency symbolFLR
        Chain's currency decimals18
        RPC URLshttps://flare-api.flare.network/ext/C/rpc
        Icon URLs(leave blank)
        Block explorer URLshttps://flare-explorer.flare.network
        +
      2. +
      3. +

        Click Submit.

        +
      4. +
      +
      +
      +
        +
      1. +

        In the Search network field, select 0x13(19) Songbird Canary-Network, and verify that the displayed values match the values in the following table.

        +
        +

        Important

        +

        Make sure the RPC node URL is https://songbird-api.flare.network/ext/C/rpc.

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Network SettingValue
        The id of chain0x13
        The name of chainSongbird Canary-Network
        Chain's currency nameSongbird
        Chain's currency symbolSGB
        Chain's currency decimals18
        RPC URLshttps://songbird-api.flare.network/ext/C/rpc
        Icon URLs(leave blank)
        Block explorer URLshttps://songbird-explorer.flare.network
        +
      2. +
      3. +

        Click Submit.

        +
      4. +
      +
      +
      +
      +
    8. +
    9. +

      Click Wallet.

      +
    10. +
    11. Specify your password, and click Unlock.
    12. +
    13. On the left side of the screen beside Balance, click the drop-down menu and select Flare or Songbird. + Connection to the network is complete, and your balance of native tokens on the selected network is displayed.
    14. +
    +

    With the previous steps completed, you now have access to the Flare network and Songbird Network and each network's native token, but you must complete an extra step for the wallet to recognize wrapped tokens, which are needed in a lot of operations.

    +

    Wrap and Delegate#

    +

    When you delegate your vote power to FTSO data providers, you not only support the Flare ecosystem but also earn monetary rewards.

    +

    Wrap and delegate your $FLR or $SGB tokens using the Flare Portal. First, wrap your tokens, and then delegate them.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/wallets/dcent-wallet/index.html b/user/wallets/dcent-wallet/index.html new file mode 100644 index 000000000..de06faa1c --- /dev/null +++ b/user/wallets/dcent-wallet/index.html @@ -0,0 +1,3969 @@ + + + + + + + + + + + + + + + + + + D'CENT Wallet - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    D'CENT Wallet#

    +

    D'CENT Biometric Wallet is a noncustodial hardware wallet and is considered one of the most secure ways to manage your crypto assets.

    +

    Getting Started#

    +

    Purchase a D'CENT Biometric hardware wallet from the official D'CENT shop or download their software wallet/mobile app from the Apple App Store or Google Play Store. +Then either initialize a new wallet or import an existing one from a recovery phrase.

    +

    The official D'CENT device setup help guides can be found here: https://userguide.dcentwallet.com/biometric-wallet/setting-up.

    +

    Adding Flare Tokens#

    +

    After your device is set up and synced with the mobile app, complete the following procedure to add native tokens $FLR and $SGB to your listed assets. Although this procedure also explains how to add the wrapped tokens $WFLR and $WSGB to your listed assets, you can automatically add $WFLR and $WSGB using the Flare Portal.

    +
      +
    1. Ensure the D'CENT biometric wallet is updated with the latest firmware, v2.24.0 or later.
    2. +
    3. Login to your D'CENT mobile app and have your device turned on, unlocked, and paired via Bluetooth.
    4. +
    5. Click the + sign on the bottom right of the Account tab.
    6. +
    7. +

      In the Search box, search for one of the following tokens to add, and select the result:

      + + + + + + + + + + + + + + + + + + + + + + + + + +
      TokenResult
      FlareFlare (FLR)
      SongbirdSongbird Token (SGB)
      Wrapped FlareWrapped Flare (WFLR)
      Wrapped SongbirdWrapped Songbird (WSGB)
      +
    8. +
    9. +

      Name your new account, and click Create.

      +
    10. +
    11. Repeat steps 4 and 5 for each token you want to add to the list of assets in your wallet.
    12. +
    +

    Wrap and Delegate#

    +

    When you delegate your vote power to FTSO data providers, you not only support the Flare ecosystem but also earn monetary rewards.

    +

    You can wrap and delegate your $SGB using D'CENT's native FTSO Portal:

    +
    +

    Delegation instructions for the Flare network are awaiting confirmation.

    +
    +
      +
    1. Click the Discovery tab at the bottom middle of the screen.
    2. +
    3. Select the FTSO Portal from the menu then click Go.
    4. +
    5. Choose the Songbird account you wish to use and click Connect.
    6. +
    7. You will need to wrap your $SGB by clicking SGB ↔️ WSGB marked in green near the top middle of the screen.
    8. +
    9. Input the $SGB amount you want to wrap and click the green SGB ↔️ WSGB box.
    10. +
    11. Click Confirm and follow the prompts to sign the transaction with your hardware device.
    12. +
    13. You can now delegate your $WSGB by clicking Add delegation.
    14. +
    15. +

      Select a provider and input the percentage of your $WSGB holdings you want to delegate to their service and press Delegate.

      +
      +

      Note

      +

      Providers listed as a Partner have additional security features integrated with D'cent.

      +
      +
    16. +
    17. +

      Click Confirm and follow the prompts to sign the transaction with your hardware device.

      +
    18. +
    19. To add a second provider (up to two), repeat steps 7 through 9.
    20. +
    +

    Alternatively, wrap and delegate your $FLR or $SGB tokens using the Flare Portal. First, wrap your tokens, and then delegate them.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/wallets/enkrypt-wallet/index.html b/user/wallets/enkrypt-wallet/index.html new file mode 100644 index 000000000..041588991 --- /dev/null +++ b/user/wallets/enkrypt-wallet/index.html @@ -0,0 +1,4038 @@ + + + + + + + + + + + + + + + + + + Enkrypt Wallet - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Enkrypt Wallet#

    +

    Enkrypt is a multichain, open-source and noncustodial wallet that tracks no data. +It interacts with Polkadot, Ethereum, Bitcoin and more, all directly in the browser.

    +

    Getting Started#

    +
      +
    1. Install Enkrypt.
    2. +
    3. Create a new wallet or import an existing wallet to Enkrypt.
    4. +
    5. Securely back up your recovery phrase offline.
    6. +
    7. Protect your Enkrypt wallet with a password.
    8. +
    +

    Adding Flare Tokens#

    +

    After you set up your wallet, connect to Flare's networks, which will add each network's native token and wrapped token to your listed assets:

    +
      +
    1. +

      Add Flare or Songbird as a custom network using these parameters:

      +
      +
      +
      +
        +
      1. From the main menu, click Manage networks. The Manage networks window is displayed.
      2. +
      3. Click the sliders icon beside the Search networks field.
      4. +
      5. Click Custom network. + The Custom network window is displayed.
      6. +
      7. +

        Specify the following values:

        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Network SettingValue
        Network NameFlare
        New RPC URLhttps://flare-api.flare.network/ext/C/rpc
        Chain ID14
        Currency SymbolFLR
        Block Explorer URLhttps://flare-explorer.flare.network
        +
      8. +
      9. +

        Click Add network.

        +
      10. +
      11. Locate Flare Mainnet at the bottom of the list, and toggle the switch to enable your wallet to display your balance of $FLR.
      12. +
      13. +

        Follow these instructions for manually adding tokens to retrieve the WNat contract address, and copy it.

        +
        +

        Important

        +

        The WNat contract address is different on each network. Ensure you copy the WNat contract address on the Flare network.

        +
        +
      14. +
      15. +

        With Flare Mainnet selected on the main menu in your Enkrypt wallet, click Add custom token. + The Add a token window is displayed.

        +
      16. +
      17. In the Contract address field, paste the WNat contract address that you copied in step 6.
      18. +
      19. Click Add token. + The wrapped token $WFLR is added to your list of Flare assets.
      20. +
      +
      +
      +
        +
      1. From the main menu, click Manage networks. + The Manage networks window is displayed.
      2. +
      3. Click the sliders icon beside the Search networks field.
      4. +
      5. Click Custom network. The Custom network window is displayed.
      6. +
      7. +

        Specify the following values:

        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Network SettingValue
        Network NameSongbird
        New RPC URLhttps://songbird-api.flare.network/ext/C/rpc
        Chain ID19
        Currency SymbolSGB
        Block Explorer URLhttps://songbird-explorer.flare.network
        +
      8. +
      9. +

        Click Add network.

        +
      10. +
      11. Locate Songbird Canary-Network at the bottom of the list, and toggle the switch to enable your wallet to display your balance of $SGB.
      12. +
      13. +

        Follow these instructions for manually adding tokens to retrieve the WNat contract address, and copy it.

        +
        +

        Important

        +

        The WNat contract address is different on each network. Ensure you copy the WNat contract address on the Songbird network.

        +
        +
      14. +
      15. +

        With Songbird Canary-Network selected on the main menu in your Enkrypt wallet, click Add custom token. + The Add a token window is displayed.

        +
      16. +
      17. In the Contract address field, paste the WNat contract address that you copied in step 6.
      18. +
      19. Click Add token. + The wrapped token $WSGB is added to your list of Songbird assets.
      20. +
      +
      +
      +
      +
    2. +
    +

    Wrap and Delegate#

    +

    When you delegate your vote power to FTSO data providers, you not only support the Flare ecosystem but also earn monetary rewards.

    +

    Wrap and delegate your $FLR or $SGB tokens using the Flare Portal. First, wrap your tokens, and then delegate them.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/wallets/how-to-access-flare-network-with-a-ledger-device/index.html b/user/wallets/how-to-access-flare-network-with-a-ledger-device/index.html new file mode 100644 index 000000000..4d3d0dd8c --- /dev/null +++ b/user/wallets/how-to-access-flare-network-with-a-ledger-device/index.html @@ -0,0 +1,4026 @@ + + + + + + + + + + + + + + + + + + Ledger Nano X and Nano S - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Ledger Nano X and Nano S#

    +

    Hardware wallets are considered among the more secure options to manage crypto assets and store private keys. +Your crypto assets can remain safe, even if your computer or phone is compromised, as long as you keep your recovery phrase safe and review all transaction details before confirming transactions.

    +

    This guide explains how to configure your Ledger device to use it through the MetaMask wallet.

    +

    One-Time Setup#

    +

    You only need to perform the steps in this section once.

    +

    Installing MetaMask#

    +

    Follow the MetaMask guide to install and configure the MetaMask wallet. +Make sure MetaMask can show $FLR and $SGB tokens, and their wrapped $WFLR and $WSGB versions.

    +

    Installing Ledger#

    +

    Follow the Ledger instructions to:

    +
      +
    1. Install Ledger Live and open it.
    2. +
    3. Initialize your Ledger device with a recovery phrase.
    4. +
    5. Protect your Ledger device with a PIN code.
    6. +
    7. Install the latest Ledger device firmware.
    8. +
    +

    Installing the Ethereum App#

    +

    Flare is EVM-compatible, so it uses the Ethereum app on Ledger. +After meeting the requirements above, install the Ethereum app on the device with the following steps:

    +
      +
    1. Open the Manager in Ledger Live.
    2. +
    3. Connect and unlock your Ledger device.
    4. +
    5. Enable the manager on your Ledger device by pressing both buttons.
    6. +
    7. Find Ethereum (ETH) in the app catalog.
    8. +
    9. Click the Install button of the app.
    10. +
    +

    Your Ledger device displays Processing…. +The app installation is complete.

    +

    Creating Accounts#

    +

    After enabling access to Songbird and Flare in MetaMask, create one or more accounts.

    +

    In MetaMask:

    +
      +
    1. Select Flare or Songbird in the network dropdown.
    2. +
    3. Connect your Ledger device using USB.
    4. +
    5. Open the Ethereum app on your Ledger device.
    6. +
    7. If Ledger Live is still running on your computer, you must quit the app.
    8. +
    9. Locate MetaMask's Settings and then Advanced settings.
    10. +
    11. Ensure that the Preferred Ledger Connection Type is set to WebHID in the drop-down menu (it should be the case by default).
    12. +
    13. Click your account image and Connect Hardware Wallet. +A pop up box opens listing paired Human Interface Devices (HID).
    14. +
    15. Highlight your Ledger S or Ledger X and click Connect. +A random set of addresses opens that are available for your use.
    16. +
    17. To create one or more accounts (for example, for different tokens or different purposes), select any account number or multiple account numbers and click Unlock.
    18. +
    +

    You have created one or more Ledger accounts to which you can send $FLR or $SGB tokens.

    +

    Your $FLR and $SGB balance will be displayed on the MetaMask overview. +Once the accounts contain $WFLR or $WSGB their balances will be shown too if you followed the Wrapping Flare Tokens guide.

    +
    +

    Note

    +

    The Ledger Live desktop application, as of version 2.55, can show your $FLR and $SGB balances but NOT the wrapped $WFLR and $WSGB versions.

    +

    The tokens are still in the account, but Ledger Live does not show them.

    +
    +

    Using Ledger with MetaMask#

    +

    Now that you have the one-time setup complete, here are a few things you can do to get started using your new accounts.

    +
      +
    • +

      Receive tokens. +To receive tokens, copy your account address and share it with the sender.

      +
    • +
    • +

      Send tokens. +To send tokens, click Send and enter the recipient address. +Then enter the desired amount and click Next. +MetaMask will ask you to confirm the transaction from the Ledger device.

      +
    • +
    • +

      Confirm transactions. +To confirm or reject a transaction, follow the on-screen instructions on your Ledger device.

      +
    • +
    +
    +

    Warning

    +

    Always review all transaction details on your Ledger device before confirming any transaction!

    +
    +

    To learn how to use Ledger, including signing transactions, go to Ledger.com.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/wallets/how-to-access-flare-network-with-a-trezor-device/index.html b/user/wallets/how-to-access-flare-network-with-a-trezor-device/index.html new file mode 100644 index 000000000..2db295f8f --- /dev/null +++ b/user/wallets/how-to-access-flare-network-with-a-trezor-device/index.html @@ -0,0 +1,4014 @@ + + + + + + + + + + + + + + + + + + Trezor T - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Trezor T#

    +

    Hardware wallets are considered among the more secure options to manage crypto assets and store private keys. +Your crypto assets can remain safe, even if your computer or phone is compromised, as long as you keep your recovery phrase safe and review all transaction details before confirming transactions.

    +

    Getting Started#

    +

    To use your Trezor device with Flare ($FLR) or Songbird ($SGB), first make sure that you have:

    +
      +
    1. Initialized your Trezor device with a recovery phrase.
    2. +
    3. Protected your Trezor device with a PIN code.
    4. +
    5. Trezor Suite is installed, open and ready to use.
    6. +
    7. Enabled Ethereum under the Crypto tab in Trezor Suite.
    8. +
    9. Installed the latest Trezor device firmware.
    10. +
    11. Installed the latest version of Google Chrome.
    12. +
    13. Installed the MetaMask browser extension.
    14. +
    +

    Use Trezor T Device with MetaMask#

    +

    You can access Flare and Songbird by using your Trezor T with the MetaMask browser extension.

    +
      +
    1. Open the MetaMask browser extension in your browser.
    2. +
    3. +

      Click Custom RPC in the network dropdown.

      +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      FieldValue
      Network NameSongbird
      New RPC URLhttps://songbird-api.flare.network/ext/C/rpc
      Chain ID19
      Currency SymbolSGB
      Block Explorer URLhttps://songbird-explorer.flare.network
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      FieldValue
      Network NameFlare
      New RPC URLhttps://flare-api.flare.network/ext/C/rpc
      Chain ID14
      Currency SymbolFLR
      Block Explorer URLhttps://flare-explorer.flare.network
      +
      +
      +
      +
    4. +
    5. +

      Click Save.

      +
    6. +
    7. Select Flare or Songbird in the network dropdown.
    8. +
    9. Connect and unlock your Trezor device.
    10. +
    11. Click your account image and Connect Hardware Wallet.
    12. +
    13. Select Trezor and click Continue.
    14. +
    15. Follow the on screen instructions to export your public key.
    16. +
    17. Select your Account and click Unlock.
    18. +
    +
    +

    Info

    +

    Please note that the provided Flare RPC node is only for individuals and not for commercial use.

    +

    Companies and developers may contact Flare Networks to arrange dedicated access.

    +
    +

    You will see your $FLR or $SGB balance on the overview. +To receive tokens, copy your account address and share it with the sender. +To send tokens, click Send and enter the recipient address, enter the desired amount and click Next. +Follow the on screen instructions to confirm or reject the transaction on your Trezor device.

    +
    +

    Warning

    +

    Always review all transaction details on your Trezor device before confirming any transaction!

    +
    +

    Wrap and Delegate#

    +

    Once connected to a Flare network, enter the address of the website or dapp you wish to use to wrap and delegate in the MetaMask browser. +A few FTSO data providers have developed dApps integrated with their websites that allow users to wrap, delegate and claim SGB and Flare rewards. +Delegating using this method is not exclusive to one specific provider, as these dapps allow you to choose from a number of different providers.

    +

    Other providers have their own websites and are developing similar dapps. +See the full list of active data providers on flaremetrics.io.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/wallets/how-to-access-flare-network-with-metamask/index.html b/user/wallets/how-to-access-flare-network-with-metamask/index.html new file mode 100644 index 000000000..b9ad3107d --- /dev/null +++ b/user/wallets/how-to-access-flare-network-with-metamask/index.html @@ -0,0 +1,4015 @@ + + + + + + + + + + + + + + + + + + + + MetaMask - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    MetaMask#

    +

    The MetaMask browser extension is a convenient way to access and interact with blockchains like Songbird or Flare. +To do so, you need to first add a custom network to MetaMask, as explained in this guide. +Make sure that you have securely backed up your recovery phrase before proceeding.

    +

    Getting Started#

    +

    To use MetaMask with Songbird or Flare, ensure you have:

    +
      +
    1. Installed the latest version of Google Chrome.
    2. +
    3. Installed the MetaMask browser extension.
    4. +
    5. Created a new wallet or imported an existing wallet to MetaMask.
    6. +
    7. Securely backed up your recovery phrase offline.
    8. +
    9. Protected your MetaMask with a password.
    10. +
    +

    Adding Flare Tokens#

    +

    After you set up your wallet, add the native tokens $FLR and $SGB and the wrapped tokens $WFLR and $WSGB to your listed assets:

    +
      +
    1. Open the MetaMask browser extension.
    2. +
    3. Unlock your MetaMask wallet with your password.
    4. +
    5. Click the networks drop-down menu, and click Add network. In a browser tab, the Settings menu opens to the Networks section.
    6. +
    7. Scroll to the bottom of the page, and click Add a network manually.
    8. +
    9. +

      Complete the following steps to set up the Flare network and Songbird network:

      +
      +
      +
      +
        +
      1. +

        Specify the values from the following table to set up the Flare network, which will add the native $FLR token to your list of assets.

        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        FieldValue
        Network NameFlare
        New RPC URLhttps://flare-api.flare.network/ext/C/rpc
        Chain ID14
        Currency SymbolFLR
        Block Explorer URLhttps://flare-explorer.flare.network
        +
      2. +
      3. +

        Click Save.

        +
      4. +
      5. Follow these instructions to automatically add $WFLR to your listed assets.
      6. +
      +
      +
      +
        +
      1. +

        Specify the values from the following table to set up the Songbird network, which will add the native $SGB token to your list of assets.

        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        FieldValue
        Network NameSongbird
        New RPC URLhttps://songbird-api.flare.network/ext/C/rpc
        Chain ID19
        Currency SymbolSGB
        Block Explorer URLhttps://songbird-explorer.flare.network
        +
      2. +
      3. +

        Click Save.

        +
      4. +
      5. Follow these instructions to automatically add $WSGB to your listed assets.
      6. +
      +
      +
      +
      +
    10. +
    +
    +

    Warning

    +

    Always review all transaction details in MetaMask before confirming any transaction!

    +
    +

    Wrap and Delegate#

    +

    When you delegate your vote power to FTSO data providers, you not only support the Flare ecosystem but also earn monetary rewards.

    +

    Wrap and delegate your $FLR or $SGB tokens using the Flare Portal. First, wrap your tokens, and then delegate them.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/wallets/index.html b/user/wallets/index.html new file mode 100644 index 000000000..8e1e71a2c --- /dev/null +++ b/user/wallets/index.html @@ -0,0 +1,3885 @@ + + + + + + + + + + + + + + + + + + Wallets - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Wallets#

    +

    Choose your wallet:

    + +

    If your wallet is not in the list, you might be able to configure it to connect to the Flare and Songbird networks by specifying the following configuration parameters in your wallet's settings:

    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    Configuration ParameterValue
    Chain ID14
    Asset TickerFLR
    RPC endpointhttps://flare-api.flare.network/ext/C/rpc
    Block Explorerhttps://flare-explorer.flare.network
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    Configuration ParameterValue
    Chain ID19
    Asset TickerSGB
    RPC endpointhttps://songbird-api.flare.network/ext/C/rpc
    Block Explorerhttps://songbird-explorer.flare.network
    +
    +
    +
    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/wallets/safepal-s1-wallet/index.html b/user/wallets/safepal-s1-wallet/index.html new file mode 100644 index 000000000..9d4b79daa --- /dev/null +++ b/user/wallets/safepal-s1-wallet/index.html @@ -0,0 +1,3972 @@ + + + + + + + + + + + + + + + + + + SafePal S1 Wallet - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    SafePal S1 Wallet#

    +

    SafePal S1 is a noncustodial hardware wallet that is considered one of the most secure ways to manage your crypto assets.

    +

    Getting Started#

    +

    Use of a SafePal S1 hardware wallet requires syncing the device with the mobile app. +A step by step unboxing guide to initialize a new device/wallet, or import an existing one from a recovery phrase, can be found here: https://safepalsupport.zendesk.com/hc/en-us/articles/360046051752-How-to-Set-Up-a-S1-Hardware-Wallet.

    +

    Adding Flare Tokens#

    +

    After you set up your wallet, add the native tokens $FLR and $SGB and the wrapped token $WFLR to your listed assets.

    +
    +

    Important

    +

    SafePal currently does not support the addition of wrapped Songbird ($WSGB) to wallets.

    +
    +
      +
    1. Ensure the SafePal S1 is updated with the latest firmware, version V1.0.32 or later.
    2. +
    3. Login to your SafePal mobile app and have your S1 device turned on and unlocked.
    4. +
    5. Scroll to the bottom of your listed assets in the mobile app, and click Manage Coins.
    6. +
    7. Click the Enter token or token contract address field. + The Search window is displayed.
    8. +
    9. +

      Complete the following steps to add Flare and Songbird tokens to your wallet:

      +
      +
      +
      +
        +
      1. Scroll through the list of networks, and select Flare.
      2. +
      3. In the Enter token or token contract address field, search for Flare.
      4. +
      5. Click the plus sign (+) displayed beside FLR (Flare). + FLR (Flare) added to your list of assets, and the homepage is displayed.
      6. +
      7. Scroll to the bottom of your listed assets in the mobile app, and click Manage Coins.
      8. +
      9. Select Flare from the list of networks again, and search for Wrapped Flare.
      10. +
      11. Click the plus sign (+) displayed beside WFLR (Flare). + WFLR (Flare) is added to your list of assets on the homepage.
      12. +
      +
      +
      +
        +
      1. +

        In the Enter token or token contract address field, search for Songbird. + A list of Songbird tokens on various blockchains is displayed.

        +
        +

        Important

        +

        Ignore all Songbird tokens categorized as BEP-20 and ERC-20.

        +
        +
      2. +
      3. +

        Click the plus sign (+) for this SGB (Songbird) token with the logo:

        +

        SGB Songbird token

        +

        SGB (Songbird) is added to your list of assets on the homepage.

        +
      4. +
      +
      +
      +
      +
    10. +
    +

    Wrap and Delegate#

    +

    When you delegate your vote power to FTSO data providers, you not only support the Flare ecosystem but also earn monetary rewards.

    +

    You can use the SafePal mobile app to wrap and delegate your tokens:

    +
      +
    1. Open the SafePal mobile app and navigate to the built-in web browser by clicking the four squares at the bottom middle of the screen.
    2. +
    3. +

      Enter the address of the website or dapp you wish to use to wrap and delegate in the search bar at the top of the screen.

      +
      +

      Info

      +

      These dapps are usually created by FTSO data providers, but some of them allow you to choose a different data provider to delegate to. + Take a look at flaremetrics.io and pick the one you prefer.

      +
      +
    4. +
    5. +

      After copying and pasting the address, click the drop-down menu to the right of the search tab.

      +
    6. +
    7. Scroll down, select the Flare or Songbird networks, and click Go.
    8. +
    9. A pop-up will appear notifying that you are being redirected to a third-party dapp. Press Confirm.
    10. +
    +

    Other data providers host similar websites or dapps for wrapping and delegation. +See the full list of signal providers on Songbird at https://flaremetrics.io/.

    +

    Alternatively, wrap and delegate your $FLR or $SGB tokens using the Flare Portal. First, wrap your tokens, and then delegate them.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/wrapping-tokens/index.html b/user/wrapping-tokens/index.html new file mode 100644 index 000000000..02dccaee7 --- /dev/null +++ b/user/wrapping-tokens/index.html @@ -0,0 +1,4060 @@ + + + + + + + + + + + + + + + + + + Wrapping Flare Tokens - Technical Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + + + +
    +
    +
    + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + + + + + + + + + + +

    Wrapping Flare Tokens#

    +

    This information explains how to wrap and unwrap native tokens on various Flare networks using the Flare Portal or the block explorer. +Wrapped tokens are required to delegate your vote power to FTSO data providers and to vote on decisions that affect how Flare networks operate.

    +

    When you complete the following steps for wrapping, your native tokens, such as $FLR and $SGB, are wrapped into $WFLR and $WSGB, respectively, so that you can participate in FTSO delegation and governance. +When you need to convert your wrapped tokens into native tokens again, unwrap the wrapped tokens using similar steps, as described below.

    +

    Using the Flare Portal#

    +
      +
    1. +

      Open the Flare Portal. + The home page is displayed.

      +

      +Flare Portal Home +
      Flare Portal home.
      +

      +
    2. +
    3. +

      Click Connect to Wallet and log into your wallet. + The interface to your Main Account opens.

      +
    4. +
    5. +

      Ensure you are connected to the network you want. + In the following image, the wallet is connected to the Flare network.

      +

      +Flare Portal Main Account +
      Main Account on the Flare network.
      +

      +
    6. +
    7. +

      Choose one of the following options:

      +
        +
      • +

        Wrap: Locate your balance of native tokens, and click Wrap.

        +
        +

        Never wrap all your tokens

        +

        Wrapping and unwrapping tokens are transactions with fees to be paid in native tokens. +Always leave some unwrapped tokens to pay for transaction fees.

        +
        +

        Specify the amount to wrap, and click Wrap again.

        +
      • +
      • +

        Unwrap: Locate your balance of wrapped tokens, and click Unwrap. + Specify the amount to unwrap, and click Unwrap again.

        +
      • +
      +
    8. +
    9. +

      Follow the steps to complete the transaction in your wallet.

      +
    10. +
    +

    Your wrapped token balance is updated and displayed in the Flare Portal and your wallet.

    +

    If your wrapped token balance is not displayed in your wallet, you must manually add the wrapped token so that your wallet recognizes it.

    +

    Using the Block Explorer#

    +
    +

    This section is for advanced users.

    +
    +
      +
    1. Open a block explorer.
    2. +
    3. From the block explorer, follow the Retrieval from Blockchain procedure to find and open the WNat contract.
    4. +
    5. Click Connect Wallet, and complete the steps to connect your wallet, ensuring you are on the network on which you will wrap tokens.
    6. +
    7. +

      Click the Write Contract tab, and use the following methods to wrap and unwrap tokens:

      +
        +
      • deposit: Wraps the amount of native tokens you specify in the field.
      • +
      • withdraw: Unwraps the amount of native tokens you specify in the field.
      • +
      +
    8. +
    +

    Your token balance is updated and displayed in your wallet. + If your wrapped token balance is not displayed in your wallet, you must manually add the wrapped token so that your wallet recognizes it.

    +

    Adding Wrapped Tokens to Wallets#

    +

    Your wrapped tokens are stored on the blockchain in a special ERC-20 smart contract called WNat, for Wrapped Native tokens. +Some wallets, like the Bifrost Wallet, are aware of this contract and are therefore preconfigured to display $WFLR and $WSGB balances. +Some other wallets, though, require you to configure them so that they can display wrapped-token balances.

    +

    If your wallet doesn't display your wrapped-token balance, you need to configure it, either automatically or manually as described in the following procedures.

    +

    Automatically#

    +

    This is typically the fastest procedure, but might not work with all wallets.

    +
      +
    1. +

      Open the Flare Portal. The home page is displayed.

      +

      +Flare Portal Home +
      Flare Portal home.
      +

      +
    2. +
    3. +

      Click Connect to Wallet and log into your wallet. The interface to your Main Account opens.

      +
    4. +
    5. +

      Ensure you are connected to the network you want. In the following image, the wallet is connected to the Flare network.

      +

      +Flare Portal Main Account +
      Main Account on the Flare network.
      +

      +
    6. +
    7. +

      On the Main Account tab, locate the Account heading and the Help icon, identified by a question mark.

      +

      +Flare Portal Account Help +
      Flare Portal Account Help.
      +

      +
    8. +
    9. +

      Click the Help icon and click How do I add Wrapped Flare token to my wallet?. + A Click here link for adding $WFLR to your wallet is displayed.

      +

      +Flare Portal Wrapping Help +
      Flare Portal Wrapping Help.
      +

      +
    10. +
    11. +

      Click Click here. + Your wallet opens. Wallets typically ask you to accept the token. The exact instructions depend on your wallet.

      +
    12. +
    13. +

      Follow the prompts in your wallet to add the wrapped token.

      +
    14. +
    +

    Your wrapped token balance is displayed in your wallet.

    +

    Manually#

    +
    +

    This section is for advanced users.

    +
    +

    If the automatic method did not work for you, most wallets can still be configured to recognize ERC-20 tokens through an Import tokens or Add custom asset menu, for example.

    +

    The exact instructions depend on your wallet, but they generally just require you to locate the aforementioned menu and provide the address of the WNat contract. +The wallet can usually then retrieve the token name, symbol, and number of decimals directly from the contract.

    +

    See the Contract Addresses page to find the address of the WNat contract.

    + +
    +
    + + + Last update: + 2023-10-04 + + +
    + + + + + + + + +
    + + + +
    +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file