跳到内容

智能账户会话 Snap:游戏 Dapp 自动审批

ETHBogota 黑客马拉松 Snap

7 分钟阅读
智能账户会话 Snap:游戏 Dapp 自动审批

MetaMask Snaps 是让 MetaMask 成为全球最具扩展性钱包的发展路线图。作为开发者,您可以以全新的方式将您的功能和 API 带入 MetaMask。Web3 开发者是这一增长的核心,本系列旨在展示当今正在构建的创新 MetaMask Snaps。

智能账户会话

Snap 代码库:https://github.com/livingrockrises/snap-auto-approvals

您为什么要构建它?

为游戏 dapp 打造无缝用户体验,以安全的方式为其提供自动审批功能。

能否带我们了解一下技术实现过程?

应用程序

我们的 Snap 由两部分组成。第一部分是用户交互的网站,第二部分是实际的 Snap。这两个元素的工作方式类似于客户端-服务器架构,其中 Snap 是服务器,网站是客户端。

网站的用户操作流程如下:

  1. 连接您的 EOA 并安装智能账户会话 Snap。

  2. 在 MetaMask 地址之上启用智能账户。MetaMask EOA 将成为该智能账户的控制器。

  3. 在您的智能账户上启用会话模块。模块为您的 Smart Safe 账户启用额外的访问控制逻辑。本质上,每个智能账户通过两种方式进行控制:一是由 MetaMask 账户所有者使用其签名密钥,二是由具有自定义访问逻辑的可选模块。

  4. 创建一个会话。

  5. 这将在您的智能账户上创建临时会话密钥,这些密钥通过模块被授权在您的钱包上执行交易。会话可以设置参数,例如开始时间、结束时间以及针对 Dapp 合约自定义操作的权限。

  6. 使用上述会话密钥发送自动审批的交易,无需 MetaMask 弹窗确认 gas 或签名。

MetaMask API

MetaMask 提供 API 调用,在用户授权的情况下,MetaMask Snaps 可以使用这些调用。

在本案例中,我们使用了以下内容:

snap_manageState - 允许我们在 MetaMask 内部存储加密数据。例如,我们用它来存储已创建的会话密钥对。

export type SessionKeyStorage = {
  owner: string;
  sessionKey: string;
  pk: string;
};

export const storeSessionInfo = async (data: SessionKeyStorage) => {
  await wallet.request({
    method: 'snap_manageState',
    params: ['update', data],
  });
};

export const clearSessionInfo = async () => {
  const result = await wallet.request({
    method: 'snap_manageState',
    params: ['clear'],
  });
  return result;
};

export const getSessionInfo = async () => {
  const result = await wallet.request({
    method: 'snap_manageState',
    params: ['get'],
  });
  return result;
};
复制

snap_confirm - 允许我们在 MetaMask 内部存储加密数据。例如,我们用它来存储已创建的账户。


export const promptUser = async (
  prompt: string,
  description: string,
  content: string,
): Promise<boolean> => {
  const response: any = await wallet.request({
    method: 'snap_confirm',
    params: [
      {
        prompt,
        description,
        textAreaContent: content,
      },
    ],
  });
  console.log('Prompt user response', response);
  if (response) {
    return response;
  }
  return false;
};

promptUser(getMessage(origin),
            'Do you want to use Smart Account',
            `Your Smart Account Address is ${_smartAccount.address}`,
          ).then((approval) => {
            if (approval) {
              console.log('Sending smart acccount response ', _smartAccount);
              resolve({
                address: _smartAccount.address,
                owner: _smartAccount.owner,
              });
            } else {
              reject(new Error('EOA user'));
            }
          });
复制

Snap 将处理通过网站的 wallet_invokeSnap 发送的传入 JSON-RPC 请求。

针对上述应用程序流程,我们创建了自定义请求方法,如 connect、enable_session_module、create_session 和 interact。以下是一个示例,代码可在此处查看。


export const useSmartAccount = async () => {
  console.log('invoke Snap...');
  const smartAccountResponse: any = await window.ethereum.request({
    method: 'wallet_invokeSnap',
    params: [
      defaultSnapOrigin,
      {
        method: 'connect',
        params: [],
      },
    ],
  });
  return smartAccountResponse;
};
复制

会话密钥模块

我们编写了一个 Gnosis Safe 风格的模块,通过基于会话密钥的访问控制来扩展智能合约钱包的功能。

模块和钱包合约的代码可在此处查看。

struct Session {
        address smartAccount;
        address sessionKey;
        uint256 startTimestamp;
        uint256 nonce;
        uint256 endTimestamp;
        bool enable;
        PermissionStorage permission;
    }

struct PermissionStorage {
        address[] whitelistDestinations;
        mapping(address => bool) whitelistDestinationMap;
        mapping(address => bytes4[]) whitelistMethods;
        mapping(address => mapping(bytes4 => bool)) whitelistMethodsMap;
        mapping(address => TokenApproval) tokenApprovals;
    }
复制

当通过调用 Snap 进而调用智能账户来创建会话时,以下方法将通过中继器从智能账户调用会话密钥模块。

function createSession(
        address sessionKey,
        PermissionParam[] calldata permissions,
        SessionParam calldata sessionParam
    ) external {
        require(
            !sessionMap[sessionKey].enable,
            "Session for key is already enabled"
        );
        Session storage _session = sessionMap[sessionKey];
        ...
复制

txHash:https://goerli.etherscan.io/tx/0x8b45f4cb0a7527bb7c44f6923eb9bb391faa656e212829ce0fd9c733ca71352b

会话创建后,中继器可以使用有效的会话密钥和签名在会话密钥模块上调用交易。


function executeTransaction(
        address _sessionKey,
        address payable _to,
        uint256 _value,
        bytes calldata _data,
        bytes calldata signature
    ) external returns (bool success) {
        Session storage session = sessionMap[_sessionKey];
        require(session.enable, "Session is not active");
        require(
            session.startTimestamp <= block.timestamp,
            "Session has not yet started"
        );
        require(session.endTimestamp >= block.timestamp, "Session has expired");
        ...
复制

txHash:https://goerli.etherscan.io/tx/0xf6d40bf9c74cff266f8bc26dabcf7a44ca1c0e85387f297f43fa5cb89bbea1a0

SDK

Biconomy SDK 是面向开发者的终极 Web3 工具套件,可帮助开发者利用智能账户,将复杂的多步骤用户旅程简化为一键式体验。

每位用户获得的是智能合约钱包,而非简单的密钥对,dApp 可以通过该智能合约钱包,使用交易捆绑包为用户定制各种无缝交互。

我们通过调用 Snap,将以下函数与 'connect' RPC 调用关联起来。


import SmartAccount from '@biconomy-sdk/smart-account';

async function getsmartAccount(): Promise<SmartAccount> {
  smartAccount = new SmartAccount(wallet, {
    activeNetworkId: Number(wallet.chainId),
    // supportedNetworksIds: supportedChains,
  });

  smartAccount = await smartAccount.init();
  console.log('initialized');
  console.log(smartAccount);
  return smartAccount;
}
复制

如果您要实现这一功能,下一步计划是什么?

我们期待 keyrings 功能的推出,以及在 MetaMask UI 中以 EOA 的形式显示智能账户信息的能力。

  1. 我们将发布与 MetaMask Snaps 兼容的 Biconomy SDK,供开发者使用。

  2. 添加社交恢复模块和使用智能账户实现一键式跨链批量交易,并在目标链交易执行后立即显示通知。

能否介绍一下您自己和您的团队?

Sachin 是 Biconomy 的 CTO 兼联合创始人。他拥有计算机科学背景,具备 6 年 Web2 和 5 年 Web3 经验。他热衷于以结构化的方式解决问题,并喜欢亲力亲为,快速实现和验证自己的想法。

Chirag 是 Biconomy 的区块链工程师。他热爱编程,并通过研究与开发不断学习 Web3 领域的一切知识。

您是什么时候第一次接触到 MetaMask Snaps 的?体验如何?

我们在 ETHBogota 黑客马拉松前不久了解到了 MetaMask Snaps。其文档质量和通过 Snap 方法所展现的能力让我们印象深刻。

MetaMask Snaps 与其他钱包有何不同?

它能够在不依赖 MetaMask 核心团队的情况下扩展 MetaMask 钱包的功能,从而实现更快速的增长。开发者可以访问 MetaMask 的现有功能,例如 JSON RPC 调用接口和存储。

请谈谈您和您的团队使用 MetaMask 构建 MetaMask Snaps 的体验?

基础开发非常直观,但我们花了大量时间来弄清楚某些特定方法的权限要求。目前,构建自定义 UI 元素(例如像显示 EOA 余额一样显示智能合约钱包余额)仍然比较复杂。

MetaMask Snaps 对您意味着什么?

它是一件秘密武器,让我们能够在 MetaMask 中支持 ERC4337 智能合约钱包,而无需自行构建,也无需 dapp 在其前端集成自定义组件。

您认为 MetaMask Snaps 为 Web3 领域带来了哪些机遇和可能性?

针对特定 dapp 定制的 MetaMask Snaps 可以提供更好的用户体验,并支持多链交互。在现有 Web3 用户群的基础上引入费用抽象、账户抽象和钱包安全能力。

对于有意尝试 MetaMask Snaps 的开发者,您有什么建议?

查阅 GitHub 讨论区和 Discord,这些资源可以帮助解决开发过程中的许多障碍。任何熟悉 JavaScript 和 JSON RPC 调用的人都可以进行构建。snap-monorepos 和示例 MetaMask Snaps 是加速开发的好起点。

如果您需要存储数据,请注意只能存储单个对象,因此您可以在一个对象中嵌套多个键值对。当您需要从自定义调用的 Snap 方法返回响应时,请确保其返回的是纯 JSON 对象。

使用 MetaMask Snaps 进行构建

开始使用 MetaMask Snaps:

  1. 查阅开发者文档

  2. 安装 MetaMask Flask

  3. 查阅 MetaMask Snaps 指南

  4. 在 Twitter、GitHub 讨论区和 Discord 上与我们保持联系

请关注我们团队在您附近举办的下一场黑客马拉松!祝 BUIDL 愉快 ⚒️

免责声明:MetaMask Snaps 通常由 Consensys Software 以外的第三方开发。使用第三方开发的 MetaMask Snaps 完全由您自行决定并承担风险,且您同意对因此类活动导致的任何损失或损害承担全部责任。Consensys 对第三方开发的 MetaMask Snaps 不作任何明示或暗示的保证,并对第三方开发的 MetaMask Snaps 免除一切责任。使用区块链相关软件存在风险,使用 MetaMask Snaps 即表示您完全接受这些风险。

AI 翻译。可能包含错误。请务必核实信息。

评价此翻译

本文作者:

  • MetaMask

    MetaMask(前身为 Consensys Software Inc)是全球最大的自托管金融平台,为用户提供一站式服务,涵盖加密资产与传统资产的持有、消费、储蓄与增值。公司正在打造实现上述功能的消费级平台,将支付、储蓄、投资与数字资产整合于一体,带来无缝一体化的使用体验。MetaMask 脱胎于全球使用最广泛的自托管钱包,让用户直接掌控自己的资金与资产,覆盖约 190 个国家和地区。自 2016 年起,MetaMask 在以太坊的发展历程中扮演了举足轻重的奠基角色。如今,MetaMask 处于区块链经济的核心位置,致力于构建「开放货币」的操作系统,让每个人都能全面掌控自己的财务生活。

    阅读所有文章