-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 27250ba
Showing
33 changed files
with
825 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
VITE_OIDC_CLIENT_ID="8b300f32-b604-49ba-80da-c21e26e82a03" | ||
VITE_OIDC_CALLBACK_URL="https://test-mpc-telegram-miniapp.vercel.app" | ||
VITE_OIDC_AUTHORIZATION_ENDPOINT="https://athena.skymavis.com/oauth2/auth" | ||
VITE_OIDC_CLIENT_SECRET="U~XhO4arIQT4oZ8K1jeCLDzqgp" | ||
VITE_OIDC_TOKEN_ENDPOINT="https://api-gateway.skymavis.com/account/oauth2/token" | ||
|
||
VITE_API_KEY="PAcmitDmTyC7AB9gq61RyxsYsjJ3oZ36" | ||
|
||
VITE_CHAIN_ID="2021" | ||
|
||
VITE_LOCKBOX_SERVICE_ENV="prod" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
module.exports = { | ||
root: true, | ||
env: { browser: true, es2020: true }, | ||
extends: [ | ||
'eslint:recommended', | ||
'plugin:@typescript-eslint/recommended', | ||
'plugin:react-hooks/recommended', | ||
], | ||
ignorePatterns: ['dist', '.eslintrc.cjs'], | ||
parser: '@typescript-eslint/parser', | ||
plugins: ['react-refresh'], | ||
rules: { | ||
'react-refresh/only-export-components': [ | ||
'warn', | ||
{ allowConstantExport: true }, | ||
], | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
pnpm-debug.log* | ||
lerna-debug.log* | ||
|
||
node_modules | ||
dist | ||
dist-ssr | ||
*.local | ||
|
||
# Editor directories and files | ||
.vscode/* | ||
!.vscode/extensions.json | ||
.idea | ||
.DS_Store | ||
*.suo | ||
*.ntvs* | ||
*.njsproj | ||
*.sln | ||
*.sw? | ||
.vercel |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# Pray Atia Telegram Mini App | ||
|
||
This is a basic example of integrating a Telegram mini-app with an MPC (Multi-Party Computation) wallet. The goal is to bring more value to the game and the Ronin ecosystem. | ||
|
||
In this example, a simple click game is implemented using the Lockbox and Mavis Account service. Both on-chain and off-chain logic are included. Every 10 clicks, the user can claim an amount of RON by calling the smart contract to claim the rewards. | ||
|
||
 | ||
|
||
## About | ||
This example using following libraries and libs: | ||
- [ReactJs](https://react.dev/) | ||
- [Vite](https://vitejs.dev/) | ||
- [Bun](https://bun.sh/) | ||
- [Lockbox](https://docs.skymavis.com/mavis/mpc/overview) | ||
- [Mavis Account](https://docs.skymavis.com/mavis/mavis-account/overview) | ||
- [Viem](https://viem.sh/) | ||
|
||
|
||
## Quick Start | ||
|
||
The example using some internal packages that is not public at the moment. In order to use it, send a request to be guide to install the packages. | ||
After the request is a | ||
|
||
```bash | ||
git clone ... | ||
cd ... | ||
bun install | ||
``` | ||
|
||
Open the browser at ... | ||
|
||
## Breakdown | ||
|
||
using account service | ||
flow | ||
|
||
|
||
|
||
## Deployment | ||
### Prequisite | ||
|
||
These are config that use need to prepare to launch the mini app production | ||
|
||
- asd | ||
- | ||
- | ||
- | ||
- | ||
|
||
## Table of Content |
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>Pray Atia Miniapp</title> | ||
</head> | ||
<body> | ||
<div id="root"></div> | ||
<script type="module" src="/src/main.tsx"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
{ | ||
"name": "test-mpc-telegram-miniapp", | ||
"private": true, | ||
"version": "0.0.0", | ||
"type": "module", | ||
"scripts": { | ||
"dev": "vite --port 3000", | ||
"build": "tsc -b && vite build", | ||
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", | ||
"preview": "vite preview" | ||
}, | ||
"dependencies": { | ||
"@axieinfinity/lockbox": "^2.1.5", | ||
"@sky-mavis/mavis-id-sdk": "0.0.2", | ||
"crypto": "^1.0.1", | ||
"framer-motion": "^11.3.8", | ||
"react": "^18.3.1", | ||
"react-dom": "^18.3.1", | ||
"viem": "^2.17.10", | ||
"zustand": "^4.5.4" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^20.14.11", | ||
"@types/react": "^18.3.3", | ||
"@types/react-dom": "^18.3.0", | ||
"@typescript-eslint/eslint-plugin": "^7.15.0", | ||
"@typescript-eslint/parser": "^7.15.0", | ||
"@vitejs/plugin-react-swc": "^3.5.0", | ||
"autoprefixer": "^10.4.19", | ||
"eslint": "^8.57.0", | ||
"eslint-plugin-react-hooks": "^4.6.2", | ||
"eslint-plugin-react-refresh": "^0.4.7", | ||
"postcss": "^8.4.39", | ||
"tailwindcss": "^3.4.6", | ||
"typescript": "^5.2.2", | ||
"vite": "^5.3.4", | ||
"vite-plugin-node-polyfills": "^0.22.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export default { | ||
plugins: { | ||
tailwindcss: {}, | ||
autoprefixer: {}, | ||
}, | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
export const abi = [ | ||
{ inputs: [], stateMutability: 'payable', type: 'constructor' }, | ||
{ | ||
anonymous: false, | ||
inputs: [ | ||
{ indexed: true, internalType: 'address', name: 'player', type: 'address' }, | ||
{ indexed: false, internalType: 'uint256', name: 'amount', type: 'uint256' }, | ||
], | ||
name: 'RewardClaimed', | ||
type: 'event', | ||
}, | ||
{ inputs: [], name: 'claimReward', outputs: [], stateMutability: 'nonpayable', type: 'function' }, | ||
{ | ||
inputs: [{ internalType: 'address', name: 'player', type: 'address' }], | ||
name: 'getScore', | ||
outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], | ||
stateMutability: 'view', | ||
type: 'function', | ||
}, | ||
{ | ||
inputs: [{ internalType: 'uint256', name: 'score', type: 'uint256' }], | ||
name: 'setScore', | ||
outputs: [], | ||
stateMutability: 'nonpayable', | ||
type: 'function', | ||
}, | ||
{ stateMutability: 'payable', type: 'receive' }, | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
import { AnimatePresence, motion } from 'framer-motion' | ||
import React, { useEffect, useState } from 'react' | ||
import { MPC_STATUS, useMPCStore } from './store' | ||
import { useMpc } from './use-mpc' | ||
|
||
const trimAddress = (address: string) => { | ||
return `${address.slice(0, 6)}...${address.slice(-4)}` | ||
} | ||
|
||
function App() { | ||
const { isConnected, lockbox, status } = useMPCStore() | ||
const { loginWithAS, claimReward } = useMpc() | ||
const [address, setAddress] = useState<string | null>('') | ||
const [balance, setBalance] = useState<number>(0) | ||
const [count, setCount] = useState(0) | ||
|
||
const [claimable, setClaimable] = useState(false) | ||
const [isClaiming, setIsClaiming] = useState(false) | ||
|
||
const fetchInfo = async () => { | ||
if (!lockbox || !isConnected) return | ||
|
||
const addresses = await lockbox.getProvider().request<string[]>({ method: 'eth_accounts' }) | ||
const balances = await lockbox.getProvider().request<string>({ method: 'eth_getBalance', params: [addresses[0] as `0x${string}`, 'latest'] }) | ||
|
||
setAddress(addresses[0]) | ||
setBalance(Number((Number(balances) / 1e18).toFixed(2))) | ||
} | ||
|
||
const login = async () => { | ||
loginWithAS() | ||
} | ||
|
||
useEffect(() => { | ||
fetchInfo() | ||
}, [lockbox, isConnected]) | ||
|
||
useEffect(() => { | ||
if (address && count > 1 && count % 10 === 0) { | ||
setClaimable(true) | ||
} | ||
}, [count]) | ||
|
||
const claim = async () => { | ||
setIsClaiming(true) | ||
|
||
try { | ||
await claimReward() | ||
setBalance((prev) => prev + 0.5) | ||
} catch (error) { | ||
console.log('Error claiming reward', error) | ||
} | ||
|
||
setIsClaiming(false) | ||
setClaimable(false) | ||
} | ||
|
||
const pray = () => { | ||
setCount((prev) => prev + 1) | ||
} | ||
|
||
return ( | ||
<main className='w-screen overflow-hidden relative h-screen flex items-center justify-center'> | ||
<div className='pointer-events-none absolute top-0 left-0 z-10 h-screen w-screen bg-vignette' /> | ||
<div className='bg-[url("./assets/background.png")] w-full h-full bg-center bg-cover absolute inset-0' /> | ||
|
||
<AnimatePresence> | ||
{claimable ? <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} className='overlay' /> : null} | ||
</AnimatePresence> | ||
|
||
<motion.figure layoutId='atia' className='relative z-0 bottom-[80px] w-[200px] h-[200px] active:scale-95 ' onClick={pray}> | ||
<img src='element-atia.png' alt='Atia' className='bottom-[0px]' /> | ||
</motion.figure> | ||
|
||
<AnimatePresence mode='wait'> | ||
{claimable && ( | ||
<motion.div | ||
layout | ||
initial={{ opacity: 0 }} | ||
animate={{ opacity: 1 }} | ||
exit={{ opacity: 0, transition: { duration: 0.05 } }} | ||
className=' absolute z-20 bg-[#91582A] w-[350px] h-[480px] rounded-2xl border-[#362D1B] border-2 flex items-center flex-col'> | ||
<motion.figure layoutId='atia' className='w-[200px] h-[200px] active:scale-95 mt-4' onClick={pray}> | ||
<img src='element-atia.png' alt='Atia' className='bottom-[0px]' /> | ||
</motion.figure> | ||
|
||
<motion.span | ||
layout | ||
initial={{ opacity: 0 }} | ||
animate={{ opacity: 1 }} | ||
exit={{ opacity: 0, transition: { duration: 0.05 } }} | ||
className='text-[#F7DAB2] text-xl mt-7'> | ||
Atia Bless you | ||
</motion.span> | ||
|
||
<motion.div | ||
layout | ||
initial={{ opacity: 0 }} | ||
animate={{ opacity: 1 }} | ||
exit={{ opacity: 0, transition: { duration: 0.05 } }} | ||
className='flex gap-2 items-center mr-5 justify-center mt-5'> | ||
<img src='icon-ron.png' alt='image' className='w-12 h-12' /> | ||
<span className='text-[#F7DAB2] text-[40px]'>0.5</span> | ||
</motion.div> | ||
|
||
{isClaiming ? ( | ||
<motion.img src='puff-loading.png' className='h-[80px] animate-spin w-auto mt-7' /> | ||
) : ( | ||
<motion.img | ||
layout | ||
initial={{ opacity: 0 }} | ||
animate={{ opacity: 1 }} | ||
exit={{ opacity: 0, transition: { duration: 0.05 } }} | ||
src='btn-claim.png' | ||
alt='login' | ||
className='h-[60px] w-auto mt-10' | ||
onClick={claim} | ||
/> | ||
)} | ||
</motion.div> | ||
)} | ||
</AnimatePresence> | ||
|
||
<div /> | ||
{address && ( | ||
<div className='absolute z-10 top-10 h-[50px]'> | ||
<div className='relative h-[70px]'> | ||
<img src='panel-count.png' alt='login' className='h-full w-auto' /> | ||
<span className='absolute font-custom text-[#F7DAB2] left-1/2 top-1/2 -translate-x-1/2 text-3xl -translate-y-1/2'>{count}</span> | ||
</div> | ||
</div> | ||
)} | ||
|
||
<div className='absolute z-10 bottom-20 h-[60px]'> | ||
{status === MPC_STATUS.IDLE ? ( | ||
<> | ||
{!address ? ( | ||
<img src='btn-login.png' alt='login' className='h-full w-auto' onClick={login} /> | ||
) : ( | ||
<div className='flex flex-col gap-2'> | ||
<div className='relative h-[60px]'> | ||
<img src='panel-address.png' alt='login' className='h-full w-auto' /> | ||
<span className='absolute text-[#FFFABA] text-2xl left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2'>{trimAddress(address)}</span> | ||
</div> | ||
|
||
<div className='relative h-[60px]'> | ||
<img src='panel-address.png' alt='login' className='h-full w-auto' /> | ||
<span className='absolute text-[#FFFABA] text-2xl left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2'>{balance} RON</span> | ||
</div> | ||
</div> | ||
)} | ||
</> | ||
) : ( | ||
<motion.img src='puff-loading.png' className='h-[80px] animate-spin w-auto mt-7' /> | ||
)} | ||
</div> | ||
</main> | ||
) | ||
} | ||
|
||
export default App |
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.