ci: clean up CI workflows and fix package dependencies
Some checks failed
Integration Tests / test-service-integration (push) Successful in 2m16s
Package Tests / Python package - aitbc-agent-sdk (push) Successful in 25s
Package Tests / Python package - aitbc-core (push) Successful in 22s
Package Tests / Python package - aitbc-crypto (push) Successful in 14s
Package Tests / Python package - aitbc-sdk (push) Successful in 18s
Package Tests / JavaScript package - aitbc-sdk-js (push) Successful in 6s
Package Tests / JavaScript package - aitbc-token (push) Successful in 21s
Production Tests / Production Integration Tests (push) Failing after 10s
Python Tests / test-python (push) Failing after 2m41s
Security Scanning / security-scan (push) Failing after 46s
Smart Contract Tests / test-solidity (map[name:aitbc-token path:packages/solidity/aitbc-token]) (push) Successful in 16s
Smart Contract Tests / lint-solidity (push) Successful in 12s

- Simplified npm install commands in CI workflows by removing fallback logic
- Added aitbc-crypto local dependency installation for aitbc-sdk in package-tests.yml
- Removed aitbc-token specific Hardhat dependency workarounds from package-tests.yml
- Fixed bare except clause in agent_daemon.py to catch specific json.JSONDecodeError
- Moved aitbc-crypto from poetry.dependencies to standard dependencies in aitbc-sdk
- Fixed MyPy type errors in receip
This commit is contained in:
aitbc
2026-04-19 19:24:09 +02:00
parent 0fc735b802
commit 625c1b7812
29 changed files with 3386 additions and 3377 deletions

View File

@@ -1,16 +1,15 @@
{
"plugins": ["@prettier/plugin-solidity"],
"plugins": ["prettier-plugin-solidity"],
"overrides": [
{
"files": "*.sol",
"options": {
"parser": "solidity-parse",
"parser": "slang",
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"singleQuote": false,
"bracketSpacing": true,
"explicitTypes": "always"
"bracketSpacing": true
}
}
]

View File

@@ -1,61 +1,76 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { AccessControl } from "@openzeppelin/contracts/access/AccessControl.sol";
import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import { MessageHashUtils } from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
/// @title AIToken
/// @notice ERC20 token that mints units for providers based on attested compute receipts
contract AIToken is ERC20, AccessControl {
using ECDSA for bytes32;
using MessageHashUtils for bytes32;
using ECDSA for bytes32;
using MessageHashUtils for bytes32;
bytes32 public constant COORDINATOR_ROLE = keccak256("COORDINATOR_ROLE");
bytes32 public constant ATTESTOR_ROLE = keccak256("ATTESTOR_ROLE");
bytes32 public constant COORDINATOR_ROLE = keccak256("COORDINATOR_ROLE");
bytes32 public constant ATTESTOR_ROLE = keccak256("ATTESTOR_ROLE");
/// @notice Tracks consumed receipt hashes to prevent replay
mapping(bytes32 => bool) public consumedReceipts;
/// @notice Tracks consumed receipt hashes to prevent replay
mapping(bytes32 => bool) public consumedReceipts;
event ReceiptConsumed(bytes32 indexed receiptHash, address indexed provider, uint256 units, address indexed attestor);
event ReceiptConsumed(
bytes32 indexed receiptHash,
address indexed provider,
uint256 units,
address indexed attestor
);
constructor(address admin) ERC20("AIToken", "AIT") {
_grantRole(DEFAULT_ADMIN_ROLE, admin);
}
constructor(address admin) ERC20("AIToken", "AIT") {
_grantRole(DEFAULT_ADMIN_ROLE, admin);
}
/// @notice Mint tokens for a provider when coordinator submits a valid attested receipt
/// @param provider Address of the compute provider receiving minted tokens
/// @param units Amount of tokens to mint
/// @param receiptHash Unique hash representing the off-chain receipt
/// @param signature Coordinator-attested signature authorizing the mint
function mintWithReceipt(
address provider,
uint256 units,
bytes32 receiptHash,
bytes calldata signature
) external onlyRole(COORDINATOR_ROLE) {
require(provider != address(0), "invalid provider");
require(units > 0, "invalid units");
require(!consumedReceipts[receiptHash], "receipt already consumed");
/// @notice Mint tokens for a provider when coordinator submits a valid attested receipt
/// @param provider Address of the compute provider receiving minted tokens
/// @param units Amount of tokens to mint
/// @param receiptHash Unique hash representing the off-chain receipt
/// @param signature Coordinator-attested signature authorizing the mint
function mintWithReceipt(
address provider,
uint256 units,
bytes32 receiptHash,
bytes calldata signature
) external onlyRole(COORDINATOR_ROLE) {
require(provider != address(0), "invalid provider");
require(units > 0, "invalid units");
require(!consumedReceipts[receiptHash], "receipt already consumed");
bytes32 digest = _mintDigest(provider, units, receiptHash);
address attestor = digest.recover(signature);
require(hasRole(ATTESTOR_ROLE, attestor), "invalid attestor signature");
bytes32 digest = _mintDigest(provider, units, receiptHash);
address attestor = digest.recover(signature);
require(hasRole(ATTESTOR_ROLE, attestor), "invalid attestor signature");
consumedReceipts[receiptHash] = true;
_mint(provider, units);
consumedReceipts[receiptHash] = true;
_mint(provider, units);
emit ReceiptConsumed(receiptHash, provider, units, attestor);
}
emit ReceiptConsumed(receiptHash, provider, units, attestor);
}
/// @notice Helper to compute the signed digest required for minting
function mintDigest(address provider, uint256 units, bytes32 receiptHash) external view returns (bytes32) {
return _mintDigest(provider, units, receiptHash);
}
/// @notice Helper to compute the signed digest required for minting
function mintDigest(
address provider,
uint256 units,
bytes32 receiptHash
) external view returns (bytes32) {
return _mintDigest(provider, units, receiptHash);
}
function _mintDigest(address provider, uint256 units, bytes32 receiptHash) internal view returns (bytes32) {
bytes32 structHash = keccak256(abi.encode(block.chainid, address(this), provider, units, receiptHash));
return structHash.toEthSignedMessageHash();
}
function _mintDigest(
address provider,
uint256 units,
bytes32 receiptHash
) internal view returns (bytes32) {
bytes32 structHash = keccak256(
abi.encode(block.chainid, address(this), provider, units, receiptHash)
);
return structHash.toEthSignedMessageHash();
}
}

View File

@@ -1,46 +1,61 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
import { AccessControl } from "@openzeppelin/contracts/access/AccessControl.sol";
/// @title AITokenRegistry
/// @notice Tracks permitted providers and staking requirements for AIToken minting
contract AITokenRegistry is AccessControl {
bytes32 public constant COORDINATOR_ROLE = keccak256("COORDINATOR_ROLE");
bytes32 public constant COORDINATOR_ROLE = keccak256("COORDINATOR_ROLE");
struct ProviderInfo {
bool active;
uint256 collateral;
}
struct ProviderInfo {
bool active;
uint256 collateral;
}
mapping(address => ProviderInfo) public providers;
mapping(address => ProviderInfo) public providers;
event ProviderRegistered(address indexed provider, uint256 collateral);
event ProviderUpdated(address indexed provider, bool active, uint256 collateral);
event ProviderRegistered(address indexed provider, uint256 collateral);
event ProviderUpdated(
address indexed provider,
bool active,
uint256 collateral
);
constructor(address admin) {
_grantRole(DEFAULT_ADMIN_ROLE, admin);
}
constructor(address admin) {
_grantRole(DEFAULT_ADMIN_ROLE, admin);
}
function registerProvider(address provider, uint256 collateral) external onlyRole(COORDINATOR_ROLE) {
require(provider != address(0), "invalid provider");
require(!providers[provider].active, "already registered");
providers[provider] = ProviderInfo({active: true, collateral: collateral});
emit ProviderRegistered(provider, collateral);
}
function registerProvider(
address provider,
uint256 collateral
) external onlyRole(COORDINATOR_ROLE) {
require(provider != address(0), "invalid provider");
require(!providers[provider].active, "already registered");
providers[provider] = ProviderInfo({
active: true,
collateral: collateral
});
emit ProviderRegistered(provider, collateral);
}
function updateProvider(
address provider,
bool active,
uint256 collateral
) external onlyRole(COORDINATOR_ROLE) {
require(provider != address(0), "invalid provider");
require(providers[provider].active || active, "provider not registered");
providers[provider] = ProviderInfo({active: active, collateral: collateral});
emit ProviderUpdated(provider, active, collateral);
}
function updateProvider(
address provider,
bool active,
uint256 collateral
) external onlyRole(COORDINATOR_ROLE) {
require(provider != address(0), "invalid provider");
require(providers[provider].active || active, "provider not registered");
providers[provider] = ProviderInfo({
active: active,
collateral: collateral
});
emit ProviderUpdated(provider, active, collateral);
}
function providerInfo(address provider) external view returns (ProviderInfo memory) {
return providers[provider];
}
function providerInfo(
address provider
) external view returns (ProviderInfo memory) {
return providers[provider];
}
}

View File

@@ -0,0 +1,7 @@
declare module "@nomicfoundation/hardhat-toolbox-mocha-ethers" {
import type { HardhatPlugin } from "hardhat/types/plugins";
const hardhatToolboxMochaEthersPlugin: HardhatPlugin;
export default hardhatToolboxMochaEthersPlugin;
}

View File

@@ -1,7 +1,8 @@
import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";
import { defineConfig } from "hardhat/config";
import hardhatToolboxMochaEthersPlugin from "@nomicfoundation/hardhat-toolbox-mocha-ethers";
const config: HardhatUserConfig = {
export default defineConfig({
plugins: [hardhatToolboxMochaEthersPlugin],
solidity: {
version: "0.8.25",
settings: {
@@ -19,11 +20,10 @@ const config: HardhatUserConfig = {
artifacts: "artifacts"
},
networks: {
hardhat: {},
localhost: {
type: "http",
chainType: "l1",
url: "http://127.0.0.1:8545"
}
}
};
export default config;
});

File diff suppressed because it is too large Load Diff

View File

@@ -12,23 +12,26 @@
"deploy": "hardhat run scripts/deploy.ts --network localhost"
},
"devDependencies": {
"@nomicfoundation/hardhat-chai-matchers": "^3.0.0",
"@nomicfoundation/hardhat-ethers": "^4.0.7",
"@nomicfoundation/hardhat-ignition-ethers": "^3.1.1",
"@nomicfoundation/hardhat-network-helpers": "^3.0.4",
"@nomicfoundation/hardhat-toolbox": "7.0.0-hh2",
"@nomicfoundation/hardhat-verify": "^3.0.13",
"@typechain/ethers-v6": "^0.5.1",
"@types/chai": "^4.3.11",
"@nomicfoundation/hardhat-ethers": "^4.0.0",
"@nomicfoundation/hardhat-ethers-chai-matchers": "^3.0.0",
"@nomicfoundation/hardhat-ignition": "^3.0.7",
"@nomicfoundation/hardhat-ignition-ethers": "^3.0.7",
"@nomicfoundation/hardhat-keystore": "^3.0.0",
"@nomicfoundation/hardhat-mocha": "^3.0.0",
"@nomicfoundation/hardhat-network-helpers": "^3.0.0",
"@nomicfoundation/hardhat-toolbox-mocha-ethers": "^3.0.2",
"@nomicfoundation/hardhat-typechain": "^3.0.0",
"@nomicfoundation/hardhat-verify": "^3.0.0",
"@nomicfoundation/ignition-core": "^3.0.7",
"@types/chai": "^5.2.3",
"@types/mocha": "^10.0.10",
"@types/node": "^20.11.30",
"chai": "^4.4.1",
"chai": "^5.1.2",
"ethers": "^6.16.0",
"hardhat": "^3.3.0",
"hardhat-gas-reporter": "^1.0.10",
"@prettier/plugin-solidity": "^1.3.1",
"mocha": "^11.0.0",
"prettier": "^3.2.5",
"solidity-coverage": "^0.8.4",
"prettier-plugin-solidity": "^2.3.1",
"ts-node": "^10.9.2",
"typescript": "^5.9.2"
},

View File

@@ -1,5 +1,10 @@
import { ethers } from "hardhat";
import { AIToken__factory } from "../typechain-types";
import type { HardhatEthers } from "@nomicfoundation/hardhat-ethers/types";
import { network } from "hardhat";
import type { NetworkConnection } from "hardhat/types/network";
type HardhatConnection = NetworkConnection & {
ethers: HardhatEthers;
};
function envOrDefault(name: string, fallback?: string): string | undefined {
const value = process.env[name]?.trim();
@@ -7,11 +12,12 @@ function envOrDefault(name: string, fallback?: string): string | undefined {
}
async function main() {
const { ethers } = (await network.connect()) as HardhatConnection;
const [deployer, coordinatorCandidate] = await ethers.getSigners();
console.log("Deploying AIToken using admin:", deployer.address);
const contractFactory: AIToken__factory = await ethers.getContractFactory("AIToken");
const contractFactory = await ethers.getContractFactory("AIToken");
const token = await contractFactory.deploy(deployer.address);
await token.waitForDeployment();
@@ -21,10 +27,13 @@ async function main() {
const coordinatorRole = await token.COORDINATOR_ROLE();
const attestorRole = await token.ATTESTOR_ROLE();
const coordinatorAddress = envOrDefault("COORDINATOR_ADDRESS", coordinatorCandidate.address);
const coordinatorAddress = envOrDefault(
"COORDINATOR_ADDRESS",
coordinatorCandidate.address,
);
if (!coordinatorAddress) {
throw new Error(
"COORDINATOR_ADDRESS not provided and could not infer fallback signer address"
"COORDINATOR_ADDRESS not provided and could not infer fallback signer address",
);
}

View File

@@ -1,9 +1,15 @@
import { ethers } from "hardhat";
import type { HardhatEthers } from "@nomicfoundation/hardhat-ethers/types";
import { network } from "hardhat";
import type { NetworkConnection } from "hardhat/types/network";
import { AIToken__factory } from "../typechain-types";
type HardhatConnection = NetworkConnection & {
ethers: HardhatEthers;
};
type HexString = `0x${string}`;
type EnvValue = string & {}
type EnvValue = string & {};
function requireEnv(name: string): EnvValue {
const value = process.env[name]?.trim();
@@ -20,7 +26,9 @@ function parseUnits(value: string): bigint {
}
return BigInt(value);
} catch (error) {
throw new Error(`UNITS must be a BigInt-compatible value, received ${value}`);
throw new Error(
`UNITS must be a BigInt-compatible value, received ${value}`,
);
}
}
@@ -32,18 +40,25 @@ function assertHex(value: string, name: string): HexString {
}
async function main() {
const contractAddress = assertHex(requireEnv("AITOKEN_ADDRESS"), "AITOKEN_ADDRESS");
const { ethers } = (await network.connect()) as HardhatConnection;
const contractAddress = assertHex(
requireEnv("AITOKEN_ADDRESS"),
"AITOKEN_ADDRESS",
);
const providerAddress = requireEnv("PROVIDER_ADDRESS");
const units = parseUnits(requireEnv("UNITS"));
const receiptHash = assertHex(requireEnv("RECEIPT_HASH"), "RECEIPT_HASH");
const signature = assertHex(requireEnv("ATTESTOR_SIGNATURE"), "ATTESTOR_SIGNATURE");
const signature = assertHex(
requireEnv("ATTESTOR_SIGNATURE"),
"ATTESTOR_SIGNATURE",
);
const coordinatorIndex = Number(process.env.COORDINATOR_SIGNER_INDEX ?? "1");
const signers = await ethers.getSigners();
const coordinator = signers[coordinatorIndex];
if (!coordinator) {
throw new Error(
`COORDINATOR_SIGNER_INDEX=${coordinatorIndex} does not correspond to an available signer`
`COORDINATOR_SIGNER_INDEX=${coordinatorIndex} does not correspond to an available signer`,
);
}
@@ -52,7 +67,12 @@ async function main() {
console.log("Units:", units.toString());
const token = AIToken__factory.connect(contractAddress, coordinator);
const tx = await token.mintWithReceipt(providerAddress, units, receiptHash, signature);
const tx = await token.mintWithReceipt(
providerAddress,
units,
receiptHash,
signature,
);
const receipt = await tx.wait();
console.log("Mint transaction hash:", receipt?.hash ?? tx.hash);

View File

@@ -1,12 +1,70 @@
import { expect } from "chai";
import { ethers } from "hardhat";
import { loadFixture } from "@nomicfoundation/hardhat-toolbox/network-helpers";
import type { Signer } from "ethers";
import type { HardhatEthers } from "@nomicfoundation/hardhat-ethers/types";
import type { NetworkHelpers } from "@nomicfoundation/hardhat-network-helpers/types";
import type { BaseContract, ContractTransactionResponse, Signer } from "ethers";
import { network } from "hardhat";
import type { NetworkConnection } from "hardhat/types/network";
import type { AIToken } from "../typechain-types";
import { AIToken__factory } from "../typechain-types";
type HardhatConnection = NetworkConnection & {
ethers: HardhatEthers;
networkHelpers: NetworkHelpers;
};
const { ethers, networkHelpers } =
(await network.connect()) as HardhatConnection;
async function expectRevert(
operation: Promise<unknown>,
expectedMessage?: string,
) {
let caughtError: unknown;
try {
await operation;
} catch (error) {
caughtError = error;
}
expect(caughtError).to.not.equal(undefined);
if (expectedMessage !== undefined) {
const message =
caughtError instanceof Error ? caughtError.message : String(caughtError);
expect(message).to.contain(expectedMessage);
}
}
async function expectEvent(
contract: BaseContract,
operation: Promise<ContractTransactionResponse>,
eventName: string,
expectedArgs: readonly unknown[],
) {
const tx = await operation;
const receipt = await tx.wait();
expect(receipt).to.not.equal(null);
const parsedLog = receipt!.logs
.map((log) => {
try {
return contract.interface.parseLog(log);
} catch {
return null;
}
})
.find((entry) => entry?.name === eventName);
expect(parsedLog).to.not.equal(undefined);
expect(parsedLog).to.not.equal(null);
expect(Array.from(parsedLog!.args)).to.deep.equal([...expectedArgs]);
}
async function deployAITokenFixture() {
const [admin, coordinator, attestor, provider, outsider] = await ethers.getSigners();
const [admin, coordinator, attestor, provider, outsider] =
await ethers.getSigners();
const factory = new AIToken__factory(admin);
const token = await factory.deploy(admin.address);
@@ -26,7 +84,7 @@ async function buildSignature(
attestor: Signer,
provider: string,
units: bigint,
receiptHash: string
receiptHash: string,
) {
const chainId = (await ethers.provider.getNetwork()).chainId;
const contractAddress = await token.getAddress();
@@ -34,7 +92,7 @@ async function buildSignature(
const encoded = abiCoder.encode(
["uint256", "address", "address", "uint256", "bytes32"],
[chainId, contractAddress, provider, units, receiptHash]
[chainId, contractAddress, provider, units, receiptHash],
);
const structHash = ethers.keccak256(encoded);
@@ -43,46 +101,61 @@ async function buildSignature(
describe("AIToken", function () {
it("mints tokens when presented a valid attestor signature", async function () {
const { token, coordinator, attestor, provider } = await loadFixture(deployAITokenFixture);
const { token, coordinator, attestor, provider } =
await networkHelpers.loadFixture(deployAITokenFixture);
const units = 100n;
const receiptHash = ethers.keccak256(ethers.toUtf8Bytes("receipt-1"));
const signature = await buildSignature(token, attestor, provider.address, units, receiptHash);
const signature = await buildSignature(
token,
attestor,
provider.address,
units,
receiptHash,
);
await expect(
await expectEvent(
token,
token
.connect(coordinator)
.mintWithReceipt(provider.address, units, receiptHash, signature)
)
.to.emit(token, "ReceiptConsumed")
.withArgs(receiptHash, provider.address, units, attestor.address);
.mintWithReceipt(provider.address, units, receiptHash, signature),
"ReceiptConsumed",
[receiptHash, provider.address, units, attestor.address],
);
expect(await token.balanceOf(provider.address)).to.equal(units);
expect(await token.consumedReceipts(receiptHash)).to.equal(true);
});
it("rejects reuse of a consumed receipt hash", async function () {
const { token, coordinator, attestor, provider } = await loadFixture(deployAITokenFixture);
const { token, coordinator, attestor, provider } =
await networkHelpers.loadFixture(deployAITokenFixture);
const units = 50n;
const receiptHash = ethers.keccak256(ethers.toUtf8Bytes("receipt-2"));
const signature = await buildSignature(token, attestor, provider.address, units, receiptHash);
const signature = await buildSignature(
token,
attestor,
provider.address,
units,
receiptHash,
);
await token
.connect(coordinator)
.mintWithReceipt(provider.address, units, receiptHash, signature);
await expect(
await expectRevert(
token
.connect(coordinator)
.mintWithReceipt(provider.address, units, receiptHash, signature)
).to.be.revertedWith("receipt already consumed");
.mintWithReceipt(provider.address, units, receiptHash, signature),
"receipt already consumed",
);
});
it("rejects signatures from non-attestors", async function () {
const { token, coordinator, attestor, provider, outsider } = await loadFixture(
deployAITokenFixture
);
const { token, coordinator, attestor, provider, outsider } =
await networkHelpers.loadFixture(deployAITokenFixture);
const units = 25n;
const receiptHash = ethers.keccak256(ethers.toUtf8Bytes("receipt-3"));
@@ -91,60 +164,85 @@ describe("AIToken", function () {
outsider,
provider.address,
units,
receiptHash
receiptHash,
);
await expect(
await expectRevert(
token
.connect(coordinator)
.mintWithReceipt(provider.address, units, receiptHash, signature)
).to.be.revertedWith("invalid attestor signature");
.mintWithReceipt(provider.address, units, receiptHash, signature),
"invalid attestor signature",
);
});
it("rejects minting to zero address", async function () {
const { token, coordinator, attestor } = await loadFixture(deployAITokenFixture);
const { token, coordinator, attestor } =
await networkHelpers.loadFixture(deployAITokenFixture);
const units = 100n;
const receiptHash = ethers.keccak256(ethers.toUtf8Bytes("receipt-4"));
const signature = await buildSignature(token, attestor, ethers.ZeroAddress, units, receiptHash);
const signature = await buildSignature(
token,
attestor,
ethers.ZeroAddress,
units,
receiptHash,
);
await expect(
await expectRevert(
token
.connect(coordinator)
.mintWithReceipt(ethers.ZeroAddress, units, receiptHash, signature)
).to.be.revertedWith("invalid provider");
.mintWithReceipt(ethers.ZeroAddress, units, receiptHash, signature),
"invalid provider",
);
});
it("rejects minting zero units", async function () {
const { token, coordinator, attestor, provider } = await loadFixture(deployAITokenFixture);
const { token, coordinator, attestor, provider } =
await networkHelpers.loadFixture(deployAITokenFixture);
const units = 0n;
const receiptHash = ethers.keccak256(ethers.toUtf8Bytes("receipt-5"));
const signature = await buildSignature(token, attestor, provider.address, units, receiptHash);
const signature = await buildSignature(
token,
attestor,
provider.address,
units,
receiptHash,
);
await expect(
await expectRevert(
token
.connect(coordinator)
.mintWithReceipt(provider.address, units, receiptHash, signature)
).to.be.revertedWith("invalid units");
.mintWithReceipt(provider.address, units, receiptHash, signature),
"invalid units",
);
});
it("rejects minting from non-coordinator", async function () {
const { token, attestor, provider, outsider } = await loadFixture(deployAITokenFixture);
const { token, attestor, provider, outsider } =
await networkHelpers.loadFixture(deployAITokenFixture);
const units = 100n;
const receiptHash = ethers.keccak256(ethers.toUtf8Bytes("receipt-6"));
const signature = await buildSignature(token, attestor, provider.address, units, receiptHash);
const signature = await buildSignature(
token,
attestor,
provider.address,
units,
receiptHash,
);
await expect(
await expectRevert(
token
.connect(outsider)
.mintWithReceipt(provider.address, units, receiptHash, signature)
).to.be.reverted;
.mintWithReceipt(provider.address, units, receiptHash, signature),
);
});
it("returns correct mint digest", async function () {
const { token, provider } = await loadFixture(deployAITokenFixture);
const { token, provider } =
await networkHelpers.loadFixture(deployAITokenFixture);
const units = 100n;
const receiptHash = ethers.keccak256(ethers.toUtf8Bytes("receipt-7"));
@@ -155,7 +253,7 @@ describe("AIToken", function () {
});
it("has correct token name and symbol", async function () {
const { token } = await loadFixture(deployAITokenFixture);
const { token } = await networkHelpers.loadFixture(deployAITokenFixture);
expect(await token.name()).to.equal("AIToken");
expect(await token.symbol()).to.equal("AIT");

View File

@@ -1,10 +1,69 @@
import { expect } from "chai";
import { ethers } from "hardhat";
import { loadFixture } from "@nomicfoundation/hardhat-toolbox/network-helpers";
import type { HardhatEthers } from "@nomicfoundation/hardhat-ethers/types";
import type { NetworkHelpers } from "@nomicfoundation/hardhat-network-helpers/types";
import type { BaseContract, ContractTransactionResponse } from "ethers";
import { network } from "hardhat";
import type { NetworkConnection } from "hardhat/types/network";
import { AITokenRegistry__factory } from "../typechain-types";
type HardhatConnection = NetworkConnection & {
ethers: HardhatEthers;
networkHelpers: NetworkHelpers;
};
const { ethers, networkHelpers } =
(await network.connect()) as HardhatConnection;
async function expectRevert(
operation: Promise<unknown>,
expectedMessage?: string,
) {
let caughtError: unknown;
try {
await operation;
} catch (error) {
caughtError = error;
}
expect(caughtError).to.not.equal(undefined);
if (expectedMessage !== undefined) {
const message =
caughtError instanceof Error ? caughtError.message : String(caughtError);
expect(message).to.contain(expectedMessage);
}
}
async function expectEvent(
contract: BaseContract,
operation: Promise<ContractTransactionResponse>,
eventName: string,
expectedArgs: readonly unknown[],
) {
const tx = await operation;
const receipt = await tx.wait();
expect(receipt).to.not.equal(null);
const parsedLog = receipt!.logs
.map((log) => {
try {
return contract.interface.parseLog(log);
} catch {
return null;
}
})
.find((entry) => entry?.name === eventName);
expect(parsedLog).to.not.equal(undefined);
expect(parsedLog).to.not.equal(null);
expect(Array.from(parsedLog!.args)).to.deep.equal([...expectedArgs]);
}
async function deployRegistryFixture() {
const [admin, coordinator, provider1, provider2, outsider] = await ethers.getSigners();
const [admin, coordinator, provider1, provider2, outsider] =
await ethers.getSigners();
const factory = new AITokenRegistry__factory(admin);
const registry = await factory.deploy(admin.address);
@@ -19,15 +78,19 @@ async function deployRegistryFixture() {
describe("AITokenRegistry", function () {
describe("Provider Registration", function () {
it("allows coordinator to register a provider", async function () {
const { registry, coordinator, provider1 } = await loadFixture(deployRegistryFixture);
const { registry, coordinator, provider1 } =
await networkHelpers.loadFixture(deployRegistryFixture);
const collateral = ethers.parseEther("100");
await expect(
registry.connect(coordinator).registerProvider(provider1.address, collateral)
)
.to.emit(registry, "ProviderRegistered")
.withArgs(provider1.address, collateral);
await expectEvent(
registry,
registry
.connect(coordinator)
.registerProvider(provider1.address, collateral),
"ProviderRegistered",
[provider1.address, collateral],
);
const info = await registry.providerInfo(provider1.address);
expect(info.active).to.equal(true);
@@ -35,43 +98,57 @@ describe("AITokenRegistry", function () {
});
it("rejects registration of zero address", async function () {
const { registry, coordinator } = await loadFixture(deployRegistryFixture);
const { registry, coordinator } = await networkHelpers.loadFixture(
deployRegistryFixture,
);
await expect(
registry.connect(coordinator).registerProvider(ethers.ZeroAddress, 0)
).to.be.revertedWith("invalid provider");
await expectRevert(
registry.connect(coordinator).registerProvider(ethers.ZeroAddress, 0),
"invalid provider",
);
});
it("rejects duplicate registration", async function () {
const { registry, coordinator, provider1 } = await loadFixture(deployRegistryFixture);
const { registry, coordinator, provider1 } =
await networkHelpers.loadFixture(deployRegistryFixture);
await registry.connect(coordinator).registerProvider(provider1.address, 100);
await registry
.connect(coordinator)
.registerProvider(provider1.address, 100);
await expect(
registry.connect(coordinator).registerProvider(provider1.address, 200)
).to.be.revertedWith("already registered");
await expectRevert(
registry.connect(coordinator).registerProvider(provider1.address, 200),
"already registered",
);
});
it("rejects registration from non-coordinator", async function () {
const { registry, provider1, outsider } = await loadFixture(deployRegistryFixture);
const { registry, provider1, outsider } =
await networkHelpers.loadFixture(deployRegistryFixture);
await expect(
registry.connect(outsider).registerProvider(provider1.address, 100)
).to.be.reverted;
await expectRevert(
registry.connect(outsider).registerProvider(provider1.address, 100),
);
});
});
describe("Provider Updates", function () {
it("allows coordinator to update provider status", async function () {
const { registry, coordinator, provider1 } = await loadFixture(deployRegistryFixture);
const { registry, coordinator, provider1 } =
await networkHelpers.loadFixture(deployRegistryFixture);
await registry.connect(coordinator).registerProvider(provider1.address, 100);
await registry
.connect(coordinator)
.registerProvider(provider1.address, 100);
await expect(
registry.connect(coordinator).updateProvider(provider1.address, false, 50)
)
.to.emit(registry, "ProviderUpdated")
.withArgs(provider1.address, false, 50);
await expectEvent(
registry,
registry
.connect(coordinator)
.updateProvider(provider1.address, false, 50),
"ProviderUpdated",
[provider1.address, false, 50n],
);
const info = await registry.providerInfo(provider1.address);
expect(info.active).to.equal(false);
@@ -79,11 +156,18 @@ describe("AITokenRegistry", function () {
});
it("allows reactivating a deactivated provider", async function () {
const { registry, coordinator, provider1 } = await loadFixture(deployRegistryFixture);
const { registry, coordinator, provider1 } =
await networkHelpers.loadFixture(deployRegistryFixture);
await registry.connect(coordinator).registerProvider(provider1.address, 100);
await registry.connect(coordinator).updateProvider(provider1.address, false, 100);
await registry.connect(coordinator).updateProvider(provider1.address, true, 200);
await registry
.connect(coordinator)
.registerProvider(provider1.address, 100);
await registry
.connect(coordinator)
.updateProvider(provider1.address, false, 100);
await registry
.connect(coordinator)
.updateProvider(provider1.address, true, 200);
const info = await registry.providerInfo(provider1.address);
expect(info.active).to.equal(true);
@@ -91,32 +175,45 @@ describe("AITokenRegistry", function () {
});
it("rejects update of unregistered provider", async function () {
const { registry, coordinator, provider1 } = await loadFixture(deployRegistryFixture);
const { registry, coordinator, provider1 } =
await networkHelpers.loadFixture(deployRegistryFixture);
await expect(
registry.connect(coordinator).updateProvider(provider1.address, false, 100)
).to.be.revertedWith("provider not registered");
await expectRevert(
registry
.connect(coordinator)
.updateProvider(provider1.address, false, 100),
"provider not registered",
);
});
});
describe("Access Control", function () {
it("admin can grant coordinator role", async function () {
const { registry, admin, outsider } = await loadFixture(deployRegistryFixture);
const { registry, admin, outsider } = await networkHelpers.loadFixture(
deployRegistryFixture,
);
const coordinatorRole = await registry.COORDINATOR_ROLE();
await registry.connect(admin).grantRole(coordinatorRole, outsider.address);
await registry
.connect(admin)
.grantRole(coordinatorRole, outsider.address);
expect(await registry.hasRole(coordinatorRole, outsider.address)).to.equal(true);
expect(
await registry.hasRole(coordinatorRole, outsider.address),
).to.equal(true);
});
it("non-admin cannot grant roles", async function () {
const { registry, coordinator, outsider } = await loadFixture(deployRegistryFixture);
const { registry, coordinator, outsider } =
await networkHelpers.loadFixture(deployRegistryFixture);
const coordinatorRole = await registry.COORDINATOR_ROLE();
await expect(
registry.connect(coordinator).grantRole(coordinatorRole, outsider.address)
).to.be.reverted;
await expectRevert(
registry
.connect(coordinator)
.grantRole(coordinatorRole, outsider.address),
);
});
});
});

View File

@@ -1,14 +1,20 @@
{
"compilerOptions": {
"target": "es2020",
"module": "commonjs",
"target": "es2022",
"module": "esnext",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"outDir": "dist",
"types": ["node", "mocha", "hardhat", "@nomicfoundation/hardhat-chai-matchers"],
"resolveJsonModule": true,
"moduleResolution": "node"
"moduleResolution": "bundler"
},
"include": ["hardhat.config.ts", "scripts", "test", "typechain-types"],
"include": [
"hardhat.config.ts",
"hardhat-toolbox-mocha-ethers.d.ts",
"scripts",
"test",
"typechain-types"
],
"exclude": ["dist"]
}

View File

@@ -2,4 +2,3 @@
/* tslint:disable */
/* eslint-disable */
export type { ECDSA } from "./ECDSA";
export type { MessageHashUtils } from "./MessageHashUtils";

View File

@@ -2,4 +2,3 @@
/* tslint:disable */
/* eslint-disable */
export { ECDSA__factory } from "./ECDSA__factory";
export { MessageHashUtils__factory } from "./MessageHashUtils__factory";

View File

@@ -49,10 +49,6 @@ declare module "hardhat/types/runtime" {
name: "ECDSA",
signerOrOptions?: ethers.Signer | FactoryOptions
): Promise<Contracts.ECDSA__factory>;
getContractFactory(
name: "MessageHashUtils",
signerOrOptions?: ethers.Signer | FactoryOptions
): Promise<Contracts.MessageHashUtils__factory>;
getContractFactory(
name: "ERC165",
signerOrOptions?: ethers.Signer | FactoryOptions
@@ -123,11 +119,6 @@ declare module "hardhat/types/runtime" {
address: string | ethers.Addressable,
signer?: ethers.Signer
): Promise<Contracts.ECDSA>;
getContractAt(
name: "MessageHashUtils",
address: string | ethers.Addressable,
signer?: ethers.Signer
): Promise<Contracts.MessageHashUtils>;
getContractAt(
name: "ERC165",
address: string | ethers.Addressable,
@@ -195,10 +186,6 @@ declare module "hardhat/types/runtime" {
name: "ECDSA",
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.ECDSA>;
deployContract(
name: "MessageHashUtils",
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.MessageHashUtils>;
deployContract(
name: "ERC165",
signerOrOptions?: ethers.Signer | DeployContractOptions
@@ -269,11 +256,6 @@ declare module "hardhat/types/runtime" {
args: any[],
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.ECDSA>;
deployContract(
name: "MessageHashUtils",
args: any[],
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.MessageHashUtils>;
deployContract(
name: "ERC165",
args: any[],

View File

@@ -24,8 +24,6 @@ export type { IERC20 } from "./@openzeppelin/contracts/token/ERC20/IERC20";
export { IERC20__factory } from "./factories/@openzeppelin/contracts/token/ERC20/IERC20__factory";
export type { ECDSA } from "./@openzeppelin/contracts/utils/cryptography/ECDSA";
export { ECDSA__factory } from "./factories/@openzeppelin/contracts/utils/cryptography/ECDSA__factory";
export type { MessageHashUtils } from "./@openzeppelin/contracts/utils/cryptography/MessageHashUtils";
export { MessageHashUtils__factory } from "./factories/@openzeppelin/contracts/utils/cryptography/MessageHashUtils__factory";
export type { ERC165 } from "./@openzeppelin/contracts/utils/introspection/ERC165";
export { ERC165__factory } from "./factories/@openzeppelin/contracts/utils/introspection/ERC165__factory";
export type { IERC165 } from "./@openzeppelin/contracts/utils/introspection/IERC165";

View File

@@ -0,0 +1,474 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type { BaseContract, BigNumberish, BytesLike, FunctionFragment, Result, Interface, EventFragment, AddressLike, ContractRunner, ContractMethod, Listener } from "ethers"
import type { TypedContractEvent, TypedDeferredTopicFilter, TypedEventLog, TypedLogDescription, TypedListener, TypedContractMethod } from "./common.js"
export interface AITokenInterface extends Interface {
getFunction(nameOrSignature: "ATTESTOR_ROLE" | "COORDINATOR_ROLE" | "DEFAULT_ADMIN_ROLE" | "allowance" | "approve" | "balanceOf" | "consumedReceipts" | "decimals" | "getRoleAdmin" | "grantRole" | "hasRole" | "mintDigest" | "mintWithReceipt" | "name" | "renounceRole" | "revokeRole" | "supportsInterface" | "symbol" | "totalSupply" | "transfer" | "transferFrom"): FunctionFragment;
getEvent(nameOrSignatureOrTopic: "Approval" | "ReceiptConsumed" | "RoleAdminChanged" | "RoleGranted" | "RoleRevoked" | "Transfer"): EventFragment;
encodeFunctionData(functionFragment: 'ATTESTOR_ROLE', values?: undefined): string;
encodeFunctionData(functionFragment: 'COORDINATOR_ROLE', values?: undefined): string;
encodeFunctionData(functionFragment: 'DEFAULT_ADMIN_ROLE', values?: undefined): string;
encodeFunctionData(functionFragment: 'allowance', values: [AddressLike, AddressLike]): string;
encodeFunctionData(functionFragment: 'approve', values: [AddressLike, BigNumberish]): string;
encodeFunctionData(functionFragment: 'balanceOf', values: [AddressLike]): string;
encodeFunctionData(functionFragment: 'consumedReceipts', values: [BytesLike]): string;
encodeFunctionData(functionFragment: 'decimals', values?: undefined): string;
encodeFunctionData(functionFragment: 'getRoleAdmin', values: [BytesLike]): string;
encodeFunctionData(functionFragment: 'grantRole', values: [BytesLike, AddressLike]): string;
encodeFunctionData(functionFragment: 'hasRole', values: [BytesLike, AddressLike]): string;
encodeFunctionData(functionFragment: 'mintDigest', values: [AddressLike, BigNumberish, BytesLike]): string;
encodeFunctionData(functionFragment: 'mintWithReceipt', values: [AddressLike, BigNumberish, BytesLike, BytesLike]): string;
encodeFunctionData(functionFragment: 'name', values?: undefined): string;
encodeFunctionData(functionFragment: 'renounceRole', values: [BytesLike, AddressLike]): string;
encodeFunctionData(functionFragment: 'revokeRole', values: [BytesLike, AddressLike]): string;
encodeFunctionData(functionFragment: 'supportsInterface', values: [BytesLike]): string;
encodeFunctionData(functionFragment: 'symbol', values?: undefined): string;
encodeFunctionData(functionFragment: 'totalSupply', values?: undefined): string;
encodeFunctionData(functionFragment: 'transfer', values: [AddressLike, BigNumberish]): string;
encodeFunctionData(functionFragment: 'transferFrom', values: [AddressLike, AddressLike, BigNumberish]): string;
decodeFunctionResult(functionFragment: 'ATTESTOR_ROLE', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'COORDINATOR_ROLE', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'DEFAULT_ADMIN_ROLE', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'allowance', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'approve', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'balanceOf', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'consumedReceipts', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'decimals', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'getRoleAdmin', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'grantRole', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'hasRole', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'mintDigest', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'mintWithReceipt', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'name', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'renounceRole', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'revokeRole', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'supportsInterface', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'symbol', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'totalSupply', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'transfer', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'transferFrom', data: BytesLike): Result;
}
export namespace ApprovalEvent {
export type InputTuple = [owner: AddressLike, spender: AddressLike, value: BigNumberish];
export type OutputTuple = [owner: string, spender: string, value: bigint];
export interface OutputObject {owner: string, spender: string, value: bigint };
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>
export type Filter = TypedDeferredTopicFilter<Event>
export type Log = TypedEventLog<Event>
export type LogDescription = TypedLogDescription<Event>
}
export namespace ReceiptConsumedEvent {
export type InputTuple = [receiptHash: BytesLike, provider: AddressLike, units: BigNumberish, attestor: AddressLike];
export type OutputTuple = [receiptHash: string, provider: string, units: bigint, attestor: string];
export interface OutputObject {receiptHash: string, provider: string, units: bigint, attestor: string };
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>
export type Filter = TypedDeferredTopicFilter<Event>
export type Log = TypedEventLog<Event>
export type LogDescription = TypedLogDescription<Event>
}
export namespace RoleAdminChangedEvent {
export type InputTuple = [role: BytesLike, previousAdminRole: BytesLike, newAdminRole: BytesLike];
export type OutputTuple = [role: string, previousAdminRole: string, newAdminRole: string];
export interface OutputObject {role: string, previousAdminRole: string, newAdminRole: string };
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>
export type Filter = TypedDeferredTopicFilter<Event>
export type Log = TypedEventLog<Event>
export type LogDescription = TypedLogDescription<Event>
}
export namespace RoleGrantedEvent {
export type InputTuple = [role: BytesLike, account: AddressLike, sender: AddressLike];
export type OutputTuple = [role: string, account: string, sender: string];
export interface OutputObject {role: string, account: string, sender: string };
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>
export type Filter = TypedDeferredTopicFilter<Event>
export type Log = TypedEventLog<Event>
export type LogDescription = TypedLogDescription<Event>
}
export namespace RoleRevokedEvent {
export type InputTuple = [role: BytesLike, account: AddressLike, sender: AddressLike];
export type OutputTuple = [role: string, account: string, sender: string];
export interface OutputObject {role: string, account: string, sender: string };
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>
export type Filter = TypedDeferredTopicFilter<Event>
export type Log = TypedEventLog<Event>
export type LogDescription = TypedLogDescription<Event>
}
export namespace TransferEvent {
export type InputTuple = [from: AddressLike, to: AddressLike, value: BigNumberish];
export type OutputTuple = [from: string, to: string, value: bigint];
export interface OutputObject {from: string, to: string, value: bigint };
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>
export type Filter = TypedDeferredTopicFilter<Event>
export type Log = TypedEventLog<Event>
export type LogDescription = TypedLogDescription<Event>
}
export interface AIToken extends BaseContract {
connect(runner?: ContractRunner | null): AIToken;
waitForDeployment(): Promise<this>;
interface: AITokenInterface;
queryFilter<TCEvent extends TypedContractEvent>(
event: TCEvent,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined,
): Promise<Array<TypedEventLog<TCEvent>>>
queryFilter<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
on<TCEvent extends TypedContractEvent>(event: TCEvent, listener: TypedListener<TCEvent>): Promise<this>
on<TCEvent extends TypedContractEvent>(filter: TypedDeferredTopicFilter<TCEvent>, listener: TypedListener<TCEvent>): Promise<this>
once<TCEvent extends TypedContractEvent>(event: TCEvent, listener: TypedListener<TCEvent>): Promise<this>
once<TCEvent extends TypedContractEvent>(filter: TypedDeferredTopicFilter<TCEvent>, listener: TypedListener<TCEvent>): Promise<this>
listeners<TCEvent extends TypedContractEvent>(
event: TCEvent
): Promise<Array<TypedListener<TCEvent>>>;
listeners(eventName?: string): Promise<Array<Listener>>
removeAllListeners<TCEvent extends TypedContractEvent>(event?: TCEvent): Promise<this>
ATTESTOR_ROLE: TypedContractMethod<
[],
[string],
'view'
>
COORDINATOR_ROLE: TypedContractMethod<
[],
[string],
'view'
>
DEFAULT_ADMIN_ROLE: TypedContractMethod<
[],
[string],
'view'
>
allowance: TypedContractMethod<
[owner: AddressLike, spender: AddressLike, ],
[bigint],
'view'
>
approve: TypedContractMethod<
[spender: AddressLike, value: BigNumberish, ],
[boolean],
'nonpayable'
>
balanceOf: TypedContractMethod<
[account: AddressLike, ],
[bigint],
'view'
>
consumedReceipts: TypedContractMethod<
[arg0: BytesLike, ],
[boolean],
'view'
>
decimals: TypedContractMethod<
[],
[bigint],
'view'
>
getRoleAdmin: TypedContractMethod<
[role: BytesLike, ],
[string],
'view'
>
grantRole: TypedContractMethod<
[role: BytesLike, account: AddressLike, ],
[void],
'nonpayable'
>
hasRole: TypedContractMethod<
[role: BytesLike, account: AddressLike, ],
[boolean],
'view'
>
mintDigest: TypedContractMethod<
[provider: AddressLike, units: BigNumberish, receiptHash: BytesLike, ],
[string],
'view'
>
mintWithReceipt: TypedContractMethod<
[provider: AddressLike, units: BigNumberish, receiptHash: BytesLike, signature: BytesLike, ],
[void],
'nonpayable'
>
name: TypedContractMethod<
[],
[string],
'view'
>
renounceRole: TypedContractMethod<
[role: BytesLike, callerConfirmation: AddressLike, ],
[void],
'nonpayable'
>
revokeRole: TypedContractMethod<
[role: BytesLike, account: AddressLike, ],
[void],
'nonpayable'
>
supportsInterface: TypedContractMethod<
[interfaceId: BytesLike, ],
[boolean],
'view'
>
symbol: TypedContractMethod<
[],
[string],
'view'
>
totalSupply: TypedContractMethod<
[],
[bigint],
'view'
>
transfer: TypedContractMethod<
[to: AddressLike, value: BigNumberish, ],
[boolean],
'nonpayable'
>
transferFrom: TypedContractMethod<
[from: AddressLike, to: AddressLike, value: BigNumberish, ],
[boolean],
'nonpayable'
>
getFunction<T extends ContractMethod = ContractMethod>(key: string | FunctionFragment): T;
getFunction(nameOrSignature: 'ATTESTOR_ROLE'): TypedContractMethod<
[],
[string],
'view'
>;
getFunction(nameOrSignature: 'COORDINATOR_ROLE'): TypedContractMethod<
[],
[string],
'view'
>;
getFunction(nameOrSignature: 'DEFAULT_ADMIN_ROLE'): TypedContractMethod<
[],
[string],
'view'
>;
getFunction(nameOrSignature: 'allowance'): TypedContractMethod<
[owner: AddressLike, spender: AddressLike, ],
[bigint],
'view'
>;
getFunction(nameOrSignature: 'approve'): TypedContractMethod<
[spender: AddressLike, value: BigNumberish, ],
[boolean],
'nonpayable'
>;
getFunction(nameOrSignature: 'balanceOf'): TypedContractMethod<
[account: AddressLike, ],
[bigint],
'view'
>;
getFunction(nameOrSignature: 'consumedReceipts'): TypedContractMethod<
[arg0: BytesLike, ],
[boolean],
'view'
>;
getFunction(nameOrSignature: 'decimals'): TypedContractMethod<
[],
[bigint],
'view'
>;
getFunction(nameOrSignature: 'getRoleAdmin'): TypedContractMethod<
[role: BytesLike, ],
[string],
'view'
>;
getFunction(nameOrSignature: 'grantRole'): TypedContractMethod<
[role: BytesLike, account: AddressLike, ],
[void],
'nonpayable'
>;
getFunction(nameOrSignature: 'hasRole'): TypedContractMethod<
[role: BytesLike, account: AddressLike, ],
[boolean],
'view'
>;
getFunction(nameOrSignature: 'mintDigest'): TypedContractMethod<
[provider: AddressLike, units: BigNumberish, receiptHash: BytesLike, ],
[string],
'view'
>;
getFunction(nameOrSignature: 'mintWithReceipt'): TypedContractMethod<
[provider: AddressLike, units: BigNumberish, receiptHash: BytesLike, signature: BytesLike, ],
[void],
'nonpayable'
>;
getFunction(nameOrSignature: 'name'): TypedContractMethod<
[],
[string],
'view'
>;
getFunction(nameOrSignature: 'renounceRole'): TypedContractMethod<
[role: BytesLike, callerConfirmation: AddressLike, ],
[void],
'nonpayable'
>;
getFunction(nameOrSignature: 'revokeRole'): TypedContractMethod<
[role: BytesLike, account: AddressLike, ],
[void],
'nonpayable'
>;
getFunction(nameOrSignature: 'supportsInterface'): TypedContractMethod<
[interfaceId: BytesLike, ],
[boolean],
'view'
>;
getFunction(nameOrSignature: 'symbol'): TypedContractMethod<
[],
[string],
'view'
>;
getFunction(nameOrSignature: 'totalSupply'): TypedContractMethod<
[],
[bigint],
'view'
>;
getFunction(nameOrSignature: 'transfer'): TypedContractMethod<
[to: AddressLike, value: BigNumberish, ],
[boolean],
'nonpayable'
>;
getFunction(nameOrSignature: 'transferFrom'): TypedContractMethod<
[from: AddressLike, to: AddressLike, value: BigNumberish, ],
[boolean],
'nonpayable'
>;
getEvent(key: 'Approval'): TypedContractEvent<ApprovalEvent.InputTuple, ApprovalEvent.OutputTuple, ApprovalEvent.OutputObject>;
getEvent(key: 'ReceiptConsumed'): TypedContractEvent<ReceiptConsumedEvent.InputTuple, ReceiptConsumedEvent.OutputTuple, ReceiptConsumedEvent.OutputObject>;
getEvent(key: 'RoleAdminChanged'): TypedContractEvent<RoleAdminChangedEvent.InputTuple, RoleAdminChangedEvent.OutputTuple, RoleAdminChangedEvent.OutputObject>;
getEvent(key: 'RoleGranted'): TypedContractEvent<RoleGrantedEvent.InputTuple, RoleGrantedEvent.OutputTuple, RoleGrantedEvent.OutputObject>;
getEvent(key: 'RoleRevoked'): TypedContractEvent<RoleRevokedEvent.InputTuple, RoleRevokedEvent.OutputTuple, RoleRevokedEvent.OutputObject>;
getEvent(key: 'Transfer'): TypedContractEvent<TransferEvent.InputTuple, TransferEvent.OutputTuple, TransferEvent.OutputObject>;
filters: {
'Approval(address,address,uint256)': TypedContractEvent<ApprovalEvent.InputTuple, ApprovalEvent.OutputTuple, ApprovalEvent.OutputObject>;
Approval: TypedContractEvent<ApprovalEvent.InputTuple, ApprovalEvent.OutputTuple, ApprovalEvent.OutputObject>;
'ReceiptConsumed(bytes32,address,uint256,address)': TypedContractEvent<ReceiptConsumedEvent.InputTuple, ReceiptConsumedEvent.OutputTuple, ReceiptConsumedEvent.OutputObject>;
ReceiptConsumed: TypedContractEvent<ReceiptConsumedEvent.InputTuple, ReceiptConsumedEvent.OutputTuple, ReceiptConsumedEvent.OutputObject>;
'RoleAdminChanged(bytes32,bytes32,bytes32)': TypedContractEvent<RoleAdminChangedEvent.InputTuple, RoleAdminChangedEvent.OutputTuple, RoleAdminChangedEvent.OutputObject>;
RoleAdminChanged: TypedContractEvent<RoleAdminChangedEvent.InputTuple, RoleAdminChangedEvent.OutputTuple, RoleAdminChangedEvent.OutputObject>;
'RoleGranted(bytes32,address,address)': TypedContractEvent<RoleGrantedEvent.InputTuple, RoleGrantedEvent.OutputTuple, RoleGrantedEvent.OutputObject>;
RoleGranted: TypedContractEvent<RoleGrantedEvent.InputTuple, RoleGrantedEvent.OutputTuple, RoleGrantedEvent.OutputObject>;
'RoleRevoked(bytes32,address,address)': TypedContractEvent<RoleRevokedEvent.InputTuple, RoleRevokedEvent.OutputTuple, RoleRevokedEvent.OutputObject>;
RoleRevoked: TypedContractEvent<RoleRevokedEvent.InputTuple, RoleRevokedEvent.OutputTuple, RoleRevokedEvent.OutputObject>;
'Transfer(address,address,uint256)': TypedContractEvent<TransferEvent.InputTuple, TransferEvent.OutputTuple, TransferEvent.OutputObject>;
Transfer: TypedContractEvent<TransferEvent.InputTuple, TransferEvent.OutputTuple, TransferEvent.OutputObject>;
};
}

View File

@@ -0,0 +1,329 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type { BaseContract, BigNumberish, BytesLike, FunctionFragment, Result, Interface, EventFragment, AddressLike, ContractRunner, ContractMethod, Listener } from "ethers"
import type { TypedContractEvent, TypedDeferredTopicFilter, TypedEventLog, TypedLogDescription, TypedListener, TypedContractMethod } from "./common.js"
export declare namespace AITokenRegistry {
export type ProviderInfoStruct = {active: boolean, collateral: BigNumberish}
export type ProviderInfoStructOutput = [active: boolean, collateral: bigint] & {active: boolean, collateral: bigint }
}
export interface AITokenRegistryInterface extends Interface {
getFunction(nameOrSignature: "COORDINATOR_ROLE" | "DEFAULT_ADMIN_ROLE" | "getRoleAdmin" | "grantRole" | "hasRole" | "providerInfo" | "providers" | "registerProvider" | "renounceRole" | "revokeRole" | "supportsInterface" | "updateProvider"): FunctionFragment;
getEvent(nameOrSignatureOrTopic: "ProviderRegistered" | "ProviderUpdated" | "RoleAdminChanged" | "RoleGranted" | "RoleRevoked"): EventFragment;
encodeFunctionData(functionFragment: 'COORDINATOR_ROLE', values?: undefined): string;
encodeFunctionData(functionFragment: 'DEFAULT_ADMIN_ROLE', values?: undefined): string;
encodeFunctionData(functionFragment: 'getRoleAdmin', values: [BytesLike]): string;
encodeFunctionData(functionFragment: 'grantRole', values: [BytesLike, AddressLike]): string;
encodeFunctionData(functionFragment: 'hasRole', values: [BytesLike, AddressLike]): string;
encodeFunctionData(functionFragment: 'providerInfo', values: [AddressLike]): string;
encodeFunctionData(functionFragment: 'providers', values: [AddressLike]): string;
encodeFunctionData(functionFragment: 'registerProvider', values: [AddressLike, BigNumberish]): string;
encodeFunctionData(functionFragment: 'renounceRole', values: [BytesLike, AddressLike]): string;
encodeFunctionData(functionFragment: 'revokeRole', values: [BytesLike, AddressLike]): string;
encodeFunctionData(functionFragment: 'supportsInterface', values: [BytesLike]): string;
encodeFunctionData(functionFragment: 'updateProvider', values: [AddressLike, boolean, BigNumberish]): string;
decodeFunctionResult(functionFragment: 'COORDINATOR_ROLE', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'DEFAULT_ADMIN_ROLE', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'getRoleAdmin', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'grantRole', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'hasRole', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'providerInfo', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'providers', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'registerProvider', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'renounceRole', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'revokeRole', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'supportsInterface', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'updateProvider', data: BytesLike): Result;
}
export namespace ProviderRegisteredEvent {
export type InputTuple = [provider: AddressLike, collateral: BigNumberish];
export type OutputTuple = [provider: string, collateral: bigint];
export interface OutputObject {provider: string, collateral: bigint };
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>
export type Filter = TypedDeferredTopicFilter<Event>
export type Log = TypedEventLog<Event>
export type LogDescription = TypedLogDescription<Event>
}
export namespace ProviderUpdatedEvent {
export type InputTuple = [provider: AddressLike, active: boolean, collateral: BigNumberish];
export type OutputTuple = [provider: string, active: boolean, collateral: bigint];
export interface OutputObject {provider: string, active: boolean, collateral: bigint };
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>
export type Filter = TypedDeferredTopicFilter<Event>
export type Log = TypedEventLog<Event>
export type LogDescription = TypedLogDescription<Event>
}
export namespace RoleAdminChangedEvent {
export type InputTuple = [role: BytesLike, previousAdminRole: BytesLike, newAdminRole: BytesLike];
export type OutputTuple = [role: string, previousAdminRole: string, newAdminRole: string];
export interface OutputObject {role: string, previousAdminRole: string, newAdminRole: string };
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>
export type Filter = TypedDeferredTopicFilter<Event>
export type Log = TypedEventLog<Event>
export type LogDescription = TypedLogDescription<Event>
}
export namespace RoleGrantedEvent {
export type InputTuple = [role: BytesLike, account: AddressLike, sender: AddressLike];
export type OutputTuple = [role: string, account: string, sender: string];
export interface OutputObject {role: string, account: string, sender: string };
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>
export type Filter = TypedDeferredTopicFilter<Event>
export type Log = TypedEventLog<Event>
export type LogDescription = TypedLogDescription<Event>
}
export namespace RoleRevokedEvent {
export type InputTuple = [role: BytesLike, account: AddressLike, sender: AddressLike];
export type OutputTuple = [role: string, account: string, sender: string];
export interface OutputObject {role: string, account: string, sender: string };
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>
export type Filter = TypedDeferredTopicFilter<Event>
export type Log = TypedEventLog<Event>
export type LogDescription = TypedLogDescription<Event>
}
export interface AITokenRegistry extends BaseContract {
connect(runner?: ContractRunner | null): AITokenRegistry;
waitForDeployment(): Promise<this>;
interface: AITokenRegistryInterface;
queryFilter<TCEvent extends TypedContractEvent>(
event: TCEvent,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined,
): Promise<Array<TypedEventLog<TCEvent>>>
queryFilter<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
on<TCEvent extends TypedContractEvent>(event: TCEvent, listener: TypedListener<TCEvent>): Promise<this>
on<TCEvent extends TypedContractEvent>(filter: TypedDeferredTopicFilter<TCEvent>, listener: TypedListener<TCEvent>): Promise<this>
once<TCEvent extends TypedContractEvent>(event: TCEvent, listener: TypedListener<TCEvent>): Promise<this>
once<TCEvent extends TypedContractEvent>(filter: TypedDeferredTopicFilter<TCEvent>, listener: TypedListener<TCEvent>): Promise<this>
listeners<TCEvent extends TypedContractEvent>(
event: TCEvent
): Promise<Array<TypedListener<TCEvent>>>;
listeners(eventName?: string): Promise<Array<Listener>>
removeAllListeners<TCEvent extends TypedContractEvent>(event?: TCEvent): Promise<this>
COORDINATOR_ROLE: TypedContractMethod<
[],
[string],
'view'
>
DEFAULT_ADMIN_ROLE: TypedContractMethod<
[],
[string],
'view'
>
getRoleAdmin: TypedContractMethod<
[role: BytesLike, ],
[string],
'view'
>
grantRole: TypedContractMethod<
[role: BytesLike, account: AddressLike, ],
[void],
'nonpayable'
>
hasRole: TypedContractMethod<
[role: BytesLike, account: AddressLike, ],
[boolean],
'view'
>
providerInfo: TypedContractMethod<
[provider: AddressLike, ],
[AITokenRegistry.ProviderInfoStructOutput],
'view'
>
providers: TypedContractMethod<
[arg0: AddressLike, ],
[[boolean, bigint] & {active: boolean, collateral: bigint }],
'view'
>
registerProvider: TypedContractMethod<
[provider: AddressLike, collateral: BigNumberish, ],
[void],
'nonpayable'
>
renounceRole: TypedContractMethod<
[role: BytesLike, callerConfirmation: AddressLike, ],
[void],
'nonpayable'
>
revokeRole: TypedContractMethod<
[role: BytesLike, account: AddressLike, ],
[void],
'nonpayable'
>
supportsInterface: TypedContractMethod<
[interfaceId: BytesLike, ],
[boolean],
'view'
>
updateProvider: TypedContractMethod<
[provider: AddressLike, active: boolean, collateral: BigNumberish, ],
[void],
'nonpayable'
>
getFunction<T extends ContractMethod = ContractMethod>(key: string | FunctionFragment): T;
getFunction(nameOrSignature: 'COORDINATOR_ROLE'): TypedContractMethod<
[],
[string],
'view'
>;
getFunction(nameOrSignature: 'DEFAULT_ADMIN_ROLE'): TypedContractMethod<
[],
[string],
'view'
>;
getFunction(nameOrSignature: 'getRoleAdmin'): TypedContractMethod<
[role: BytesLike, ],
[string],
'view'
>;
getFunction(nameOrSignature: 'grantRole'): TypedContractMethod<
[role: BytesLike, account: AddressLike, ],
[void],
'nonpayable'
>;
getFunction(nameOrSignature: 'hasRole'): TypedContractMethod<
[role: BytesLike, account: AddressLike, ],
[boolean],
'view'
>;
getFunction(nameOrSignature: 'providerInfo'): TypedContractMethod<
[provider: AddressLike, ],
[AITokenRegistry.ProviderInfoStructOutput],
'view'
>;
getFunction(nameOrSignature: 'providers'): TypedContractMethod<
[arg0: AddressLike, ],
[[boolean, bigint] & {active: boolean, collateral: bigint }],
'view'
>;
getFunction(nameOrSignature: 'registerProvider'): TypedContractMethod<
[provider: AddressLike, collateral: BigNumberish, ],
[void],
'nonpayable'
>;
getFunction(nameOrSignature: 'renounceRole'): TypedContractMethod<
[role: BytesLike, callerConfirmation: AddressLike, ],
[void],
'nonpayable'
>;
getFunction(nameOrSignature: 'revokeRole'): TypedContractMethod<
[role: BytesLike, account: AddressLike, ],
[void],
'nonpayable'
>;
getFunction(nameOrSignature: 'supportsInterface'): TypedContractMethod<
[interfaceId: BytesLike, ],
[boolean],
'view'
>;
getFunction(nameOrSignature: 'updateProvider'): TypedContractMethod<
[provider: AddressLike, active: boolean, collateral: BigNumberish, ],
[void],
'nonpayable'
>;
getEvent(key: 'ProviderRegistered'): TypedContractEvent<ProviderRegisteredEvent.InputTuple, ProviderRegisteredEvent.OutputTuple, ProviderRegisteredEvent.OutputObject>;
getEvent(key: 'ProviderUpdated'): TypedContractEvent<ProviderUpdatedEvent.InputTuple, ProviderUpdatedEvent.OutputTuple, ProviderUpdatedEvent.OutputObject>;
getEvent(key: 'RoleAdminChanged'): TypedContractEvent<RoleAdminChangedEvent.InputTuple, RoleAdminChangedEvent.OutputTuple, RoleAdminChangedEvent.OutputObject>;
getEvent(key: 'RoleGranted'): TypedContractEvent<RoleGrantedEvent.InputTuple, RoleGrantedEvent.OutputTuple, RoleGrantedEvent.OutputObject>;
getEvent(key: 'RoleRevoked'): TypedContractEvent<RoleRevokedEvent.InputTuple, RoleRevokedEvent.OutputTuple, RoleRevokedEvent.OutputObject>;
filters: {
'ProviderRegistered(address,uint256)': TypedContractEvent<ProviderRegisteredEvent.InputTuple, ProviderRegisteredEvent.OutputTuple, ProviderRegisteredEvent.OutputObject>;
ProviderRegistered: TypedContractEvent<ProviderRegisteredEvent.InputTuple, ProviderRegisteredEvent.OutputTuple, ProviderRegisteredEvent.OutputObject>;
'ProviderUpdated(address,bool,uint256)': TypedContractEvent<ProviderUpdatedEvent.InputTuple, ProviderUpdatedEvent.OutputTuple, ProviderUpdatedEvent.OutputObject>;
ProviderUpdated: TypedContractEvent<ProviderUpdatedEvent.InputTuple, ProviderUpdatedEvent.OutputTuple, ProviderUpdatedEvent.OutputObject>;
'RoleAdminChanged(bytes32,bytes32,bytes32)': TypedContractEvent<RoleAdminChangedEvent.InputTuple, RoleAdminChangedEvent.OutputTuple, RoleAdminChangedEvent.OutputObject>;
RoleAdminChanged: TypedContractEvent<RoleAdminChangedEvent.InputTuple, RoleAdminChangedEvent.OutputTuple, RoleAdminChangedEvent.OutputObject>;
'RoleGranted(bytes32,address,address)': TypedContractEvent<RoleGrantedEvent.InputTuple, RoleGrantedEvent.OutputTuple, RoleGrantedEvent.OutputObject>;
RoleGranted: TypedContractEvent<RoleGrantedEvent.InputTuple, RoleGrantedEvent.OutputTuple, RoleGrantedEvent.OutputObject>;
'RoleRevoked(bytes32,address,address)': TypedContractEvent<RoleRevokedEvent.InputTuple, RoleRevokedEvent.OutputTuple, RoleRevokedEvent.OutputObject>;
RoleRevoked: TypedContractEvent<RoleRevokedEvent.InputTuple, RoleRevokedEvent.OutputTuple, RoleRevokedEvent.OutputObject>;
};
}

View File

@@ -0,0 +1,92 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type {
FunctionFragment,
Typed,
EventFragment,
ContractTransaction,
ContractTransactionResponse,
DeferredTopicFilter,
EventLog,
TransactionRequest,
LogDescription,
} from 'ethers'
export interface TypedDeferredTopicFilter<_TCEvent extends TypedContractEvent> extends DeferredTopicFilter {}
export interface TypedContractEvent<
InputTuple extends Array<any> = any,
OutputTuple extends Array<any> = any,
OutputObject = any,
> {
(...args: Partial<InputTuple>): TypedDeferredTopicFilter<TypedContractEvent<InputTuple, OutputTuple, OutputObject>>
name: string
fragment: EventFragment
getFragment(...args: Partial<InputTuple>): EventFragment
}
type __TypechainAOutputTuple<T> = T extends TypedContractEvent<infer _U, infer W> ? W : never
type __TypechainOutputObject<T> = T extends TypedContractEvent<infer _U, infer _W, infer V> ? V : never
export interface TypedEventLog<TCEvent extends TypedContractEvent> extends Omit<EventLog, 'args'> {
args: __TypechainAOutputTuple<TCEvent> & __TypechainOutputObject<TCEvent>
}
export interface TypedLogDescription<TCEvent extends TypedContractEvent> extends Omit<LogDescription, 'args'> {
args: __TypechainAOutputTuple<TCEvent> & __TypechainOutputObject<TCEvent>
}
export type TypedListener<TCEvent extends TypedContractEvent> = (
...listenerArg: [...__TypechainAOutputTuple<TCEvent>, TypedEventLog<TCEvent>, ...undefined[]]
) => void
export type MinEthersFactory<C, ARGS> = {
deploy(...a: ARGS[]): Promise<C>
}
export type GetContractTypeFromFactory<F> = F extends MinEthersFactory<infer C, any> ? C : never
export type GetARGsTypeFromFactory<F> = F extends MinEthersFactory<any, any> ? Parameters<F['deploy']> : never
export type StateMutability = 'nonpayable' | 'payable' | 'view'
export type BaseOverrides = Omit<TransactionRequest, 'to' | 'data'>
export type NonPayableOverrides = Omit<BaseOverrides, 'value' | 'blockTag' | 'enableCcipRead'>
export type PayableOverrides = Omit<BaseOverrides, 'blockTag' | 'enableCcipRead'>
export type ViewOverrides = Omit<TransactionRequest, 'to' | 'data'>
export type Overrides<S extends StateMutability> = S extends 'nonpayable'
? NonPayableOverrides
: S extends 'payable'
? PayableOverrides
: ViewOverrides
export type PostfixOverrides<A extends Array<any>, S extends StateMutability> = A | [...A, Overrides<S>]
export type ContractMethodArgs<A extends Array<any>, S extends StateMutability> = PostfixOverrides<
{ [I in keyof A]-?: A[I] | Typed },
S
>
export type DefaultReturnType<R> = R extends Array<any> ? R[0] : R
// export interface ContractMethod<A extends Array<any> = Array<any>, R = any, D extends R | ContractTransactionResponse = R | ContractTransactionResponse> {
export interface TypedContractMethod<
A extends Array<any> = Array<any>,
R = any,
S extends StateMutability = 'payable',
> {
(...args: ContractMethodArgs<A, S>): S extends 'view'
? Promise<DefaultReturnType<R>>
: Promise<ContractTransactionResponse>
name: string
fragment: FunctionFragment
getFragment(...args: ContractMethodArgs<A, S>): FunctionFragment
populateTransaction(...args: ContractMethodArgs<A, S>): Promise<ContractTransaction>
staticCall(...args: ContractMethodArgs<A, 'view'>): Promise<DefaultReturnType<R>>
send(...args: ContractMethodArgs<A, S>): Promise<ContractTransactionResponse>
estimateGas(...args: ContractMethodArgs<A, S>): Promise<bigint>
staticCallResult(...args: ContractMethodArgs<A, 'view'>): Promise<R>
}

View File

@@ -0,0 +1,450 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type { Addressable } from "ethers";
import { Contract, ContractFactory, ContractTransactionResponse, Interface } from "ethers"
import type { Signer, AddressLike, ContractDeployTransaction, ContractRunner } from "ethers"
import type { NonPayableOverrides } from "../common.js"
import type { AITokenRegistry, AITokenRegistryInterface } from "../AITokenRegistry.js";
const _abi = [
{
"inputs": [
{
"internalType": "address",
"name": "admin",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "AccessControlBadConfirmation",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "bytes32",
"name": "neededRole",
"type": "bytes32"
}
],
"name": "AccessControlUnauthorizedAccount",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "provider",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "collateral",
"type": "uint256"
}
],
"name": "ProviderRegistered",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "provider",
"type": "address"
},
{
"indexed": false,
"internalType": "bool",
"name": "active",
"type": "bool"
},
{
"indexed": false,
"internalType": "uint256",
"name": "collateral",
"type": "uint256"
}
],
"name": "ProviderUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "previousAdminRole",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "newAdminRole",
"type": "bytes32"
}
],
"name": "RoleAdminChanged",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "RoleGranted",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "RoleRevoked",
"type": "event"
},
{
"inputs": [],
"name": "COORDINATOR_ROLE",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "DEFAULT_ADMIN_ROLE",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
}
],
"name": "getRoleAdmin",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "grantRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "hasRole",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "provider",
"type": "address"
}
],
"name": "providerInfo",
"outputs": [
{
"components": [
{
"internalType": "bool",
"name": "active",
"type": "bool"
},
{
"internalType": "uint256",
"name": "collateral",
"type": "uint256"
}
],
"internalType": "struct AITokenRegistry.ProviderInfo",
"name": "",
"type": "tuple"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "providers",
"outputs": [
{
"internalType": "bool",
"name": "active",
"type": "bool"
},
{
"internalType": "uint256",
"name": "collateral",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "provider",
"type": "address"
},
{
"internalType": "uint256",
"name": "collateral",
"type": "uint256"
}
],
"name": "registerProvider",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"internalType": "address",
"name": "callerConfirmation",
"type": "address"
}
],
"name": "renounceRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "revokeRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes4",
"name": "interfaceId",
"type": "bytes4"
}
],
"name": "supportsInterface",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "provider",
"type": "address"
},
{
"internalType": "bool",
"name": "active",
"type": "bool"
},
{
"internalType": "uint256",
"name": "collateral",
"type": "uint256"
}
],
"name": "updateProvider",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
] as const;
const _bytecode = "0x608060405234801561000f575f80fd5b506040516109a13803806109a183398101604081905261002e916100e8565b6100385f8261003f565b5050610115565b5f828152602081815260408083206001600160a01b038516845290915281205460ff166100df575f838152602081815260408083206001600160a01b03861684529091529020805460ff191660011790556100973390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45060016100e2565b505f5b92915050565b5f602082840312156100f8575f80fd5b81516001600160a01b038116811461010e575f80fd5b9392505050565b61087f806101225f395ff3fe608060405234801561000f575f80fd5b50600436106100b1575f3560e01c80633ae259161161006e5780633ae259161461018b5780636b366cb51461020057806391d1485414610227578063a217fddf1461023a578063d119056514610241578063d547741f14610254575f80fd5b806301ffc9a7146100b55780630787bc27146100dd5780631af431a714610120578063248a9ca3146101355780632f2ff15d1461016557806336568abe14610178575b5f80fd5b6100c86100c336600461073e565b610267565b60405190151581526020015b60405180910390f35b6101096100eb366004610787565b600160208190525f9182526040909120805491015460ff9091169082565b6040805192151583526020830191909152016100d4565b61013361012e3660046107a0565b61029d565b005b6101576101433660046107c8565b5f9081526020819052604090206001015490565b6040519081526020016100d4565b6101336101733660046107df565b6103e9565b6101336101863660046107df565b610413565b6101e3610199366004610787565b604080518082019091525f8082526020820152506001600160a01b03165f908152600160208181526040928390208351808501909452805460ff1615158452909101549082015290565b6040805182511515815260209283015192810192909252016100d4565b6101577f2e8b98eef02e8df3bd27d1270ded3bea3d14db99c5234c7b14001a7fff957bcc81565b6100c86102353660046107df565b61044b565b6101575f81565b61013361024f366004610809565b610473565b6101336102623660046107df565b6105d8565b5f6001600160e01b03198216637965db0b60e01b148061029757506301ffc9a760e01b6001600160e01b03198316145b92915050565b7f2e8b98eef02e8df3bd27d1270ded3bea3d14db99c5234c7b14001a7fff957bcc6102c7816105fc565b6001600160a01b0383166103155760405162461bcd60e51b815260206004820152601060248201526f34b73b30b634b210383937bb34b232b960811b60448201526064015b60405180910390fd5b6001600160a01b0383165f9081526001602052604090205460ff16156103725760405162461bcd60e51b8152602060048201526012602482015271185b1c9958591e481c9959da5cdd195c995960721b604482015260640161030c565b604080518082018252600180825260208083018681526001600160a01b0388165f8181528484528690209451855460ff19169015151785559051939092019290925591518481527f90c9734131c1e4fb36cde2d71e6feb93fb258f71be8a85411c173d25e1516e80910160405180910390a2505050565b5f82815260208190526040902060010154610403816105fc565b61040d8383610609565b50505050565b6001600160a01b038116331461043c5760405163334bd91960e11b815260040160405180910390fd5b6104468282610698565b505050565b5f918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b7f2e8b98eef02e8df3bd27d1270ded3bea3d14db99c5234c7b14001a7fff957bcc61049d816105fc565b6001600160a01b0384166104e65760405162461bcd60e51b815260206004820152601060248201526f34b73b30b634b210383937bb34b232b960811b604482015260640161030c565b6001600160a01b0384165f9081526001602052604090205460ff16806105095750825b6105555760405162461bcd60e51b815260206004820152601760248201527f70726f7669646572206e6f742072656769737465726564000000000000000000604482015260640161030c565b60408051808201825284151580825260208083018681526001600160a01b0389165f8181526001808552908790209551865460ff1916901515178655915194909101939093558351918252810185905290917fe226f4be7d881611b5a3ddc83f2e771728014b8012359a29890cd3d670c43dc8910160405180910390a250505050565b5f828152602081905260409020600101546105f2816105fc565b61040d8383610698565b6106068133610701565b50565b5f610614838361044b565b610691575f838152602081815260408083206001600160a01b03861684529091529020805460ff191660011790556106493390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4506001610297565b505f610297565b5f6106a3838361044b565b15610691575f838152602081815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a4506001610297565b61070b828261044b565b61073a5760405163e2517d3f60e01b81526001600160a01b03821660048201526024810183905260440161030c565b5050565b5f6020828403121561074e575f80fd5b81356001600160e01b031981168114610765575f80fd5b9392505050565b80356001600160a01b0381168114610782575f80fd5b919050565b5f60208284031215610797575f80fd5b6107658261076c565b5f80604083850312156107b1575f80fd5b6107ba8361076c565b946020939093013593505050565b5f602082840312156107d8575f80fd5b5035919050565b5f80604083850312156107f0575f80fd5b823591506108006020840161076c565b90509250929050565b5f805f6060848603121561081b575f80fd5b6108248461076c565b925060208401358015158114610838575f80fd5b92959294505050604091909101359056fea26469706673582212201777f6e8fbdbbc1162afca135af6f0ea80738b2c91d95d3ba599ee9b7f5111c264736f6c63430008190033";
type AITokenRegistryConstructorParams = [signer?: Signer] | ConstructorParameters<typeof ContractFactory>;
const isSuperArgs = (xs: AITokenRegistryConstructorParams): xs is ConstructorParameters<typeof ContractFactory> =>
xs.length > 1
export class AITokenRegistry__factory extends ContractFactory {
constructor(...args: AITokenRegistryConstructorParams) {
if (isSuperArgs(args)) {
super(...args);
} else {
super(_abi, _bytecode, args[0]);
}
}
override getDeployTransaction(admin: AddressLike, overrides?: NonPayableOverrides & { from?: string }): Promise<ContractDeployTransaction> {
return super.getDeployTransaction(admin, overrides || {});
};
override deploy(admin: AddressLike, overrides?: NonPayableOverrides & { from?: string }) {
return super.deploy(admin, overrides || {}) as Promise<AITokenRegistry & {
deploymentTransaction(): ContractTransactionResponse;
}>;
}
override connect(runner: ContractRunner | null): AITokenRegistry__factory {
return super.connect(runner) as AITokenRegistry__factory;
}
static readonly bytecode = _bytecode;
static readonly abi = _abi;
static createInterface(): AITokenRegistryInterface {
return new Interface(_abi) as AITokenRegistryInterface;
}
override attach(address: string | Addressable): AITokenRegistry {
return super.attach(address) as AITokenRegistry;
}
static connect(address: string, runner?: ContractRunner | null): AITokenRegistry {
return new Contract(address, _abi, runner) as unknown as AITokenRegistry;
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,5 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
export { AIToken__factory } from './AIToken__factory.js';
export { AITokenRegistry__factory } from './AITokenRegistry__factory.js';

View File

@@ -0,0 +1,51 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import { ethers } from 'ethers'
import { DeployContractOptions, FactoryOptions, HardhatEthersHelpers as HardhatEthersHelpersBase} from "@nomicfoundation/hardhat-ethers/types";
import * as Contracts from "./index.js";
declare module "@nomicfoundation/hardhat-ethers/types" {
interface HardhatEthersHelpers extends HardhatEthersHelpersBase {
getContractFactory(name: 'AIToken', signerOrOptions?: ethers.Signer | FactoryOptions): Promise<Contracts.AIToken__factory>
getContractFactory(name: 'AITokenRegistry', signerOrOptions?: ethers.Signer | FactoryOptions): Promise<Contracts.AITokenRegistry__factory>
getContractAt(name: 'AIToken', address: string | ethers.Addressable, signer?: ethers.Signer): Promise<Contracts.AIToken>
getContractAt(name: 'AITokenRegistry', address: string | ethers.Addressable, signer?: ethers.Signer): Promise<Contracts.AITokenRegistry>
deployContract(name: 'AIToken', signerOrOptions?: ethers.Signer | DeployContractOptions): Promise<Contracts.AIToken>
deployContract(name: 'AITokenRegistry', signerOrOptions?: ethers.Signer | DeployContractOptions): Promise<Contracts.AITokenRegistry>
deployContract(name: 'AIToken', args: any[], signerOrOptions?: ethers.Signer | DeployContractOptions): Promise<Contracts.AIToken>
deployContract(name: 'AITokenRegistry', args: any[], signerOrOptions?: ethers.Signer | DeployContractOptions): Promise<Contracts.AITokenRegistry>
// default types
getContractFactory(
name: string,
signerOrOptions?: ethers.Signer | FactoryOptions
): Promise<ethers.ContractFactory>;
getContractFactory(
abi: any[],
bytecode: ethers.BytesLike,
signer?: ethers.Signer
): Promise<ethers.ContractFactory>;
getContractAt(
nameOrAbi: string | any[],
address: string | ethers.Addressable,
signer?: ethers.Signer
): Promise<ethers.Contract>;
deployContract(
name: string,
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<ethers.Contract>;
deployContract(
name: string,
args: any[],
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<ethers.Contract>;
}
}

View File

@@ -0,0 +1,8 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
export type { AIToken } from './AIToken.js';
export type { AITokenRegistry } from './AITokenRegistry.js';
export * as factories from './factories/index.js';
export { AIToken__factory } from './factories/AIToken__factory.js';
export { AITokenRegistry__factory } from './factories/AITokenRegistry__factory.js';