Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,297 changes: 947 additions & 350 deletions contracts/src/lib.rs

Large diffs are not rendered by default.

177 changes: 37 additions & 140 deletions contracts/test_snapshots/test/test_deposit_withdraw.1.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
{
"generators": {
"address": 3,
"address": 4,
"nonce": 0
},
"auth": [
[],
[
[
"CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
"CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4",
{
"function": {
"contract_fn": {
"contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
"contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
"function_name": "initialize",
"args": [
{
"address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M"
"address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4"
},
{
"address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"
}
]
}
Expand All @@ -26,15 +29,15 @@
],
[
[
"CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
"CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
{
"function": {
"contract_fn": {
"contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
"contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
"function_name": "deposit",
"args": [
{
"address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
"address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M"
},
{
"i128": {
Expand All @@ -46,10 +49,10 @@
"u32": 60
},
{
"u32": 30
"u32": 0
},
{
"u32": 10
"u32": 0
}
]
}
Expand All @@ -63,133 +66,24 @@
[],
[
[
"CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
"CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
{
"function": {
"contract_fn": {
"contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
"function_name": "withdraw",
"args": [
{
"address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
},
{
"i128": {
"hi": 0,
"lo": 500
}
}
]
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
"key": "ledger_key_contract_instance",
"durability": "persistent"
}
},
"sub_invocations": []
}
]
],
[]
],
"ledger": {
"protocol_version": 22,
"sequence_number": 0,
"timestamp": 0,
"network_id": "0000000000000000000000000000000000000000000000000000000000000000",
"base_reserve": 0,
"min_persistent_entry_ttl": 4096,
"min_temp_entry_ttl": 16,
"max_entry_ttl": 6312000,
"ledger_entries": [
[
{
"contract_data": {
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
"key": {
"vec": [
{
"symbol": "Admin"
}
]
},
"durability": "persistent"
}
},
[
{
"last_modified_ledger_seq": 0,
"data": {
"contract_data": {
"ext": "v0",
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
"key": {
"vec": [
{
"symbol": "Admin"
}
]
},
"durability": "persistent",
"val": {
"address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M"
}
}
},
"ext": "v0"
},
4095
]
],
[
{
"contract_data": {
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
"key": {
"vec": [
{
"symbol": "UserBalance"
},
{
"address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
}
]
},
"durability": "persistent"
}
},
[
{
"last_modified_ledger_seq": 0,
"data": {
"contract_data": {
"ext": "v0",
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
"key": {
"vec": [
{
"symbol": "UserBalance"
},
{
"address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
}
]
},
"durability": "persistent",
"val": {
"i128": {
"hi": 0,
"lo": 500
}
}
}
},
"ext": "v0"
},
4095
]
],
[
{
"contract_data": {
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
"key": {
[
{
"last_modified_ledger_seq": 0,
"data": {
"contract_data": {
"ext": "v0",
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
"key": "ledger_key_contract_instance",
"durability": "persistent",
"val": {
"contract_instance": {
"vec": [
{
"symbol": "UserBlendBalance"
Expand Down Expand Up @@ -333,6 +227,9 @@
{
"contract_data": {
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
=======
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
>>>>>>> fc31c44 (feat: Connect Freighter Wallet integration (Issue 4.1))
Comment on lines 229 to +232
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This snapshot contains unresolved git merge-conflict markers (======= / >>>>>>> ...), which makes the JSON invalid and will break snapshot-based tests/tools. Please resolve the conflict and regenerate the snapshot so it’s valid JSON.

Suggested change
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
=======
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
>>>>>>> fc31c44 (feat: Connect Freighter Wallet integration (Issue 4.1))
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",

Copilot uses AI. Check for mistakes.
"key": "ledger_key_contract_instance",
"durability": "persistent"
}
Expand All @@ -343,7 +240,7 @@
"data": {
"contract_data": {
"ext": "v0",
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
"key": "ledger_key_contract_instance",
"durability": "persistent",
"val": {
Expand All @@ -364,7 +261,7 @@
[
{
"contract_data": {
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
"key": {
"ledger_key_nonce": {
"nonce": 1033654523790656264
Expand All @@ -379,7 +276,7 @@
"data": {
"contract_data": {
"ext": "v0",
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
"key": {
"ledger_key_nonce": {
"nonce": 1033654523790656264
Expand All @@ -397,7 +294,7 @@
[
{
"contract_data": {
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
"key": {
"ledger_key_nonce": {
"nonce": 5541220902715666415
Expand All @@ -412,7 +309,7 @@
"data": {
"contract_data": {
"ext": "v0",
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
"key": {
"ledger_key_nonce": {
"nonce": 5541220902715666415
Expand All @@ -430,7 +327,7 @@
[
{
"contract_data": {
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4",
"key": {
"ledger_key_nonce": {
"nonce": 801925984706572462
Expand All @@ -445,7 +342,7 @@
"data": {
"contract_data": {
"ext": "v0",
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4",
"key": {
"ledger_key_nonce": {
"nonce": 801925984706572462
Expand Down
19 changes: 19 additions & 0 deletions frontend/src/app/components/ConnectWalletButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';

export interface ConnectWalletButtonProps {
onClick: () => void;
publicKey?: string;
}

function truncatePublicKey(key: string) {
if (!key) return '';
return key.slice(0, 4) + '...' + key.slice(-4);
}

export const ConnectWalletButton: React.FC<ConnectWalletButtonProps> = ({ onClick, publicKey }) => {
return (
<button onClick={onClick} className="connect-wallet-btn">
{publicKey ? truncatePublicKey(publicKey) : 'Connect Wallet'}
</button>
Comment on lines +3 to +17
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ConnectWalletButton is described as a reusable component that detects Freighter and triggers connection, but it currently only renders a button and delegates all detection/connection logic to callers via onClick. To meet the stated requirement and avoid duplicating logic, consider moving Freighter detection + connect flow (and possibly the “install Freighter” UX trigger) into this component (or a shared hook used by it).

Copilot uses AI. Check for mistakes.
);
};
8 changes: 8 additions & 0 deletions frontend/src/app/components/DashboardHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import React from 'react';

export const DashboardHeader: React.FC<{ children?: React.ReactNode }> = ({ children }) => (
<header className="dashboard-header" style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '1rem 2rem', borderBottom: '1px solid #eee' }}>
<div style={{ fontWeight: 700, fontSize: '1.5rem' }}>Smasage</div>
<div>{children}</div>
</header>
);
24 changes: 24 additions & 0 deletions frontend/src/app/components/WalletContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"use client";
import { createContext, useContext, useState, ReactNode } from 'react';

interface WalletContextType {
publicKey: string | null;
setPublicKey: (key: string | null) => void;
}

const WalletContext = createContext<WalletContextType | undefined>(undefined);

export const WalletProvider = ({ children }: { children: ReactNode }) => {
const [publicKey, setPublicKey] = useState<string | null>(null);
return (
<WalletContext.Provider value={{ publicKey, setPublicKey }}>
{children}
</WalletContext.Provider>
);
};

export const useWallet = () => {
const ctx = useContext(WalletContext);
if (!ctx) throw new Error('useWallet must be used within WalletProvider');
return ctx;
};
6 changes: 5 additions & 1 deletion frontend/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@

import type { Metadata } from 'next';
import './globals.css';
import { WalletProvider } from './components/WalletContext';

export const metadata: Metadata = {
title: 'Smasage | AI Portfolio Manager',
Expand All @@ -16,7 +18,9 @@ export default function RootLayout({
<head>
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&display=swap" rel="stylesheet" />
</head>
<body>{children}</body>
<body>
<WalletProvider>{children}</WalletProvider>
</body>
</html>
);
}
Loading
Loading