{"id":21670762,"url":"https://github.com/flowstake/photo-attestation","last_synced_at":"2026-04-15T18:02:25.764Z","repository":{"id":225534939,"uuid":"766214566","full_name":"flowstake/photo-attestation","owner":"flowstake","description":"Photographic attestation with digital signatures for validation","archived":false,"fork":false,"pushed_at":"2024-06-21T17:58:01.000Z","size":18,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-03-20T07:45:05.198Z","etag":null,"topics":["computer-vision"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/flowstake.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-03-02T16:43:26.000Z","updated_at":"2024-10-26T22:33:45.000Z","dependencies_parsed_at":"2024-03-02T18:44:14.894Z","dependency_job_id":"061c1857-d9ab-4885-ae74-24e58027387e","html_url":"https://github.com/flowstake/photo-attestation","commit_stats":null,"previous_names":["flowstake/photo-attestation"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/flowstake/photo-attestation","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flowstake%2Fphoto-attestation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flowstake%2Fphoto-attestation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flowstake%2Fphoto-attestation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flowstake%2Fphoto-attestation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flowstake","download_url":"https://codeload.github.com/flowstake/photo-attestation/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flowstake%2Fphoto-attestation/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31853279,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-15T15:24:51.572Z","status":"ssl_error","status_checked_at":"2026-04-15T15:24:39.138Z","response_time":63,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["computer-vision"],"created_at":"2024-11-25T12:35:15.617Z","updated_at":"2026-04-15T18:02:25.745Z","avatar_url":"https://github.com/flowstake.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FlowStake Technology: Photo/Video Attestation Requirements\n\n## User Interface and Experience (UI/UX)\n- **Capture Interface:** Design an intuitive interface for users to easily capture photos or videos during their activities. This should include a clear, easy-to-use camera functionality within the app.\n- **Guided Instructions:** Provide users with clear instructions on how to capture the required evidence. This might include tips on framing, lighting, and specific content that needs to be captured (e.g., a clear view of the user’s face, the activity environment, etc.).\n- **Feedback Mechanism:** Implement a feedback mechanism that informs users if their photos or videos meet the required criteria or if they need to retake them.\n\n## Technical Specifications\n- **Resolution and Quality:** Set minimum resolution and quality standards for the photos and videos to ensure they are clear and usable for attestation purposes.\n- **Format and Compression:** Determine acceptable file formats (e.g., JPEG, MP4) and implement compression algorithms that maintain quality while optimizing file size for efficient upload and storage.\n- **Metadata Capture:** Ensure the app captures relevant metadata such as timestamp, GPS coordinates, and device information to accompany each photo or video for verification purposes.\n\n## Security and Verification\n- **Encryption:** Use end-to-end encryption to secure the photos and videos during upload and storage, ensuring that they cannot be tampered with.\n- **Watermarking:** Implement digital watermarking to embed user-specific information within the photos or videos, making it difficult to use fraudulent media.\n- **Blockchain Integration:** Store the attestation data on a distributed ledger (e.g., Hedera Hashgraph) to provide a tamper-proof record of the evidence. Each entry should include a hash of the photo or video file and its metadata.\n\n## Data Storage and Management\n- **Cloud Storage:** Utilize scalable cloud storage solutions (e.g., Firebase) to handle the large volume of media files. Ensure the storage system can handle peak loads during events.\n- **IPFS Integration:** Use InterPlanetary File System (IPFS) for decentralized media storage. IPFS allows for efficient and distributed storage of media files, ensuring data is accessible and resilient.\n- **Hash-Addressable Content:** Ensure all media files stored in IPFS are hash-addressable, meaning each file is referenced by its unique cryptographic hash. This guarantees data immutability and integrity, as any change in the file content will result in a different hash.\n- **Retention Policies:** Define data retention policies to manage the lifecycle of the media files, including how long they will be stored and when they will be archived or deleted.\n- **Access Control:** Implement strict access control measures to ensure that only authorized users can view or manage the attestation files.\n\n## Attestation Process\n- **Real-time Uploads:** Enable real-time uploading of photos and videos during the activity to provide immediate proof of participation and minimize post-activity fraud.\n- **Peer Review System:** Allow for a peer review system where users can verify each other's submissions, enhancing community trust and engagement.\n- **Automated Verification:** Develop algorithms to perform initial automated checks on the media files, such as verifying GPS data against the activity route or detecting signs of manipulation.\n\n## User Notifications and Feedback\n- **Upload Confirmation:** Notify users once their media files have been successfully uploaded and verified.\n- **Verification Status:** Provide real-time updates on the verification status of their submissions, including any issues that need to be addressed.\n- **Community Feedback:** Implement a system for users to receive feedback from peers and the platform on the quality and authenticity of their submissions.\n\n## Compliance and Legal Considerations\n- **Privacy Policies:** Ensure compliance with privacy regulations such as GDPR by clearly communicating how user data will be used, stored, and protected.\n- **User Consent:** Obtain explicit consent from users for capturing and storing their media files as part of the attestation process.\n- **Dispute Resolution:** Establish procedures for users to dispute verification results or raise concerns about privacy and data security.\n\n## Integration with Other Features\n- **Activity Feed:** Integrate the attested photos and videos into a social feed within the app, allowing users to share their achievements and engage with the community.\n- **Smart Contracts:** Use Ethereum smart contracts to facilitate and enforce sports betting competitions, ensuring that the results based on attested activities are transparent and fair.\n\n## IPFS for Media Storage and Hash-Addressable Content for Data Immutability\n- **Decentralized Storage:** Leverage IPFS to store media files in a decentralized manner. This ensures high availability and resistance to censorship.\n- **Content Hashing:** Utilize content hashing to ensure that each file can be uniquely identified and verified. The hash serves as a unique fingerprint for the file.\n- **Data Integrity:** Guarantee data integrity by ensuring that any alteration in the media file changes its hash, thereby making tampering easily detectable.\n- **Interoperability:** Ensure that the IPFS-stored media files can be accessed and verified across different systems and platforms, promoting interoperability and transparency.\n\nBy meeting these requirements, FlowStake technology can create a robust, secure, and user-friendly system for photo and video attestation, enhancing the credibility and engagement of the platform.\n\n# FlowStake Technology: Photo/Video Attestation Platform\n\nThis project is built using Expo and React Native, integrating IPFS for media storage and blockchain for data immutability.\n\n## Directory Structure\n\n/FlowStakeApp\n  /assets\n  /components\n    /Camera.js\n    /PhotoAttestation.js\n    /VideoAttestation.js\n  /screens\n    /HomeScreen.js\n    /CaptureScreen.js\n    /ProfileScreen.js\n  /utils\n    /ipfs.js\n    /blockchain.js\n  App.js\n  app.json\n  package.json\n  babel.config.js\n\n\n## Code Structure\n\n### `App.js`\n\n```javascript\nimport React from 'react';\nimport { NavigationContainer } from '@react-navigation/native';\nimport { createStackNavigator } from '@react-navigation/stack';\nimport HomeScreen from './screens/HomeScreen';\nimport CaptureScreen from './screens/CaptureScreen';\nimport ProfileScreen from './screens/ProfileScreen';\n\nconst Stack = createStackNavigator();\n\nexport default function App() {\n  return (\n    \u003cNavigationContainer\u003e\n      \u003cStack.Navigator initialRouteName=\"Home\"\u003e\n        \u003cStack.Screen name=\"Home\" component={HomeScreen} /\u003e\n        \u003cStack.Screen name=\"Capture\" component={CaptureScreen} /\u003e\n        \u003cStack.Screen name=\"Profile\" component={ProfileScreen} /\u003e\n      \u003c/Stack.Navigator\u003e\n    \u003c/NavigationContainer\u003e\n  );\n}\n```\n\n### `Homescreen.js`\n\n```javascript\nimport React from 'react';\nimport { View, Text, Button, StyleSheet } from 'react-native';\n\nexport default function HomeScreen({ navigation }) {\n  return (\n    \u003cView style={styles.container}\u003e\n      \u003cText\u003eWelcome to FlowStake\u003c/Text\u003e\n      \u003cButton\n        title=\"Capture Activity\"\n        onPress={() =\u003e navigation.navigate('Capture')}\n      /\u003e\n      \u003cButton\n        title=\"Profile\"\n        onPress={() =\u003e navigation.navigate('Profile')}\n      /\u003e\n    \u003c/View\u003e\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    justifyContent: 'center',\n    alignItems: 'center',\n  },\n});\n```\n\n### `CaptureScreen.js`\n\n```javascript\nimport React from 'react';\nimport { View, Text, StyleSheet } from 'react-native';\nimport Camera from '../components/Camera';\n\nexport default function CaptureScreen() {\n  return (\n    \u003cView style={styles.container}\u003e\n      \u003cText\u003eCapture your activity\u003c/Text\u003e\n      \u003cCamera /\u003e\n    \u003c/View\u003e\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    justifyContent: 'center',\n    alignItems: 'center',\n  },\n});\n```\n\n### `ProfileScreen.js`\n\n```javascript\nimport React from 'react';\nimport { View, Text, StyleSheet } from 'react-native';\n\nexport default function ProfileScreen() {\n  return (\n    \u003cView style={styles.container}\u003e\n      \u003cText\u003eProfile\u003c/Text\u003e\n      {/* Additional profile details can be added here */}\n    \u003c/View\u003e\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    justifyContent: 'center',\n    alignItems: 'center',\n  },\n});\n```\n\n### `Camera.js`\n\n```javascript\nimport React, { useState, useRef } from 'react';\nimport { View, Button, StyleSheet } from 'react-native';\nimport { Camera } from 'expo-camera';\nimport * as FileSystem from 'expo-file-system';\nimport uploadToIPFS from '../utils/ipfs';\n\nexport default function CameraComponent() {\n  const [hasPermission, setHasPermission] = useState(null);\n  const cameraRef = useRef(null);\n\n  React.useEffect(() =\u003e {\n    (async () =\u003e {\n      const { status } = await Camera.requestPermissionsAsync();\n      setHasPermission(status === 'granted');\n    })();\n  }, []);\n\n  const takePicture = async () =\u003e {\n    if (cameraRef.current) {\n      const photo = await cameraRef.current.takePictureAsync();\n      await uploadToIPFS(photo.uri);\n    }\n  };\n\n  if (hasPermission === null) {\n    return \u003cView /\u003e;\n  }\n  if (hasPermission === false) {\n    return \u003cText\u003eNo access to camera\u003c/Text\u003e;\n  }\n  return (\n    \u003cView style={styles.container}\u003e\n      \u003cCamera style={styles.camera} type={Camera.Constants.Type.back} ref={cameraRef}\u003e\n        \u003cView style={styles.buttonContainer}\u003e\n          \u003cButton title=\"Take Picture\" onPress={takePicture} /\u003e\n        \u003c/View\u003e\n      \u003c/Camera\u003e\n    \u003c/View\u003e\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n  },\n  camera: {\n    flex: 1,\n  },\n  buttonContainer: {\n    flex: 1,\n    backgroundColor: 'transparent',\n    flexDirection: 'row',\n    margin: 20,\n  },\n});\n```\n\n### `ipfs.js`\n\n```javascript\nimport * as IPFS from 'ipfs-core';\n\nconst ipfs = await IPFS.create();\n\nconst uploadToIPFS = async (fileUri) =\u003e {\n  try {\n    const file = await FileSystem.readAsStringAsync(fileUri, {\n      encoding: FileSystem.EncodingType.Base64,\n    });\n\n    const { cid } = await ipfs.add(Buffer.from(file, 'base64'));\n    console.log('File uploaded to IPFS with CID:', cid);\n    return cid;\n  } catch (error) {\n    console.error('Error uploading to IPFS:', error);\n  }\n};\n\nexport default uploadToIPFS;\n```\n\n### `blockchain.js`\n\n```javascript\nimport Web3 from 'web3';\n\nconst web3 = new Web3('https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID');\n\nconst smartContractAddress = 'YOUR_SMART_CONTRACT_ADDRESS';\nconst smartContractABI = [\n  // Your smart contract ABI\n];\n\nconst contract = new web3.eth.Contract(smartContractABI, smartContractAddress);\n\nexport const addProofToBlockchain = async (userAddress, ipfsHash) =\u003e {\n  try {\n    const tx = await contract.methods.addProof(userAddress, ipfsHash).send({ from: userAddress });\n    console.log('Transaction successful:', tx);\n    return tx;\n  } catch (error) {\n    console.error('Error adding proof to blockchain:', error);\n  }\n};\n```\n\n### `package.json`\n\n```javascript\n{\n  \"name\": \"FlowStakeApp\",\n  \"version\": \"1.0.0\",\n  \"main\": \"node_modules/expo/AppEntry.js\",\n  \"scripts\": {\n    \"start\": \"expo start\",\n    \"android\": \"expo start --android\",\n    \"ios\": \"expo start --ios\",\n    \"web\": \"expo start --web\"\n  },\n  \"dependencies\": {\n    \"expo\": \"^46.0.0\",\n    \"expo-camera\": \"^12.2.0\",\n    \"react\": \"17.0.1\",\n    \"react-dom\": \"17.0.1\",\n    \"react-native\": \"0.64.2\",\n    \"react-native-web\": \"0.17.1\",\n    \"react-navigation\": \"^4.4.4\",\n    \"react-navigation-stack\": \"^2.10.4\",\n    \"ipfs-core\": \"^0.12.1\",\n    \"web3\": \"^1.5.2\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.9.0\"\n  },\n  \"private\": true\n}\n```\n\n### `babel.config.js`\n\n```javascript\nmodule.exports = function(api) {\n  api.cache(true);\n  return {\n    presets: ['babel-preset-expo'],\n  };\n};\n```\n\n### `app.json`\n\n```javascript\n{\n  \"expo\": {\n    \"name\": \"FlowStakeApp\",\n    \"slug\": \"flowstakeapp\",\n    \"version\": \"1.0.0\",\n    \"orientation\": \"portrait\",\n    \"icon\": \"./assets/icon.png\",\n    \"splash\": {\n      \"image\": \"./assets/splash.png\",\n      \"resizeMode\": \"contain\",\n      \"backgroundColor\": \"#ffffff\"\n    },\n    \"updates\": {\n      \"fallbackToCacheTimeout\": 0\n    },\n    \"assetBundlePatterns\": [\n      \"**/*\"\n    ],\n    \"ios\": {\n      \"supportsTablet\": true\n    },\n    \"android\": {\n      \"adaptiveIcon\": {\n        \"foregroundImage\": \"./assets/adaptive-icon.png\",\n        \"backgroundColor\": \"#ffffff\"\n      }\n    },\n    \"web\": {\n      \"favicon\": \"./assets/favicon.png\"\n    }\n  }\n}\n```\n\nFIN\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflowstake%2Fphoto-attestation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflowstake%2Fphoto-attestation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflowstake%2Fphoto-attestation/lists"}