Skip to content

Commit

Permalink
Merge pull request #58 from openfort-xyz/feat/rpc-methods
Browse files Browse the repository at this point in the history
Feat/rpc methods
  • Loading branch information
jamalavedra authored Nov 26, 2024
2 parents 96f58f0 + f70e48d commit 3bb7f8f
Show file tree
Hide file tree
Showing 50 changed files with 2,134 additions and 10,822 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.8.13] - 2024-11-26
### Feat
- Add support for ERC-7715 and EIP-5792
- Add new zkSync smart accounts

## [0.8.12] - 2024-10-31
### Added
- Link Third Party Auth Provider
Expand Down
14 changes: 7 additions & 7 deletions examples/apps/auth-sample/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@
},
"dependencies": {
"@heroicons/react": "^2.0.13",
"@openfort/openfort-js": "0.8.10",
"@openfort/openfort-node": "^0.6.65",
"@radix-ui/react-dialog": "^1.1.2",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-switch": "^1.1.1",
"@radix-ui/react-toast": "^1.1.2",
"@rainbow-me/rainbowkit": "^2.1.1",
"@reown/walletkit": "^1.1.0",
Expand All @@ -24,17 +25,18 @@
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"cors": "^2.8.5",
"ethers": "5.7.2",
"jsonwebtoken": "^9.0.2",
"lucide-react": "^0.454.0",
"next": "^12.3.1",
"react": "^18.3.0",
"react-dom": "^18.3.0",
"@openfort/openfort-js": "^0.8.13",
"siwe": "^2.1.4",
"tailwind-merge": "^2.5.4",
"tailwind-merge": "^2.5.2",
"tailwindcss": "3.3.3",
"tailwindcss-animate": "^1.0.7",
"viem": "2.9.31",
"wagmi": "^2.9.2"
"viem": "2.21.50",
"wagmi": "^2.13.0"
},
"devDependencies": {
"@types/cors": "^2.8.17",
Expand All @@ -43,7 +45,6 @@
"autoprefixer": "^10.3.4",
"eslint": "7.32.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-import": "^0.13.0",
"eslint-config-next": "^12.3.1",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.24.2",
Expand All @@ -54,7 +55,6 @@
"lint-staged": "^13.0.3",
"postcss": "^8.3.6",
"prettier": "^2.7.1",
"tailwindcss": "^3.2.1",
"typescript": "5.4.2"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { useState } from 'react'
import { Switch } from '../ui/switch'
import { Label } from '../ui/label'
import BackendMintButton from './BackendMintButton'
import EIP1193MintButton from './EIP1193MintButton'
import EIP1193CreateSessionButton from '../SessionKey/EIP1193CreateSessionButton'
import BackendCreateSessionButton from '../SessionKey/BackendCreateSessionButton'
import { Alert, AlertDescription, AlertTitle } from '../ui/alert'

const sessionMethods = [
{id: '1hour', title: '1 Hour'},
{id: '1day', title: '1 Day'},
{id: '1month', title: '1 Month'},
];

export default function AccountActions({ handleSetMessage }: { handleSetMessage: (message: string) => void }) {
const [isProviderEnabled, setIsProviderEnabled] = useState(true)
const [sessionKey, setSessionKey] = useState<`0x${string}` | null>(null);

return (
<div className="bg-white p-4 rounded-md shadow-2xl space-y-4">
<h2 className="font-medium text-xl pb-4">
Account actions
</h2>

<div className="flex items-center space-x-2 mb-4">
<Switch
id="provider-switch"
checked={isProviderEnabled}
onCheckedChange={setIsProviderEnabled}
/>
<Label htmlFor="provider-switch">EIP-1193 Provider</Label>
</div>

{isProviderEnabled ? (
<div>
<EIP1193MintButton handleSetMessage={handleSetMessage} />
</div>
) : (
<div className='space-y-2'>
<Alert className='bg-blue-50'>
<AlertTitle>Backend Action!</AlertTitle>
<AlertDescription>
This mode creates an API call to your backend to mint the NFT.
</AlertDescription>
</Alert>
<BackendMintButton handleSetMessage={handleSetMessage} />
</div>
)}
<fieldset>
<legend className="font-medium leading-6 text-black">
Session key duration
</legend>
<div className="mt-3 space-y-1">
{sessionMethods.map((sessionMethod) => (
<div key={sessionMethod.id} className="flex items-center">
<input
disabled={sessionKey !== null}
id={sessionMethod.id}
name="session-method"
type="radio"
defaultChecked={sessionMethod.id === '1day'}
className="h-4 w-4 border-gray-300 text-blue-600 focus:ring-blue-600"
/>
<label
htmlFor={sessionMethod.id}
className="ml-3 block text-sm font-medium leading-6 text-gray-900"
>
{sessionMethod.title}
</label>
</div>
))}
</div>
</fieldset>
{isProviderEnabled ? (
<div>
<EIP1193CreateSessionButton handleSetMessage={handleSetMessage} setSessionKey={setSessionKey} sessionKey={sessionKey}/>
</div>
) : (
<div className='space-y-2'>
<BackendCreateSessionButton handleSetMessage={handleSetMessage} setSessionKey={setSessionKey} sessionKey={sessionKey}/>
</div>
)}
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import {useOpenfort} from '../../hooks/useOpenfort';
import {EmbeddedState} from '@openfort/openfort-js';
import Loading from '../Loading';
import openfort from '../../utils/openfortConfig';
import { Button } from '../ui/button';

const MintNFTButton: React.FC<{
const BackendMintButton: React.FC<{
handleSetMessage: (message: string) => void;
}> = ({handleSetMessage}) => {
const {state} = useOpenfort();
Expand Down Expand Up @@ -43,15 +44,16 @@ const MintNFTButton: React.FC<{

return (
<div>
<button
onClick={handleMintNFT}
disabled={state !== EmbeddedState.READY}
className={`mt-4 w-32 px-4 py-2 bg-black text-white font-semibold rounded-lg shadow-md hover:bg-gray-800 disabled:bg-gray-400 disabled:cursor-not-allowed focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-opacity-50`}
<Button
className='w-full'
disabled={state !== EmbeddedState.READY}
onClick={handleMintNFT}
variant="outline"
>
{loading ? <Loading /> : 'Mint NFT'}
</button>
</Button>
</div>
);
};

export default MintNFTButton;
export default BackendMintButton;
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import React, {useState} from 'react';
import {useOpenfort} from '../../hooks/useOpenfort';
import {EmbeddedState} from '@openfort/openfort-js';
import Loading from '../Loading';
import { Button } from '../ui/button';
import { createPublicClient, createWalletClient, custom, encodeFunctionData, http } from 'viem'
import { polygonAmoy } from 'viem/chains';
import { eip5792Actions } from 'viem/experimental'

const EIP1193MintButton: React.FC<{
handleSetMessage: (message: string) => void;
}> = ({handleSetMessage}) => {
const {getEvmProvider, state} = useOpenfort();
const [loading, setLoading] = useState(false);
const [loadingBatch, setLoadingBatch] = useState(false);

const handleSendTransaction = async () => {
const provider = getEvmProvider();
if (!provider) {
throw new Error('Failed to get EVM provider');
}
setLoading(true);
const publicClient = createPublicClient({
chain: polygonAmoy,
transport: http()
})
const walletClient = createWalletClient({
chain: polygonAmoy,
transport: custom(provider)
})

const erc721Address = '0x2522f4fc9af2e1954a3d13f7a5b2683a00a4543a';

// Read more about [ABI Formats](https://docs.soliditylang.org/en/latest/abi-spec.html#json).
const abi = [
{
"inputs": [
{
"internalType": "address",
"name": "_to",
"type": "address"
}
],
"name": "mint",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]

const [account] = await walletClient.getAddresses()
const { request } = await publicClient.simulateContract({
account,
address: erc721Address,
abi: abi,
functionName: 'mint',
args: ['0x64452Dff1180b21dc50033e1680bB64CDd492582']
})


let tx: `0x${string}`;
try {
tx = await walletClient.writeContract(request)
console.log('Transaction hash:', tx);
handleSetMessage(`https://amoy.polygonscan.com/tx/${tx}`);
const receipt = await publicClient.getTransactionReceipt({hash: tx});
console.log('Transaction receipt:', receipt);
} catch (error: any) {
console.error('Failed to send transaction:', error);
}
setLoading(false);
};

const handleSendCalls = async () => {
const provider = getEvmProvider();
if (!provider) {
throw new Error('Failed to get EVM provider');
}
setLoadingBatch(true);
const walletClient = createWalletClient({
chain: polygonAmoy,
transport: custom(provider)
}).extend(eip5792Actions())

const erc721Address = '0x2522f4fc9af2e1954a3d13f7a5b2683a00a4543a';

// Read more about [ABI Formats](https://docs.soliditylang.org/en/latest/abi-spec.html#json).
const abi = [
{
"inputs": [
{
"internalType": "address",
"name": "_to",
"type": "address"
}
],
"name": "mint",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]

const [account] = await walletClient.getAddresses()

try {
const tx = await walletClient.sendCalls({
account,
calls: [
{
to: erc721Address,
data: encodeFunctionData({abi, functionName:"mint", args:['0x64452Dff1180b21dc50033e1680bB64CDd492582']})
},
{
to: erc721Address,
data: encodeFunctionData({abi, functionName:"mint", args:['0x64452Dff1180b21dc50033e1680bB64CDd492582']})
},
],
})

console.log('Transaction hash:', tx);
handleSetMessage(`https://amoy.polygonscan.com/tx/${tx}`);
} catch (error: any) {
console.error('Failed to send transaction:', error);
}
setLoadingBatch(false);
};

return (
<div className='space-y-2'>
<Button
className='w-full'
disabled={state !== EmbeddedState.READY}
onClick={handleSendTransaction}
variant="outline"
>
{loading ? <Loading /> : 'Mint NFT'}
</Button>
<Button
className='w-full'
disabled={state !== EmbeddedState.READY}
onClick={handleSendCalls}
variant="outline"
>
{loadingBatch ? <Loading /> : 'Send batch calls'}
</Button>
</div>
);
};

export default EIP1193MintButton;
Loading

0 comments on commit 3bb7f8f

Please sign in to comment.