MetaMask Snaps — это дорожная карта к созданию самого расширяемого кошелька в мире. Как разработчик, вы можете добавлять свои функции и API в MetaMask совершенно новыми способами. Разработчики Web3 — основа этого роста, и данная серия материалов призвана продемонстрировать новые MetaMask Snaps, создаваемые сегодня.
Polysnap
Репозиторий Snap: https://github.com/Niraj-Kamdar/Polysnap
Почему вы его создали?
Сейчас разработчикам приходится создавать отдельный snap для каждой новой функции, которую они хотят добавить в MetaMask. Polysnap предлагает более эффективный подход к повторному использованию кода. Широкий набор Wasm-модулей на базе Polywrap хранится в IPFS. Polysnap позволяет разработчикам приложений выполнять любой Wasm-wrapper, развёрнутый в IPFS, на лету и безопасно — с помощью простого вызова JSON RPC, без необходимости создавать новый Snap.
Пользователям dapp, использующего Polysnap, не нужно устанавливать несколько snaps — достаточно установить только Polysnap, что позволяет сократить потенциальные векторы атак. Dapp на базе Polysnap может быть безопаснее традиционного snap, поскольку Polysnap контролирует все действия, связанные с возможностями хоста — доступом в интернет, доступом к кошельку и т. д. — и всегда требует подтверждения от пользователя перед выполнением любого кода, использующего эти возможности.
Разработчикам dapp не нужно просить пользователей устанавливать несколько Snaps для работы приложения — вместо этого можно использовать один Snap — Polysnap — и запускать любые Polywrap-wrappers.
Разработчики Snap больше не ограничены JavaScript и его экосистемой. Теперь они могут писать Polywrap-wrappers на таких языках, как Rust, Go и AssemblyScript, и вызывать их через Polysnap.
Можете рассказать о технической реализации?
Проект Polysnap состоит из двух элементов:
Polysnap (MetaMask Snap)
Демонстрационный сайт Polysnap
MetaMask Snap — это основная функция и главный фокус проекта. Сайт используется для демонстрации возможностей Snap.
Snap
Polysnap можно разделить на 3 части.
Polywrap Client
Plugin Wrapper
WASM Wrapper
1. Polywrap Client
Polywrap создаёт единую среду выполнения для интернета, которая является безопасной, открытой и принадлежащей пользователям.
Polywrap позволяет создавать бесконечно расширяемое программное обеспечение, работающее где угодно, с помощью Polywrap Client. Polywrap Client поддерживает два типа wrappers:
Wasm Wrapper — любой изолированный Wasm-модуль, собранный и развёрнутый в IPFS с помощью инструментария Polywrap
Plugin Wrapper — любой wrapper возможностей хоста, предоставляющий Wasm-wrappers доступ к различным функциям хоста: HTTP, файловой системе и JSON-RPC.
Вы можете ознакомиться с тем, как мы используем Polywrap Client для вызова любого wrapper с помощью простого JSON-RPC вызова к Polysnap.
export const onRpcRequest: OnRpcRequestHandler = async ({
origin,
request,
}) => {
switch (request.method) {
case 'wrap_invoke':
const invocation = request.params as unknown as InvokerOptions;
const isApproved = await wallet.request({
method: 'snap_confirm',
params: [
{
prompt: `${origin}`.substring(0, 40),
description: `URI: ${invocation.uri}\nMethod: ${invocation.method}`,
textAreaContent: `Args ${JSON.stringify(invocation.args)}`,
},
],
});
if (isApproved === true) {
const client = await getClient();
const response = await client.invoke<any>(invocation);
if (!response.ok) {
throw response.error;
}
return deserializeMap(response.value);
}
throw new Error('User declined invocation');
default:
throw new Error('Method not found.');
}
};
2. Plugin Wrapper
Plugin wrappers встроены непосредственно в Polysnap через Polywrap Client. Эти Plugin wrappers открывают доступ к возможностям, предоставляемым внутри SES-среды MetaMask, например: HTTP, Ethereum JSON-RPC.
В этой MVP мы добавили поддержку трёх различных плагинов.
HTTP Plugin — предоставляет API для выполнения HTTP GET/POST запросов непосредственно из Wasm Wrapper
IPFS Plugin — предоставляет API для хранения, закрепления и получения файлов из IPFS
IPFS URI Resolver Plugin — предоставляет API для разрешения развёрнутых Wasm Wrappers из IPFS
3. Wasm Wrapper
Wasm wrappers — это Wasm-модули, собранные и развёрнутые в IPFS с помощью инструментария Polywrap. Поскольку Wasm является изолированной средой, он не может выполнять никакой ввод-вывод, если хост не предоставит для этого API. Благодаря этому любые Wasm wrappers можно безопасно запускать внутри MetaMask Snap. Polysnap не может выполнять никакие функции хоста, например доступ в интернет, без помощи Plugin wrappers. Все развёрнутые в IPFS wrappers можно найти по адресу: wrappers.io
export async function getClient(): Promise<PolywrapClient> {
const ipfsResolverWrapperResult = await ipfsResolverPlugin(
{},
).createWrapper();
if (!ipfsResolverWrapperResult.ok) {
throw ipfsResolverWrapperResult.error;
}
const ipfsUriResolver = new WrapperResolver(
Uri.from('ens/ipfs-resolver.polywrap.eth'),
ipfsResolverWrapperResult.value,
);
const ipfsWrapperResult = await ipfsPlugin({}).createWrapper();
if (!ipfsWrapperResult.ok) {
throw ipfsWrapperResult.error;
}
const ipfsResolver = new WrapperResolver(
Uri.from('ens/ipfs.polywrap.eth'),
ipfsWrapperResult.value,
);
const httpWrapperResult = await httpPlugin({}).createWrapper();
if (!httpWrapperResult.ok) {
throw httpWrapperResult.error;
}
const httpResolver = new WrapperResolver(
Uri.from('ens/http.polywrap.eth'),
httpWrapperResult.value,
);
const resolver = RecursiveResolver.from([
httpResolver,
ipfsResolver,
ipfsUriResolver,
new ExtendableUriResolver(),
]);
return new PolywrapClient({
interfaces: [
{
interface: new Uri('wrap://ens/uri-resolver.core.polywrap.eth'),
implementations: [
new Uri('wrap://ens/ipfs-resolver.polywrap.eth'),
],
},
],
envs: [
{
uri: new Uri('wrap://ens/ipfs.polywrap.eth'),
env: {
provider: defaultIpfsProviders[0],
fallbackProviders: defaultIpfsProviders.slice(1),
},
},
],
resolver,
});
}
Сайт Polysnap
Сайт Polysnap — это простой демонстрационный ресурс, созданный для демонстрации PolySnap в действии. На нём есть кнопка для подключения кошелька MetaMask и установки Snap, а также панель запросов, которая отправляет JSON RPC вызов к Polysnap и отображает результат.
Для отправки вызова к Snap пользователь указывает три элемента:
uri, который разрешается в Wasm wrapper (в хакатонном проекте поддерживаются только IPFS URI, однако будущая версия может поддерживать и ENS-разрешение)
Имя вызываемого method
JSON-объект args, содержащий аргументы, которые будут переданы вызываемому методу
При нажатии кнопки «Invoke» сайт считывает значения из этих полей и передаёт их в Snap. Snap открывает окно подтверждения для запроса одобрения вызова, гарантируя, что приложение не выполнит никаких вызовов без согласия конечного пользователя.
Если вызов одобрен, Polywrap Client в Snap обрабатывает его и возвращает результат. Результат отображается в блоке под кнопками. Разумеется, в реальном приложении разработчики, как правило, настраивают вызовы программно и используют результат иначе.
Как следует из названия, Polysnap — это один Snap с возможностями многих. С помощью одного лишь Polysnap разработчики могут вызывать любой метод в любом Polywrap Wasm wrapper, написанном на любом языке, компилируемом в Wasm.
Wrappers загружаются во время выполнения и кэшируются. Поскольку Wasm wrappers изолированы и не имеют состояния, Polysnap добавляет дополнительный уровень безопасности к уже защищённой среде Snap.
И всё это полностью децентрализовано.
Каковы следующие шаги, если вы будете развивать проект?
Вот список всех улучшений, которые мы предусмотрели для следующей версии Polysnap:
Добавить поддержку дополнительных Plugin Wrappers: Cache, Concurrency, Ethereum, Near, Tezos и других
Добавить систему безопасности на основе разрешений для доступа к каждому плагину Polywrap, чтобы конечный пользователь мог самостоятельно управлять безопасностью
Создать сайт для установки PolySnap с демонстрацией возможностей, документацией и простой установкой для конечных пользователей
Добавить поддержку IPFS, ENS и HTTP Polywrap URI Resolvers
Поддержать возможность разработчиков приложений передавать пользовательские конфигурации для каждого вызова Polywrap Client, настраиваемые при вызове через JSON-RPC с MetaMask Snap
Поддержать пользовательские решения для управления кэшем wrappers, кэшируемых PolySnap
Расскажите немного о себе и своей команде.
Мы оба являемся участниками dOrg — DAO фрилансеров-разработчиков и дизайнеров — а также разработчиками Polywrap.
Kris — Я программист в сфере Web3. Моя жизнь изменилась в 2020 году, когда друг познакомил меня с dOrg и децентрализованным вебом. Вскоре я присоединился к команде Polywrap, чтобы помочь создать инструменты SDK следующего поколения для разработчиков.
Niraj — Я Web3-разработчик в dOrg и в настоящее время работаю над проектом Polywrap в качестве основного разработчика. Я занимаюсь Web3-разработкой уже 2 года и до прихода в Polywrap вносил вклад в проекты Badger, Opolis, Coordinape и Llama.
Какие возможности вы видите в MetaMask Snaps и что это открывает для пространства Web3?
Мы считаем, что MetaMask Snaps способен превратить MetaMask в хаб, который приведёт миллионы новых пользователей в Web3. Опыт разработчиков и безопасность — ключевые факторы успеха любой экосистемы плагинов. Мы верим, что Polysnap может обеспечить и то, и другое для MetaMask Snaps, делая его ещё более удобным, расширяемым и безопасным.
Есть ли советы для разработчиков, желающих попробовать MetaMask Snaps?
MetaMask Snaps позволяет расширять возможности MetaMask, создавая новые расширения MetaMask Snaps для вашего кошелька MetaMask. Это очень мощный инструмент, открывающий огромное количество сценариев использования: интеграция различных L1-кошельков непосредственно в MetaMask, предоставление более детальной информации о транзакциях и многое другое. Мы хотим сделать опыт разработчиков при реализации подобных сценариев ещё проще с помощью Polysnap.
MetaMask Snaps — это всё ещё новая технология, но всего за один уикенд мы увидели, как команды создают невероятные MetaMask Snaps — включая даже кошелёк Cosmos внутри MetaMask. Даже если функция MetaMask Snaps ещё находится в предпродакшн-состоянии — начинайте как можно раньше!
Или вместо написания нового Snap вы можете рассмотреть создание Polywrap Wasm wrapper на таком языке, как Rust или AssemblyScript. Тогда вы сможете не только вызывать его через Polysnap без необходимости писать собственный Snap, но и использовать его где угодно с помощью Polywrap client.
Разработка с MetaMask Snaps
Чтобы начать работу с MetaMask Snaps:
Ознакомьтесь с документацией для разработчиков
Установите MetaMask Flask
Изучите руководство по MetaMask Snaps
Оставайтесь на связи с нами в Twitter, обсуждениях GitHub и Discord
Следите за нашей командой на следующем хакатоне рядом с вами! Удачного BUIDLing'а ⚒️
Отказ от ответственности: MetaMask Snaps, как правило, разрабатываются третьими сторонами, а не Consensys Software. Использование MetaMask Snaps, разработанных третьими сторонами, осуществляется по вашему собственному усмотрению и на ваш риск, и вы соглашаетесь с тем, что несёте единоличную ответственность за любые убытки или ущерб, возникшие в результате такой деятельности. Consensys не даёт никаких явных или подразумеваемых гарантий, ни устных, ни письменных, в отношении Snaps, разработанных третьими сторонами, и отказывается от какой-либо ответственности за MetaMask Snaps, разработанные третьими сторонами. Использование программного обеспечения, связанного с блокчейном, сопряжено с рисками, которые вы полностью принимаете на себя при использовании MetaMask Snaps.