Experimental Next-gen Account for Ethereum.
Warning
This repository is work-in-progress and highly experimental. It is recommended not to use it in production just yet.
- Install
- Usage
- JSON-RPC Reference
- Available ERC-5792 Capabilities
- Wagmi Reference
- Development
- License
pnpm i porto
The example below demonstrates usage of Porto's EIP-1193 Provider:
import { Porto } from 'porto'
const porto = Porto.create()
const account = await porto.provider.request({
method: 'experimental_connect',
params: [{ capabilities: { grantSession: true } }]
})
Porto can be used in conjunction with Wagmi to provide a seamless experience for developers and end-users.
Get started with Wagmi by following the official guide.
After you have set up Wagmi, you can set up Porto by calling Porto.create()
. This will automatically
inject a Porto-configured EIP-1193 Provider into your Wagmi instance via EIP-6963: Multi Injected Provider Discovery.
import { Porto } from 'porto'
import { http, createConfig, createStorage } from 'wagmi'
import { odysseyTestnet } from 'wagmi/chains'
Porto.create()
export const wagmiConfig = createConfig({
chains: [odysseyTestnet],
storage: createStorage({ storage: localStorage }),
transports: {
[odysseyTestnet.id]: http(),
},
})
This means you can now use Wagmi-compatible Hooks like useConnect
. For more info, check out the Wagmi Reference.
import { W } from 'porto/wagmi'
import { useConnectors } from 'wagmi'
function Connect() {
const connect = W.useConnect()
const connectors = useConnectors()
return connectors?.map((connector) => (
<div key={connector.uid}>
<button
onClick={() =>
connect.mutate({
connector,
grantSession: true,
})
}
>
Login
</button>
<button
onClick={() =>
connect.mutate({
connector,
createAccount: true,
grantSession: true,
}
)}
>
Register
</button>
</div>
))
}
Porto implements the following standardized wallet JSON-RPC methods:
eth_accounts
eth_requestAccounts
eth_sendTransaction
eth_signTypedData_v4
personal_sign
wallet_getCapabilities
wallet_getCallsStatus
wallet_sendCalls
In addition to the above, Porto implements the following experimental JSON-RPC methods:
Note
These JSON-RPC methods intend to be upstreamed as an ERC (or deprecated in favor of upcoming/existing ERCs) in the near future. They are purposefully minimalistic and intend to be iterated on.
Connects an end-user to an application.
{
method: 'experimental_connect',
params: [{
// ERC-5792 capabilities to define extended behavior.
capabilities: {
// Whether to create a new account.
createAccount?: boolean | { label?: string },
// Whether to grant a session with an optional expiry.
// Defaults to user-configured expiry on the account.
grantSession?: boolean | { expiry?: number },
}
}]
}
{
account: {
// The address of the account.
address: `0x${string}`,
// ERC-5792 capabilities to define extended behavior.
capabilities: {
// The sessions granted to the account.
sessions: {
// The expiry of the session.
expiry: number,
// The ID of the session.
id: `0x${string}`,
}[],
}
}[]
}
Creates (and connects) a new account.
{
method: 'experimental_createAccount',
params: [{
// Label for the account. Used as the Passkey
// credential display name.
label?: string
}]
}
// Address of the created account.
`0x${string}`
Disconnects the account.
{
method: 'experimental_disconnect'
}
Grants a session on the account.
Minimal alternative to the draft ERC-7715 specification. We hope to upstream concepts from this method and eventually use ERC-7715 or similar.
{
method: 'experimental_grantSession',
params: [{
// Address of the account to grant a session on.
address?: `0x${string}`
// The expiry of the session.
// Defaults to user-configured expiry on the account.
expiry?: number
// The keys to grant on the session.
keys?: {
algorithm: 'p256' | 'secp256k1',
publicKey: `0x${string}`,
}[]
}]
}
{
// The expiry of the session.
expiry: number,
// The ID of the session.
id: `0x${string}`,
}
Returns a set of hex payloads to sign over to import an external account, and prepares values needed to fill context for the experimental_importAccount
JSON-RPC method.
{
method: 'experimental_prepareImportAccount',
params: [{
// Address of the account to import.
address?: `0x${string}`,
// ERC-5792 capabilities to define extended behavior.
capabilities: {
// Whether to grant a session with an optional expiry.
// Defaults to user-configured expiry on the account.
grantSession?: boolean | { expiry?: number },
}
}]
}
{
// Filled context for the `experimental_importAccount` JSON-RPC method.
context: unknown
// Hex payloads to sign over.
signPayloads: `0x${string}`[]
}
Imports an account.
{
method: 'experimental_importAccount',
params: [{
// Context from the `experimental_prepareImportAccount` JSON-RPC method.
context: unknown,
// Signatures over the payloads returned by `experimental_prepareImportAccount`.
signatures: `0x${string}`[]
}]
}
{
// The address of the account.
address: `0x${string}`,
// ERC-5792 capabilities to define extended behavior.
capabilities: {
// The sessions granted to the account.
sessions: {
// The expiry of the session.
expiry: number,
// The ID of the session.
id: `0x${string}`,
}[],
}
}
Lists the active sessions on the account.
{
method: 'experimental_sessions',
params: [{
// Address of the account to list sessions on.
address?: `0x${string}`
}]
}
{ expiry: number, id: `0x${string}` }[]
Porto implements the following ERC-5792 capabilities to define extended behavior:
The Porto Account supports atomic batch calls. This means that multiple calls will be executed in a single transaction upon using wallet_sendCalls
.
Porto supports programmatic account creation.
Accounts may be created via the experimental_createAccount
JSON-RPC method.
Example:
{ method: 'experimental_createAccount' }
Accounts may be created upon connection with the createAccount
parameter on the experimental_connect
JSON-RPC method.
Example:
{
method: 'experimental_connect',
params: [{
capabilities: {
createAccount: true
// OR
createAccount: { label: "My Example Account" }
}
}]
}
Porto supports account session management (ie. session keys & their permissions).
Sessions may be granted via the experimental_grantSession
JSON-RPC method.
Example:
{
method: 'experimental_grantSession',
params: [{
address: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbe',
expiry: 1727078400
}]
}
Sessions may be granted upon connection with the grantSession
parameter on the experimental_connect
JSON-RPC method.
Example:
{
method: 'experimental_connect',
params: [{
capabilities: {
grantSession: {
expiry: 1727078400
}
}
}]
}
If a session is granted upon connection, the experimental_connect
JSON-RPC method will return the session on the capabilities.sessions
parameter of the response.
Example:
{
address: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbe',
capabilities: {
sessions: [{ expiry: 1727078400, id: '0x...' }]
}
}
Porto implements the following Wagmi VanillaJS Actions and React Hooks that map directly to the experimental JSON-RPC methods.
Note
Porto only supports the React version of Wagmi at the moment. If you are interested in adding support for other Wagmi Adapters, please create a Pull Request.
Import via named export or A
namespace (better autocomplete DX and does not impact tree shaking).
connect
createAccount
disconnect
grantSession
importAccount
sessions
import { A } from 'porto/wagmi/actions' // A.connect()
import { connect } from 'porto/wagmi/actions'
Import via named export or W
namespace (better autocomplete DX and does not impact tree shaking).
useConnect
useCreateAccount
useDisconnect
useGrantSession
useImportAccount
useSessions
import { W } from 'porto/wagmi' // W.useConnect()
import { useConnect } from 'porto/wagmi'
# Install pnpm
$ curl -fsSL https://get.pnpm.io/install.sh | sh -
$ pnpm install # Install modules
$ pnpm wagmi generate # get ABIs, etc.
$ pnpm dev # Run playground
# Install Foundry
$ foundryup
$ forge build --config-path ./contracts/foundry.toml # Build
$ forge test --config-path ./contracts/foundry.toml # Test
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in these packages by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.