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

@@ -58,6 +58,10 @@ jobs:
source venv/bin/activate
pip install -q --upgrade pip setuptools wheel
if [[ "${{ matrix.package.name }}" == "aitbc-sdk" ]]; then
pip install -q -e "$WORKSPACE/repo/packages/py/aitbc-crypto"
fi
# Install dependencies
if [[ -f "pyproject.toml" ]]; then
pip install -q -e ".[dev]" 2>/dev/null || pip install -q -e .
@@ -137,17 +141,7 @@ jobs:
node --version
npm --version
npm install --legacy-peer-deps 2>/dev/null || npm install
# Fix missing Hardhat dependencies for aitbc-token
if [[ "${{ matrix.package.name }}" == "aitbc-token" ]]; then
echo "Installing missing Hardhat dependencies..."
npm install --save-dev "@nomicfoundation/hardhat-ignition@^0.15.16" "@nomicfoundation/ignition-core@^0.15.15" 2>/dev/null || true
# Fix formatting issues
echo "Fixing formatting issues..."
npm run format 2>/dev/null || echo "⚠️ Format fix failed"
fi
npm install --legacy-peer-deps
# Build
npm run build

View File

@@ -52,7 +52,7 @@ jobs:
echo "Node: $(node --version), npm: $(npm --version)"
# Install
npm install --legacy-peer-deps 2>/dev/null || npm install
npm install --legacy-peer-deps
# Compile
if [[ -f "hardhat.config.js" ]] || [[ -f "hardhat.config.ts" ]]; then
@@ -116,7 +116,7 @@ jobs:
if [[ -d "$project" ]] && [[ -f "$project/package.json" ]]; then
echo "=== Linting $project ==="
cd "$project"
npm install --legacy-peer-deps 2>/dev/null || npm install
npm install --legacy-peer-deps
if node -e "const pkg=require('./package.json'); process.exit(pkg.scripts && pkg.scripts.lint ? 0 : 1)"; then
npm run lint

View File

@@ -187,7 +187,7 @@ def main():
elif isinstance(tx.tx_metadata, str):
try:
data = json.loads(tx.tx_metadata).get("payload", "")
except:
except json.JSONDecodeError:
pass
elif hasattr(tx, "payload") and tx.payload:
if isinstance(tx.payload, dict):

View File

@@ -12,12 +12,10 @@ dependencies = [
"requests>=2.31.0",
"pydantic>=2.5.0",
"httpx>=0.25.0",
"pynacl>=1.5.0"
"pynacl>=1.5.0",
"aitbc-crypto>=0.1.0"
]
[tool.poetry.dependencies]
aitbc-crypto = { path = "../aitbc-crypto", develop = true }
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

View File

@@ -2,7 +2,7 @@ from __future__ import annotations
import time
from dataclasses import dataclass, field
from typing import Any, Dict, Iterable, Iterator, List, Optional
from typing import Any, Dict, Iterable, Iterator, List, Optional, cast
import httpx
import base64
@@ -94,7 +94,10 @@ class CoordinatorReceiptClient:
resp = self._request("GET", f"/v1/jobs/{job_id}/receipt", allow_404=True)
if resp is None:
return None
return resp.json() # type: ignore[return-value]
payload = resp.json()
if not isinstance(payload, dict):
raise ValueError("Expected receipt payload to be a JSON object")
return cast(Dict[str, Any], payload)
def fetch_history(self, job_id: str) -> List[Dict[str, Any]]:
return list(self.iter_receipts(job_id=job_id))

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,10 +1,10 @@
// 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
@@ -18,7 +18,12 @@ contract AIToken is ERC20, AccessControl {
/// @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);
@@ -50,12 +55,22 @@ contract AIToken is ERC20, AccessControl {
}
/// @notice Helper to compute the signed digest required for minting
function mintDigest(address provider, uint256 units, bytes32 receiptHash) external view returns (bytes32) {
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));
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,7 +1,7 @@
// 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
@@ -16,16 +16,26 @@ contract AITokenRegistry is AccessControl {
mapping(address => ProviderInfo) public providers;
event ProviderRegistered(address indexed provider, uint256 collateral);
event ProviderUpdated(address indexed provider, bool active, uint256 collateral);
event ProviderUpdated(
address indexed provider,
bool active,
uint256 collateral
);
constructor(address admin) {
_grantRole(DEFAULT_ADMIN_ROLE, admin);
}
function registerProvider(address provider, uint256 collateral) external onlyRole(COORDINATOR_ROLE) {
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});
providers[provider] = ProviderInfo({
active: true,
collateral: collateral
});
emit ProviderRegistered(provider, collateral);
}
@@ -36,11 +46,16 @@ contract AITokenRegistry is AccessControl {
) 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});
providers[provider] = ProviderInfo({
active: active,
collateral: collateral
});
emit ProviderUpdated(provider, active, collateral);
}
function providerInfo(address provider) external view returns (ProviderInfo memory) {
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';