|
| 1 | +// SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | +pragma solidity 0.8.27; |
| 3 | + |
| 4 | +import { IPaymentsCollector } from "./IPaymentsCollector.sol"; |
| 5 | +import { IGraphPayments } from "./IGraphPayments.sol"; |
| 6 | +import { IAuthorizable } from "./IAuthorizable.sol"; |
| 7 | + |
| 8 | +/** |
| 9 | + * @title Interface for the {RecurringCollector} contract |
| 10 | + * @dev Implements the {IPaymentCollector} interface as defined by the Graph |
| 11 | + * Horizon payments protocol. |
| 12 | + * @notice Implements a payments collector contract that can be used to collect |
| 13 | + * recurrent payments. |
| 14 | + */ |
| 15 | +interface IRecurringCollector is IAuthorizable, IPaymentsCollector { |
| 16 | + /// @notice A representation of a signed Recurrent Collection Voucher (RCV) |
| 17 | + struct SignedRCV { |
| 18 | + // The RCV |
| 19 | + RecurrentCollectionVoucher rcv; |
| 20 | + // Signature - 65 bytes: r (32 Bytes) || s (32 Bytes) || v (1 Byte) |
| 21 | + bytes signature; |
| 22 | + } |
| 23 | + |
| 24 | + /// @notice The Recurrent Collection Voucher (RCV) |
| 25 | + struct RecurrentCollectionVoucher { |
| 26 | + // The agreement ID of the RCV |
| 27 | + bytes16 agreementId; |
| 28 | + // The deadline for accepting the RCV |
| 29 | + uint256 acceptDeadline; |
| 30 | + // The duration of the RCV in seconds |
| 31 | + uint256 duration; |
| 32 | + // The address of the payer the RCV was issued by |
| 33 | + address payer; |
| 34 | + // The address of the data service the RCV was issued to |
| 35 | + address dataService; |
| 36 | + // The address of the service provider the RCV was issued to |
| 37 | + address serviceProvider; |
| 38 | + // The maximum amount of tokens that can be collected in the first collection |
| 39 | + // on top of the amount allowed for subsequent collections |
| 40 | + uint256 maxInitialTokens; |
| 41 | + // The maximum amount of tokens that can be collected in a single collection |
| 42 | + // except for the first collection |
| 43 | + uint256 maxOngoingTokensPerSecond; |
| 44 | + // The minimum amount of seconds that must pass between collections |
| 45 | + uint32 minSecondsPerCollection; |
| 46 | + // The maximum amount of seconds that can pass between collections |
| 47 | + uint32 maxSecondsPerCollection; |
| 48 | + // Arbitrary metadata to extend functionality if a data service requires it |
| 49 | + bytes metadata; |
| 50 | + } |
| 51 | + |
| 52 | + /// @notice The data for an agreement |
| 53 | + struct AgreementData { |
| 54 | + // The timestamp when the agreement was accepted |
| 55 | + uint256 acceptedAt; |
| 56 | + // The timestamp when the agreement was last collected at |
| 57 | + uint256 lastCollectionAt; |
| 58 | + // The duration of the agreement in seconds |
| 59 | + uint256 duration; |
| 60 | + // The maximum amount of tokens that can be collected in the first collection |
| 61 | + // on top of the amount allowed for subsequent collections |
| 62 | + uint256 maxInitialTokens; |
| 63 | + // The maximum amount of tokens that can be collected in a single collection |
| 64 | + // except for the first collection |
| 65 | + uint256 maxOngoingTokensPerSecond; |
| 66 | + // The minimum amount of seconds that must pass between collections |
| 67 | + uint32 minSecondsPerCollection; |
| 68 | + // The maximum amount of seconds that can pass between collections |
| 69 | + uint32 maxSecondsPerCollection; |
| 70 | + } |
| 71 | + |
| 72 | + /// @notice The key for a stored agreement |
| 73 | + struct AgreementKey { |
| 74 | + // The address of the data service the agreement was issued to |
| 75 | + address dataService; |
| 76 | + // The address of the payer the agreement was issued by |
| 77 | + address payer; |
| 78 | + // The address of the service provider the agreement was issued to |
| 79 | + address serviceProvider; |
| 80 | + // The ID of the agreement |
| 81 | + bytes16 agreementId; |
| 82 | + } |
| 83 | + |
| 84 | + /// @notice The params for collecting an agreement |
| 85 | + struct CollectParams { |
| 86 | + // The agreement key that uniquely identifies it |
| 87 | + AgreementKey key; |
| 88 | + // The collection ID |
| 89 | + bytes32 collectionId; |
| 90 | + // The amount of tokens to collect |
| 91 | + uint256 tokens; |
| 92 | + // The data service cut in PPM |
| 93 | + uint256 dataServiceCut; |
| 94 | + } |
| 95 | + |
| 96 | + /** |
| 97 | + * @notice Emitted when an RCV is collected |
| 98 | + * @param dataService The address of the data service |
| 99 | + * @param payer The address of the payer |
| 100 | + * @param serviceProvider The address of the service provider |
| 101 | + */ |
| 102 | + event RCVCollected( |
| 103 | + address indexed dataService, |
| 104 | + address indexed payer, |
| 105 | + address indexed serviceProvider, |
| 106 | + bytes32 collectionId, |
| 107 | + uint256 tokens, |
| 108 | + uint256 dataServiceCut |
| 109 | + ); |
| 110 | + |
| 111 | + /** |
| 112 | + * Thrown when calling accept() for an agreement with an elapsed acceptance deadline |
| 113 | + * @param elapsedAt The timestamp when the acceptance deadline elapsed |
| 114 | + */ |
| 115 | + error RecurringCollectorAgreementAcceptanceElapsed(uint256 elapsedAt); |
| 116 | + |
| 117 | + /** |
| 118 | + * Thrown when the RCV signer is invalid |
| 119 | + */ |
| 120 | + error RecurringCollectorInvalidRCVSigner(); |
| 121 | + |
| 122 | + /** |
| 123 | + * Thrown when the payment type is not IndexingFee |
| 124 | + * @param paymentType The provided payment type |
| 125 | + */ |
| 126 | + error RecurringCollectorInvalidPaymentType(IGraphPayments.PaymentTypes paymentType); |
| 127 | + |
| 128 | + /** |
| 129 | + * Thrown when the caller is not the data service the RCV was issued to |
| 130 | + * @param caller The address of the caller |
| 131 | + * @param dataService The address of the data service |
| 132 | + */ |
| 133 | + error RecurringCollectorCallerNotDataService(address caller, address dataService); |
| 134 | + |
| 135 | + /** |
| 136 | + * Thrown when calling collect() with invalid data |
| 137 | + * @param data The invalid data |
| 138 | + */ |
| 139 | + error RecurringCollectorInvalidCollectData(bytes data); |
| 140 | + |
| 141 | + /** |
| 142 | + * Thrown when calling accept() for an already accepted agreement |
| 143 | + * @param key The agreement key |
| 144 | + */ |
| 145 | + error RecurringCollectorAgreementAlreadyAccepted(AgreementKey key); |
| 146 | + |
| 147 | + /** |
| 148 | + * Thrown when calling cancel() for a never accepted agreement |
| 149 | + * @param key The agreement key |
| 150 | + */ |
| 151 | + error RecurringCollectorAgreementNeverAccepted(AgreementKey key); |
| 152 | + |
| 153 | + /** |
| 154 | + * Thrown when calling collect() on an invalid agreement |
| 155 | + * @param key The agreement key |
| 156 | + * @param acceptedAt The agreement accepted timestamp |
| 157 | + */ |
| 158 | + error RecurringCollectorAgreementInvalid(AgreementKey key, uint256 acceptedAt); |
| 159 | + |
| 160 | + /** |
| 161 | + * Thrown when calling collect() on an elapsed agreement |
| 162 | + * @param key The agreement key |
| 163 | + * @param agreementEnd The agreement end timestamp |
| 164 | + */ |
| 165 | + error RecurringCollectorAgreementElapsed(AgreementKey key, uint256 agreementEnd); |
| 166 | + |
| 167 | + /** |
| 168 | + * Thrown when calling collect() too soon |
| 169 | + * @param key The agreement key |
| 170 | + * @param secondsSinceLast Seconds since last collection |
| 171 | + * @param minSeconds Minimum seconds between collections |
| 172 | + */ |
| 173 | + error RecurringCollectorCollectionTooSoon(AgreementKey key, uint256 secondsSinceLast, uint256 minSeconds); |
| 174 | + |
| 175 | + /** |
| 176 | + * Thrown when calling collect() too late |
| 177 | + * @param key The agreement key |
| 178 | + * @param secondsSinceLast Seconds since last collection |
| 179 | + * @param maxSeconds Maximum seconds between collections |
| 180 | + */ |
| 181 | + error RecurringCollectorCollectionTooLate(AgreementKey key, uint256 secondsSinceLast, uint256 maxSeconds); |
| 182 | + |
| 183 | + /** |
| 184 | + * Thrown when calling collect() too late |
| 185 | + * @param key The agreement key |
| 186 | + * @param tokens The amount of tokens to collect |
| 187 | + * @param maxTokens The maximum amount of tokens allowed to collect |
| 188 | + */ |
| 189 | + error RecurringCollectorCollectAmountTooHigh(AgreementKey key, uint256 tokens, uint256 maxTokens); |
| 190 | + |
| 191 | + /** |
| 192 | + * @dev Accept an indexing agreement. |
| 193 | + * @param signedRCV The signed Recurrent Collection Voucher which is to be accepted. |
| 194 | + */ |
| 195 | + function accept(SignedRCV memory signedRCV) external; |
| 196 | + |
| 197 | + /** |
| 198 | + * @dev Cancel an indexing agreement. |
| 199 | + * @param payer The address of the payer for the agreement. |
| 200 | + * @param serviceProvider The address of the serviceProvider for the agreement. |
| 201 | + * @param agreementId The agreement's ID. |
| 202 | + */ |
| 203 | + function cancel(address payer, address serviceProvider, bytes16 agreementId) external; |
| 204 | + |
| 205 | + /** |
| 206 | + * @dev Computes the hash of a RecurrentCollectionVoucher (RCV). |
| 207 | + * @param rcv The RCV for which to compute the hash. |
| 208 | + * @return The hash of the RCV. |
| 209 | + */ |
| 210 | + function encodeRCV(RecurrentCollectionVoucher calldata rcv) external view returns (bytes32); |
| 211 | + |
| 212 | + /** |
| 213 | + * @dev Recovers the signer address of a signed RecurrentCollectionVoucher (RCV). |
| 214 | + * @param signedRCV The SignedRCV containing the RCV and its signature. |
| 215 | + * @return The address of the signer. |
| 216 | + */ |
| 217 | + function recoverRCVSigner(SignedRCV calldata signedRCV) external view returns (address); |
| 218 | +} |
0 commit comments