Skip to content

Commit c532d8a

Browse files
authored
extension UI
Extension UI
2 parents 6a8c605 + 0f47ca7 commit c532d8a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+10125
-1521
lines changed

README.md

+63
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,66 @@ See [LICENSE](LICENSE) file for details.
128128
## Disclaimer
129129

130130
This platform is for educational purposes and responsible red teaming. Use your powers for good, and happy hacking!
131+
132+
## Development Setup
133+
134+
### Prerequisites
135+
- Node.js and npm (for extension development)
136+
- Scarb (Cairo package manager)
137+
- jq (JSON processor for scripts)
138+
139+
### Installation
140+
1. Install root dependencies:
141+
```bash
142+
npm install
143+
```
144+
145+
2. Install jq if not already installed:
146+
```bash
147+
# macOS
148+
brew install jq
149+
150+
# Ubuntu/Debian
151+
sudo apt-get install jq
152+
```
153+
154+
3. Set up the Git pre-commit hook:
155+
```bash
156+
# Make sure the Git hooks directory exists
157+
mkdir -p .git/hooks
158+
159+
# Copy the pre-commit hook
160+
cp scripts/pre-commit .git/hooks/
161+
chmod +x .git/hooks/pre-commit
162+
```
163+
164+
### ABI Synchronization
165+
The project maintains automatic synchronization between the Cairo contract ABIs and the TypeScript interfaces used in the extension. This is handled through a Git pre-commit hook that:
166+
167+
1. Builds the contracts using Scarb
168+
2. Extracts the ABIs from the contract class files using jq
169+
3. Updates the TypeScript ABI files in `extension/src/abis/`
170+
4. Verifies that all changes are committed
171+
172+
If you see an error about ABI files being out of sync during commit, simply add the updated ABI files to your commit.
173+
174+
### Manual ABI Sync
175+
To manually synchronize the ABIs:
176+
177+
```bash
178+
./scripts/sync-abis.sh
179+
```
180+
181+
## Project Structure
182+
183+
### Contracts
184+
- `contracts/` - Cairo smart contracts
185+
- `contracts/target/release/*.contract_class.json` - Compiled contract files containing ABIs
186+
187+
### Extension
188+
- `extension/` - Browser extension code
189+
- `extension/src/abis/` - TypeScript ABI definitions (auto-generated)
190+
191+
### Scripts
192+
- `scripts/` - Development and maintenance scripts
193+
- `scripts/sync-abis.ts` - ABI synchronization script

contracts/tests/test_contract.cairo

+106
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,36 @@ fn deploy_test_token(token_holder: ContractAddress) -> ContractAddress {
8282
address.into()
8383
}
8484

85+
fn deploy_registry_with_token(tee: ContractAddress) -> (ContractAddress, ContractAddress) {
86+
let token_contract = declare("ERC20").unwrap();
87+
let agent_contract = declare("Agent").unwrap();
88+
let registry_contract = declare("AgentRegistry").unwrap();
89+
90+
// Deploy token first
91+
let mut token_calldata = ArrayTrait::new();
92+
let name = ByteArray::from_string("Test Token");
93+
let symbol = ByteArray::from_string("TST");
94+
let initial_supply: u256 = 1000000;
95+
let recipient = starknet::get_contract_address();
96+
97+
name.serialize(ref token_calldata);
98+
symbol.serialize(ref token_calldata);
99+
initial_supply.serialize(ref token_calldata);
100+
recipient.serialize(ref token_calldata);
101+
102+
let (token_address, _) = token_contract.deploy(@token_calldata).unwrap();
103+
104+
// Deploy registry with token
105+
let mut registry_calldata = ArrayTrait::new();
106+
agent_contract.class_hash.serialize(ref registry_calldata);
107+
tee.serialize(ref registry_calldata);
108+
token_address.serialize(ref registry_calldata);
109+
110+
let (registry_address, _) = registry_contract.deploy(@registry_calldata).unwrap();
111+
112+
(registry_address, token_address)
113+
}
114+
85115
#[test]
86116
fn test_register_agent() {
87117
let setup = setup();
@@ -1015,3 +1045,79 @@ fn test_withdraw_after_drain() {
10151045
start_cheat_caller_address(agent_address, setup.creator);
10161046
agent.withdraw(); // Should succeed
10171047
}
1048+
1049+
#[test]
1050+
fn test_successful_agent_transfer() {
1051+
// Deploy registry with token
1052+
let tee = starknet::contract_address_const::<0x1>();
1053+
let (registry_address, token_address) = deploy_registry_with_token(tee);
1054+
let registry = IAgentRegistryDispatcher { contract_address: registry_address };
1055+
let token = IERC20Dispatcher { contract_address: token_address };
1056+
1057+
// Register an agent
1058+
registry.register_agent(
1059+
ByteArray::from_string("Test Agent"),
1060+
ByteArray::from_string("Test Prompt")
1061+
);
1062+
1063+
let agents = registry.get_agents();
1064+
let agent_address = *agents.at(0);
1065+
1066+
// Send some tokens to the agent
1067+
let agent_initial_balance: u256 = 100;
1068+
token.transfer(agent_address, agent_initial_balance);
1069+
1070+
// Verify agent received the tokens
1071+
let balance_before = token.balance_of(agent_address);
1072+
assert(balance_before == agent_initial_balance, 'Wrong initial balance');
1073+
1074+
// Create a new recipient address
1075+
let new_owner = starknet::contract_address_const::<0x123>();
1076+
1077+
// Start spoofing the TEE address for the transfer
1078+
starknet::testing::set_caller_address(tee);
1079+
1080+
// Transfer the agent to a new address
1081+
registry.transfer(agent_address, new_owner);
1082+
1083+
// Verify tokens were transferred to new owner
1084+
let balance_after_agent = token.balance_of(agent_address);
1085+
let balance_after_new_owner = token.balance_of(new_owner);
1086+
1087+
assert(balance_after_agent == 0, 'Agent should have 0 balance');
1088+
assert(balance_after_new_owner == agent_initial_balance, 'New owner wrong balance');
1089+
}
1090+
1091+
#[test]
1092+
fn test_get_token_address() {
1093+
let tee = starknet::contract_address_const::<0x1>();
1094+
let (registry_address, token_address) = deploy_registry_with_token(tee);
1095+
let registry = IAgentRegistryDispatcher { contract_address: registry_address };
1096+
1097+
let stored_token = registry.get_token();
1098+
assert(stored_token == token_address, 'Wrong token address');
1099+
}
1100+
1101+
#[test]
1102+
#[should_panic(expected: ('Only tee can transfer',))]
1103+
fn test_transfer_not_tee() {
1104+
let tee = starknet::contract_address_const::<0x1>();
1105+
let (registry_address, _) = deploy_registry_with_token(tee);
1106+
let registry = IAgentRegistryDispatcher { contract_address: registry_address };
1107+
1108+
// Register an agent
1109+
registry.register_agent(
1110+
ByteArray::from_string("Test Agent"),
1111+
ByteArray::from_string("Test Prompt")
1112+
);
1113+
1114+
let agents = registry.get_agents();
1115+
let agent_address = *agents.at(0);
1116+
1117+
// Try to transfer without being TEE
1118+
starknet::testing::set_caller_address(starknet::contract_address_const::<0x999>());
1119+
registry.transfer(
1120+
agent_address,
1121+
starknet::contract_address_const::<0x123>()
1122+
);
1123+
}

extension/.env.development

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
VITE_DEV_SERVER_URL=http://localhost:5173

extension/background.js

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
console.log('Background script initiated')
2+
3+
chrome.runtime.onInstalled.addListener(() => {
4+
console.log('onInstalled listener handler 11')
5+
// console.log('starknet', window.starknet_argentX)
6+
})

extension/manifest.json

+24-6
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,37 @@
55
"description": "Pay-to-tweet mechanism for interacting with AI agents on Twitter/X",
66
"permissions": [
77
"activeTab",
8-
"cookies"
8+
"tabs",
9+
"cookies",
10+
"scripting",
11+
"storage"
912
],
1013
"host_permissions": [
1114
"https://*.twitter.com/*"
1215
],
1316
"content_scripts": [
1417
{
15-
"matches": ["https://twitter.com/*", "https://x.com/*"],
16-
"css": ["assets/contentStyle.css"],
17-
"js": ["src/content-script/index.tsx"]
18+
"matches": [
19+
"https://twitter.com/*",
20+
"https://x.com/*"
21+
],
22+
"css": [
23+
"assets/contentStyle.css"
24+
],
25+
"js": [
26+
"src/content-script/index.tsx"
27+
],
28+
"run_at": "document_end",
29+
"all_frames": true
1830
}
1931
],
2032
"action": {
21-
"default_popup": "index.html"
33+
"default_popup": "index.html"
34+
},
35+
"background": {
36+
"service_worker": "background.js"
37+
},
38+
"content_security_policy": {
39+
"extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self'"
2240
}
23-
}
41+
}

0 commit comments

Comments
 (0)