Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Capsule Integration to Bocknative #1

Merged
merged 1 commit into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ For full documentation, check out the README.md for each package or the [docs pa
- [Portis](packages/portis/README.md)
- [MEW-Wallet](packages/mew-wallet/README.md)
- [Web3Auth](packages/web3auth/README.md)
- [Capsule](packages/capsule/README.md)
- [Sequence](packages/sequence/README.md)
- [Taho (previously Tally Ho)](packages/tallyho/README.md)
- [Enkrypt](packages/enkrypt/README.md)
Expand Down
1 change: 1 addition & 0 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"@web3-onboard/arcana-auth": "^2.0.0",
"@web3-onboard/bitget": "^2.0.0",
"@web3-onboard/blocto": "^2.0.0",
"@web3-onboard/capsule": "^2.0.0-alpha.1",
"@web3-onboard/cede-store": "^2.1.0",
"@web3-onboard/coinbase": "^2.2.5",
"@web3-onboard/core": "^2.21.2",
Expand Down
8 changes: 7 additions & 1 deletion docs/src/lib/services/onboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const intiOnboard = async (theme) => {
const { default: bloctoModule } = await import('@web3-onboard/blocto')
const { default: venlyModule } = await import('@web3-onboard/venly')
const { default: bitgetModule } = await import('@web3-onboard/bitget')
const { default: capsuleModule, Environment } = await import('@web3-onboard/capsule')
const INFURA_ID = '8b60d52405694345a99bcb82e722e0af'

const injected = injectedModule()
Expand Down Expand Up @@ -127,6 +128,10 @@ const intiOnboard = async (theme) => {
environment: 'staging'
})

const capsule = capsuleModule({
environment: Environment.DEVELOPMENT,
})

return Onboard({
connect: { autoConnectAllPreviousWallet: true },
wallets: [
Expand Down Expand Up @@ -156,7 +161,8 @@ const intiOnboard = async (theme) => {
portis,
frame,
infinityWallet,
blocto
blocto,
capsule
// venly
],
chains: [
Expand Down
64 changes: 64 additions & 0 deletions docs/src/routes/docs/[...4]wallets/[...5]capsule/+page.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Capsule

## Wallet module for connecting Capsule to web3-onboard

[Capsule](https://usecapsule.com/) is a signing solution that you can use to create secure embedded MPC wallets with just an email or social login that are recoverable, portable, and permissioned across different crypto applications, so your users don't need to create different signers or contract accounts for every app they use.

Adding the Capsule Module to web3onboard gives your users the ability to log in with Capsule wallets created elsewhere. You can also [request a Capsule API Key](https://form.typeform.com/to/hLaJeYJW) to allow users to easily create embedded wallets within web3onboard without any extra integration steps.

To learn more, check out the [Capsule Developer Docs](https://docs.usecapsule.com/)

### Install

`yarn add @web3-onboard/capsule`

## Options

```typescript
type CapsuleInitOptions = {
environment: Environment
appName: string
apiKey?: string
}
```

`environment` - The environment to which you want to connect, either `Environment.DEVELOPMENT` for testnets and development only or `Environment.PRODUCTION` for production use.
`appName` - Your Application's name - displayed in the modal when your users are prompted to log in.
`apiKey` - Your Capsule API Key. Required for new user creation, but not required if you are only allowing users to log in. To get an API key, fill out [this form](https://form.typeform.com/to/hLaJeYJW).

## Usage

```typescript
import Onboard from '@web3-onboard/core'
import capsuleModule from '@web3-onboard/capsule'

// initialize the module with options
const capsule = capsuleModule()

const onboard = Onboard({
// ... other Onboard options
wallets: [
capsule
//... other wallets
]
})

const connectedWallets = await onboard.connectWallet()
console.log(connectedWallets)
```

## Build env settings (webpack config)

You may need to add the following rule to your webpack config module
in order to handle certain styling files (See the config for the
Blocknative demo app):

```typescript
{
test: /\.(woff(2)?|eot|ttf|otf|svg)$/,
type: 'asset/resource',
generator: {
filename: 'fonts/[name][ext][query]'
}
}
```
64 changes: 64 additions & 0 deletions packages/capsule/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# @web3-onboard/capsule

## Wallet module for connecting Capsule to web3-onboard

[Capsule](https://usecapsule.com/) is a signing solution that you can use to create secure embedded MPC wallets with just an email or social login that are recoverable, portable, and permissioned across different crypto applications, so your users don't need to create different signers or contract accounts for every app they use.

Adding the Capsule Module to web3onboard gives your users the ability to log in with Capsule wallets created elsewhere. You can also [request a Capsule API Key](https://form.typeform.com/to/hLaJeYJW) to allow users to easily create embedded wallets within web3onboard without any extra integration steps.

To learn more, check out the [Capsule Developer Docs](https://docs.usecapsule.com/)

### Install

`yarn add @web3-onboard/capsule`

## Options

```typescript
type CapsuleInitOptions = {
environment: Environment
appName: string
apiKey?: string
}
```

`environment` - The environment to which you want to connect, either `Environment.DEVELOPMENT` for testnets and development only or `Environment.PRODUCTION` for production use.
`appName` - Your Application's name - displayed in the modal when your users are prompted to log in.
`apiKey` - Your Capsule API Key. Required for new user creation, but not required if you are only allowing users to log in. To get an API key, fill out [this form](https://form.typeform.com/to/hLaJeYJW).

## Usage

```typescript
import Onboard from '@web3-onboard/core'
import capsuleModule from '@web3-onboard/capsule'

// initialize the module with options
const capsule = capsuleModule()

const onboard = Onboard({
// ... other Onboard options
wallets: [
capsule
//... other wallets
]
})

const connectedWallets = await onboard.connectWallet()
console.log(connectedWallets)
```

## Build env settings (webpack config)

You may need to add the following rule to your webpack config module
in order to handle certain styling files (See the config for the
Blocknative demo app):

```typescript
{
test: /\.(woff(2)?|eot|ttf|otf|svg)$/,
type: 'asset/resource',
generator: {
filename: 'fonts/[name][ext][query]'
}
}
```
67 changes: 67 additions & 0 deletions packages/capsule/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
{
"name": "@web3-onboard/capsule",
"version": "2.0.0-alpha.1",
"description": "Capsule SDK wallet module for connecting to Web3-Onboard. Web3-Onboard makes it simple to connect Ethereum hardware and software wallets to your dapp. Features standardised spec compliant web3 providers for all supported wallets, framework agnostic modern javascript UI with code splitting, CSS customization, multi-chain and multi-account support, reactive wallet state subscriptions and real-time transaction state change notifications.",
"module": "dist/index.js",
"browser": "dist/index.js",
"main": "dist/index.js",
"type": "module",
"typings": "dist/index.d.ts",
"files": [
"dist"
],
"homepage": "https://onboard.blocknative.com",
"bugs": "https://github.com/blocknative/web3-onboard/issues",
"repository": {
"type": "git",
"url": "https://github.com/blocknative/web3-onboard.git",
"directory": "packages/capsule"
},
"scripts": {
"build": "tsc",
"dev": "tsc -w"
},
"license": "MIT",
"keywords": [
"Ethereum",
"Web3",
"EVM",
"dapp",
"Multichain",
"Wallet",
"Transaction",
"Provider",
"Hardware Wallet",
"Notifications",
"React",
"Svelte",
"Vue",
"Next",
"Nuxt",
"MetaMask",
"Coinbase",
"WalletConnect",
"Ledger",
"Trezor",
"Connect Wallet",
"Ethereum Hooks",
"Blocknative",
"Mempool",
"pending",
"confirmed",
"Injected Wallet",
"Crypto",
"Crypto Wallet",
"Capsule"
],
"dependencies": {
"@usecapsule/web-sdk": "^0.29.1",
"@wagmi/chains": "^1.8.0",
"@web3-onboard/common": "^2.3.3",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"typescript": "^5.2.2"
}
}
4 changes: 4 additions & 0 deletions packages/capsule/src/icon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export default `<svg width="77" height="129" viewBox="0 0 77 129" fill="none" xmlns="http://www.w3.org/2000/svg">
<path transform="scale(1, 0.770) translate(0, 19.35)" d="M73.4019 48.7847C72.4708 52.0066 68.9114 53.6023 65.8093 52.319C63.0129 51.1622 61.6114 48.0644 62.2981 45.1204C62.7343 43.25 63.0486 41.4685 63.241 39.7758C63.6196 36.5516 63.6156 33.6856 63.2289 31.1778C62.8421 28.67 62.0764 26.5924 60.9316 24.9449C59.8224 23.2652 58.3734 22.0554 56.5847 21.3154C53.4068 20.0008 49.8924 20.5191 46.0413 22.8703C42.2068 25.1814 38.2569 29.276 34.1915 35.1542C30.1427 40.9922 26.1984 48.5405 22.3585 57.7988C18.4522 67.2175 15.8554 75.4406 14.5682 82.4681C13.3167 89.4633 13.2273 95.108 14.3 99.4021C15.4083 103.664 17.5419 106.448 20.7007 107.755C22.4514 108.479 24.2873 108.675 26.2086 108.343C28.1655 107.979 30.1519 107.087 32.1677 105.667C34.2024 104.255 36.2203 102.319 38.2212 99.8597C39.2693 98.5877 40.2905 97.178 41.2847 95.6308C42.9275 93.0742 46.1383 91.894 48.9351 93.0881C52.0134 94.4024 53.3673 98.0414 51.7104 100.947C49.6748 104.516 47.4968 107.836 45.1763 110.907C41.7356 115.494 38.1351 119.311 34.3748 122.357C30.6311 125.363 26.875 127.378 23.1063 128.401C19.3543 129.385 15.7372 129.156 12.2549 127.716C7.117 125.59 3.56991 121.188 1.61359 114.509C-0.342729 107.831 -0.520163 99.2817 1.08128 88.8625C2.68272 78.4434 6.2262 66.6207 11.7117 53.3944C17.2139 40.1281 23.0885 29.2697 29.3354 20.8193C35.599 12.3288 41.7868 6.41298 47.8988 3.0719C54.0108 -0.269182 59.6167 -0.884874 64.7165 1.22482C67.9705 2.57093 70.5972 4.78448 72.5966 7.86548C74.596 10.9465 75.9169 14.8033 76.5593 19.436C77.2183 24.0286 77.1382 29.3015 76.3189 35.2547C75.7595 39.481 74.7872 43.991 73.4019 48.7847Z" fill="black"/>
<path transform="scale(1, 0.770) translate(0, 19.35)" d="M53.4845 68.8256C54.8485 65.5369 58.6237 63.9751 61.9167 65.3374L62.2327 65.4681C65.5256 66.8303 67.0894 70.6007 65.7254 73.8894C64.3614 77.1782 60.5862 78.7399 57.2932 77.3777L56.9772 77.2469C53.6842 75.8847 52.1205 72.1143 53.4845 68.8256Z" fill="black"/>
</svg>`
90 changes: 90 additions & 0 deletions packages/capsule/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import type { AppMetadata, WalletInit } from '@web3-onboard/common';
import type { CapsuleInitOptions } from './types';
import type { Chain } from '@wagmi/chains';
import type { Chain as BlocknativeChain } from '@web3-onboard/common';
import { Environment as CapsuleEnvironment } from '@usecapsule/web-sdk';

type ChainId = number;
type ChainsMap = Map<ChainId, Chain>;

async function buildChainsMap(): Promise<ChainsMap> {
const chains = await import ('viem/chains');
const chainEntries = Object.entries(chains);
const chainsMap: ChainsMap = new Map();

for (const [chainName, chainObject] of chainEntries) {
if (chainObject && 'id' in chainObject) {
chainsMap.set(chainObject.id, chainObject as Chain);
}
}

return chainsMap;
}

function getChainsByIds(chainIds: number[], chainsMap: ChainsMap): Chain[] {
return chainIds.map(id => chainsMap.get(id)).filter((c): c is Chain => !!c);
}

function convertChainIdToNumber(chainId: string | number): number {
if (typeof chainId === 'number') {
return chainId;
}
const hexRegex = /^[0-9a-fA-F]+$/;
return hexRegex.test(chainId) ? parseInt(chainId, 16) : Number(chainId);
}

function validateOptions(options: CapsuleInitOptions, chains: BlocknativeChain[], appMetadata: AppMetadata | null): void {
if (!(options.environment in CapsuleEnvironment)) {
throw new Error(`Invalid environment. Must be one of the Environment enum values.`);
}

if (appMetadata == null) {
throw new Error('No appMetadata passed into the Onboard object');
}

if (typeof appMetadata.name !== 'string' || appMetadata.name.trim() === '') {
throw new Error('appName must be a non-empty string.');
}

if (!Array.isArray(chains) || chains.length === 0) {
throw new Error('chains must be a non-empty array.');
}
if (chains.some(chain => typeof Number(chain.id) !== 'number')) {
throw new Error('All elements in chains must be numbers.');
}

if (options.apiKey !== undefined && (typeof options.apiKey !== 'string' || options.apiKey.trim() === '')) {
throw new Error('apiKey must be a non-empty string.');
}
}

function capsule(options: CapsuleInitOptions): WalletInit {
return () => {
return {
label: 'Capsule',
getIcon: async () => (await import('./icon')).default,
getInterface: async ({ chains, appMetadata }) => {
const { default: Capsule, CapsuleEIP1193Provider } = await import('@usecapsule/web-sdk');
validateOptions(options, chains, appMetadata);
const capsule = new Capsule(options.environment, options.apiKey);
const chainsMap = await buildChainsMap();

const providerOpts = {
capsule: capsule,
chainId: convertChainIdToNumber(chains[0].id).toString(),
appName: appMetadata?.name as string,
chains: getChainsByIds(chains.map(ch => convertChainIdToNumber(ch.id)), chainsMap),
};
const provider = new CapsuleEIP1193Provider(providerOpts);

return {
instance: capsule,
provider: provider
}
},
}
}
}

export default capsule;
export { CapsuleEnvironment as Environment };
17 changes: 17 additions & 0 deletions packages/capsule/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Environment } from '@usecapsule/web-sdk'
import { ChainId } from '@web3-onboard/common'

/**
* Options for initializing the Capsule environment.
*
* @typedef {Object} CapsuleInitOptions
* @property {Environment} environment - Specifies the working environment for the application.
* 'DEVELOPMENT' should be used for testing with non-real funds and wallets on a testnet.
* 'PRODUCTION' should be used when the application is ready for live deployment with real transactions.
* @property {string} [apiKey] - Optional API key necessary for performing transactions and wallet creation.
* This key needs to be obtained by completing a form available at https://7f4shq8oyfd.typeform.com/to/F86oVLhb.
*/
export type CapsuleInitOptions = {
environment: Environment
apiKey?: string
}
22 changes: 22 additions & 0 deletions packages/capsule/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"extends": "../../tsconfig.json",
"include": [
"src/**/*"
],
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"declaration": true,
"declarationDir": "dist",
"allowSyntheticDefaultImports": true,
"paths": {
"*": [
"./src/*",
"./node_modules/*"
]
},
"typeRoots": [
"node_modules/@types"
]
}
}
1 change: 1 addition & 0 deletions packages/demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"@web3-onboard/arcana-auth": "^2.0.0",
"@web3-onboard/bitget": "2.0.1",
"@web3-onboard/blocto": "2.0.0",
"@web3-onboard/capsule": "2.0.0-alpha.1",
"@web3-onboard/cede-store": "^2.1.0",
"@web3-onboard/coinbase": "^2.2.6",
"@web3-onboard/core": "^2.21.2",
Expand Down
Loading