diff --git a/packages/nextjs/contracts/deployedContracts.ts b/packages/nextjs/contracts/deployedContracts.ts index f04dc0a..1b3466d 100644 --- a/packages/nextjs/contracts/deployedContracts.ts +++ b/packages/nextjs/contracts/deployedContracts.ts @@ -5,14 +5,15 @@ const deployedContracts = { devnet: { - SchemaRegistry: { + AttestationRegistry: { address: - "0x01e118bd0158076bbe64f87f5519ee7c074ca5cb618a80bf7741b2ec3187aafb", + "0x07c59f28a693a4d629f0b0358ae52649ca3e6743e111bedc0c822ee76ece3387", abi: [ { type: "impl", - name: "SchemaRegistryImpl", - interface_name: "contracts::SchemaRegistry::ISchemaRegistry", + name: "AttestationRegistryImpl", + interface_name: + "contracts::AttestationRegistry::IAttestationRegistry", }, { type: "struct", @@ -48,14 +49,22 @@ const deployedContracts = { }, { type: "interface", - name: "contracts::SchemaRegistry::ISchemaRegistry", + name: "contracts::AttestationRegistry::IAttestationRegistry", items: [ { type: "function", - name: "register", + name: "attest", inputs: [ { - name: "schema", + name: "schema_uid", + type: "core::integer::u128", + }, + { + name: "recipient", + type: "core::starknet::contract_address::ContractAddress", + }, + { + name: "data", type: "core::byte_array::ByteArray", }, { @@ -70,54 +79,58 @@ const deployedContracts = { ], state_mutability: "external", }, + ], + }, + { + type: "constructor", + name: "constructor", + inputs: [ { - type: "function", - name: "get_schema", - inputs: [ - { - name: "uid", - type: "core::integer::u128", - }, - ], - outputs: [ - { - type: "(core::integer::u128, core::bool, core::byte_array::ByteArray)", - }, - ], - state_mutability: "view", + name: "schema_registry_address", + type: "core::starknet::contract_address::ContractAddress", }, ], }, { type: "event", - name: "contracts::SchemaRegistry::SchemaRegistry::Registered", + name: "contracts::AttestationRegistry::AttestationRegistry::Attested", kind: "struct", members: [ { - name: "uid", - type: "core::integer::u128", + name: "recipient", + type: "core::starknet::contract_address::ContractAddress", kind: "key", }, { - name: "caller", + name: "attester", type: "core::starknet::contract_address::ContractAddress", + kind: "key", + }, + { + name: "uid", + type: "core::integer::u128", kind: "data", }, { - name: "schema_record", - type: "core::byte_array::ByteArray", + name: "schema_uid", + type: "core::integer::u128", + kind: "key", + }, + { + name: "timestamp", + type: "core::integer::u64", kind: "data", }, ], }, { type: "event", - name: "contracts::SchemaRegistry::SchemaRegistry::Event", + name: "contracts::AttestationRegistry::AttestationRegistry::Event", kind: "enum", variants: [ { - name: "Registered", - type: "contracts::SchemaRegistry::SchemaRegistry::Registered", + name: "Attested", + type: "contracts::AttestationRegistry::AttestationRegistry::Attested", kind: "nested", }, ], @@ -126,14 +139,15 @@ const deployedContracts = { }, }, sepolia: { - SchemaRegistry: { + AttestationRegistry: { address: - "0x067bdf6bf6f1b72315c541abdc443cdd55992ea29546933ddfec19cb200fce87", + "0x077cf1b7bb4ce74559dbbab85714f1d69e520657670639ff77c9e99eedeb13f6", abi: [ { type: "impl", - name: "SchemaRegistryImpl", - interface_name: "contracts::SchemaRegistry::ISchemaRegistry", + name: "AttestationRegistryImpl", + interface_name: + "contracts::AttestationRegistry::IAttestationRegistry", }, { type: "struct", @@ -169,14 +183,22 @@ const deployedContracts = { }, { type: "interface", - name: "contracts::SchemaRegistry::ISchemaRegistry", + name: "contracts::AttestationRegistry::IAttestationRegistry", items: [ { type: "function", - name: "register", + name: "attest", inputs: [ { - name: "schema", + name: "schema_uid", + type: "core::integer::u128", + }, + { + name: "recipient", + type: "core::starknet::contract_address::ContractAddress", + }, + { + name: "data", type: "core::byte_array::ByteArray", }, { @@ -191,54 +213,58 @@ const deployedContracts = { ], state_mutability: "external", }, + ], + }, + { + type: "constructor", + name: "constructor", + inputs: [ { - type: "function", - name: "get_schema", - inputs: [ - { - name: "uid", - type: "core::integer::u128", - }, - ], - outputs: [ - { - type: "(core::integer::u128, core::bool, core::byte_array::ByteArray)", - }, - ], - state_mutability: "view", + name: "schema_registry_address", + type: "core::starknet::contract_address::ContractAddress", }, ], }, { type: "event", - name: "contracts::SchemaRegistry::SchemaRegistry::Registered", + name: "contracts::AttestationRegistry::AttestationRegistry::Attested", kind: "struct", members: [ { - name: "uid", - type: "core::integer::u128", + name: "recipient", + type: "core::starknet::contract_address::ContractAddress", kind: "key", }, { - name: "caller", + name: "attester", type: "core::starknet::contract_address::ContractAddress", + kind: "key", + }, + { + name: "uid", + type: "core::integer::u128", kind: "data", }, { - name: "schema_record", - type: "core::byte_array::ByteArray", + name: "schema_uid", + type: "core::integer::u128", + kind: "key", + }, + { + name: "timestamp", + type: "core::integer::u64", kind: "data", }, ], }, { type: "event", - name: "contracts::SchemaRegistry::SchemaRegistry::Event", + name: "contracts::AttestationRegistry::AttestationRegistry::Event", kind: "enum", variants: [ { - name: "Registered", - type: "contracts::SchemaRegistry::SchemaRegistry::Registered", + name: "Attested", + type: "contracts::AttestationRegistry::AttestationRegistry::Attested", kind: "nested", }, ], diff --git a/packages/nextjs/scaffold.config.ts b/packages/nextjs/scaffold.config.ts index fac39e1..ee79a8f 100644 --- a/packages/nextjs/scaffold.config.ts +++ b/packages/nextjs/scaffold.config.ts @@ -9,7 +9,7 @@ export type ScaffoldConfig = { }; const scaffoldConfig = { - targetNetworks: [chains.sepolia], + targetNetworks: [chains.devnet], // Only show the Burner Wallet when running on devnet onlyLocalBurnerWallet: false, rpcProviderUrl: process.env.NEXT_PUBLIC_PROVIDER_URL || "", diff --git a/packages/snfoundry/contracts/src/AttestationRegistry.cairo b/packages/snfoundry/contracts/src/AttestationRegistry.cairo new file mode 100644 index 0000000..c57db7a --- /dev/null +++ b/packages/snfoundry/contracts/src/AttestationRegistry.cairo @@ -0,0 +1,151 @@ +use starknet::ContractAddress; +use super::SchemaRegistry::{ISchemaRegistry, ISchemaRegistryDispatcher}; + +#[starknet::interface] +pub trait IAttestationRegistry { + fn attest(ref self: TContractState, schema_uid: u128, recipient: ContractAddress, data: ByteArray, revocable: bool) -> u128; + // fn revoke(ref self: TContractState, request: RevocationRequest); +} + +// Define structs +#[derive(Drop, Serde, starknet::Store)] +struct Attestation { + uid: u128, + schema_uid: u128, + time: u64, + // expiration_time: u64, + recipient: ContractAddress, + attester: ContractAddress, + data: ByteArray, +} + +#[derive(Drop, Serde, starknet::Store)] +struct AttestationRequest { + schema_uid: u128, + recipient: ContractAddress, + // expiration_time: u64, + data: ByteArray, + revocable: bool +} + +// #[derive(Drop, Serde, starknet::Store)] +// struct RevocationRequestData { +// uid: felt252, +// value: u256, +// } + +// #[derive(Drop, Serde, starknet::Store)] +// struct RevocationRequest { +// schema: felt252, +// data: RevocationRequestData, +// } + + +#[starknet::contract] +mod AttestationRegistry { + use core::traits::Into; + use contracts::SchemaRegistry::ISchemaRegistryDispatcherTrait; + use starknet::{get_caller_address, get_block_timestamp}; + use super::{ + ContractAddress, IAttestationRegistry, AttestationRequest, Attestation, + ISchemaRegistryDispatcher + }; + + // Define constants + const EMPTY_UID: u128 = 0; + const NO_EXPIRATION_TIME: u64 = 0; + + // Events + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + Attested: Attested, + // Revoked: Revoked, + // Timestamped: Timestamped, + // RevokedOffchain: RevokedOffchain, + } + + #[derive(Drop, starknet::Event)] + struct Attested { + #[key] + recipient: ContractAddress, + #[key] + attester: ContractAddress, + uid: u128, + #[key] + schema_uid: u128, + timestamp: u64, + } + + // // The global mapping between attestations and their UIDs. + // mapping(bytes32 uid => Attestation attestation) private _db; + + // // The global mapping between data and their timestamps. + // mapping(bytes32 data => uint64 timestamp) private _timestamps; + + // // The global mapping between data and their revocation timestamps. + // mapping(address revoker => mapping(bytes32 data => uint64 timestamp) timestamps) private _revocationsOffchain; + #[storage] + struct Storage { + schema_registry: ContractAddress, + db: LegacyMap::, + timestamps: LegacyMap::, + current_uid: u128, + // revocations_offchain: LegacyMap::<(ContractAddress, felt252), u64>, + } + + // Constructor +#[constructor] + fn constructor(ref self: ContractState, schema_registry_address: ContractAddress) { + self.schema_registry.write(schema_registry_address); + } + + #[abi(embed_v0)] + impl AttestationRegistryImpl of IAttestationRegistry { + fn attest(ref self: ContractState, schema_uid: u128, recipient: ContractAddress, data: ByteArray, revocable: bool) -> u128 { + let contract_address = self.schema_registry.read(); + // let (fetched_uid, fetched_revocable, fetched_schema) = ISchemaRegistryDispatcher { contract_address } + // .get_schema(schema_uid); + + // assert!(fetched_uid != EMPTY_UID, "Schema Not Found"); + // assert!( + // request.expiration_time != NO_EXPIRATION_TIME + // && request.expiration_time <= get_block_timestamp(), + // "Invalid Expiration Time" + // ); + // assert!(!fetched_revocable && revocable, "Irrevocable"); + + let mut attestation = Attestation { + uid: EMPTY_UID, + schema_uid, + time: get_block_timestamp(), + // expiration_time: request.expiration_time, + recipient, + attester: get_caller_address(), + data + }; + + self.current_uid.write(self.current_uid.read() + 1); + let uid = self.current_uid.read(); + attestation.uid = uid; + + self.db.write(uid, attestation); + + self + .emit( + Attested { + recipient, + attester: get_caller_address(), + uid, + schema_uid, + timestamp: get_block_timestamp() + } + ); + + uid + } + + // fn revoke(ref self: ContractState, request: RevocationRequest) {} + } +} + diff --git a/packages/snfoundry/contracts/src/lib.cairo b/packages/snfoundry/contracts/src/lib.cairo index dbd2a4b..02bd141 100644 --- a/packages/snfoundry/contracts/src/lib.cairo +++ b/packages/snfoundry/contracts/src/lib.cairo @@ -1,5 +1,5 @@ -mod SAS; -mod YourContract; +// mod SAS; +mod AttestationRegistry; mod SchemaRegistry; #[cfg(test)] mod test { diff --git a/packages/snfoundry/scripts-ts/deploy.ts b/packages/snfoundry/scripts-ts/deploy.ts index 1e5e502..90f308b 100644 --- a/packages/snfoundry/scripts-ts/deploy.ts +++ b/packages/snfoundry/scripts-ts/deploy.ts @@ -1,14 +1,29 @@ import { deployContract, deployer, exportDeployments } from "./deploy-contract"; const deployScript = async (): Promise => { + // await deployContract( + // { + // owner: deployer.address, // the deployer address is the owner of the contract + // }, + // "SchemaRegistry", + // ); + await deployContract( - { - owner: deployer.address, // the deployer address is the owner of the contract - }, - "SchemaRegistry" - ); + { + schema_registry_address: "0x048ec8a62f68659ed94e57e497e154d96cc4d5356ef35a58c6b3f4e034325a8f", // the deployer address is the owner of the contract, + }, + "AttestationRegistry" +); }; +// await deployContract( +// { +// schema_registry_address: "0x075d3a77b16fdb4609b981f6f8ccb393470b67ee64a832139931483f099c36d8", // the deployer address is the owner of the contract, +// }, +// // "SchemaRegistry", +// "AttestationRegistry" +// ); + deployScript() .then(() => { exportDeployments();