feat(connect-explorer-nextra): scaffolding
4
packages/connect-explorer-nextra/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
# NextJS ignore file
|
||||
.next/
|
||||
.env
|
||||
!public/
|
||||
19
packages/connect-explorer-nextra/README.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# connect-explorer-nextra
|
||||
|
||||
Revamped version of `connect-explorer` with a new UI and more features.
|
||||
|
||||
Using [Nextra](https://nextra.site) docs framework.
|
||||
|
||||
## Running
|
||||
|
||||
```bash
|
||||
yarn dev
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
```bash
|
||||
yarn build
|
||||
```
|
||||
|
||||
Static files will be generated in `out/` directory.
|
||||
@@ -0,0 +1,17 @@
|
||||
import React from 'react';
|
||||
|
||||
interface ApiPlaygroundProps {
|
||||
method: string;
|
||||
}
|
||||
|
||||
export const ApiPlayground = ({ method }: ApiPlaygroundProps) => {
|
||||
return (
|
||||
<div className="bg-white border border-neutral-200 fixed d-block bottom-2 left-2 right-2 md:left-64 p-4 z-50 rounded-2xl dark:bg-neutral-900 shadow-xl">
|
||||
<h2 className="text-2xl font-bold">{method} API</h2>
|
||||
<p>This is the API playground... (WIP)</p>
|
||||
<button className="btn bg-green-700 text-white px-8 py-2 font-bold rounded-2xl mt-2">
|
||||
Send
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
46
packages/connect-explorer-nextra/components/Param.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
import React from 'react';
|
||||
import Markdown from 'react-markdown';
|
||||
|
||||
interface ParamProps {
|
||||
name: string;
|
||||
type: string | React.ReactNode;
|
||||
required?: boolean;
|
||||
description?: string;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
export const Param = (props: ParamProps) => {
|
||||
return (
|
||||
<>
|
||||
<div className="mt-2 rounded-2xl bg-gradient-to-b from-neutral-100 to-transparent">
|
||||
<div className="flex flex-row px-4 py-2 gap-4 justify-center items-center">
|
||||
<h3 className="font-bold font-mono text-sm">{props.name}</h3>
|
||||
<div className="flex-1 text-sm">
|
||||
{typeof props.type === 'string' ? (
|
||||
<Markdown>{props.type}</Markdown>
|
||||
) : (
|
||||
props.type
|
||||
)}
|
||||
</div>
|
||||
{props.required ? (
|
||||
<div className="bg-green-200 text-green-700 py-1 px-3 d-inline-block rounded-2xl font-bold">
|
||||
required
|
||||
</div>
|
||||
) : (
|
||||
<div className="bg-blue-200 text-blue-600 py-1 px-3 d-inline-block rounded-2xl font-bold">
|
||||
optional
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{props.description && (
|
||||
<div className="px-8 py-2 bg-white rounded-lg">
|
||||
<Markdown>{props.description}</Markdown>
|
||||
</div>
|
||||
)}
|
||||
{props.children && (
|
||||
<div className="mx-4 px-4 py-2 bg-white rounded-lg">{props.children}</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
5
packages/connect-explorer-nextra/next-env.d.ts
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
||||
22
packages/connect-explorer-nextra/next.config.js
Normal file
@@ -0,0 +1,22 @@
|
||||
const withNextra = require('nextra')({
|
||||
theme: 'nextra-theme-docs',
|
||||
themeConfig: './theme.config.tsx',
|
||||
});
|
||||
|
||||
module.exports = withNextra({
|
||||
output: 'export',
|
||||
images: {
|
||||
unoptimized: true,
|
||||
},
|
||||
transpilePackages: ['@trezor/components'],
|
||||
compiler: {
|
||||
styledComponents: true,
|
||||
},
|
||||
webpack: config => {
|
||||
// Image loader
|
||||
config.module.rules.push({
|
||||
test: /\.(svg)$/,
|
||||
type: 'asset/resource',
|
||||
});
|
||||
},
|
||||
});
|
||||
28
packages/connect-explorer-nextra/package.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "connect-explorer-nextra",
|
||||
"packageManager": "yarn@4.0.2",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@trezor/components": "workspace:^",
|
||||
"next": "^14.1.1",
|
||||
"nextra": "^2.13.4",
|
||||
"nextra-theme-docs": "^2.13.4",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-markdown": "^9.0.1",
|
||||
"styled-components": "^6.1.8"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "next",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"type-check": "yarn g:tsc --build tsconfig.json"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "20.11.24",
|
||||
"autoprefixer": "^10.4.18",
|
||||
"postcss": "^8.4.35",
|
||||
"tailwindcss": "^3.4.1"
|
||||
}
|
||||
}
|
||||
10
packages/connect-explorer-nextra/pages/_app.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import React from 'react';
|
||||
|
||||
import type { AppProps } from 'next/app';
|
||||
|
||||
import '../styles/globals.css';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function MyApp({ Component, pageProps }: AppProps) {
|
||||
return <Component {...pageProps} />;
|
||||
}
|
||||
4
packages/connect-explorer-nextra/pages/_meta.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"index": "Home",
|
||||
"bitcoin": "Bitcoin"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"getPublicKey": "getPublicKey"
|
||||
}
|
||||
132
packages/connect-explorer-nextra/pages/bitcoin/getPublicKey.mdx
Normal file
@@ -0,0 +1,132 @@
|
||||
import { ApiPlayground } from '../../components/ApiPlayground';
|
||||
import { Param } from '../../components/Param';
|
||||
|
||||
<ApiPlayground method="getPublicKey" />
|
||||
|
||||
## Get public key
|
||||
|
||||
Retrieves BIP32 extended public derived by given BIP32 path.
|
||||
User is presented with a description of the requested key and asked to confirm the export.
|
||||
|
||||
```javascript
|
||||
const result = await TrezorConnect.getPublicKey(params);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Params
|
||||
|
||||
[Optional common params](commonParams.md)
|
||||
|
||||
#### Exporting single public key
|
||||
|
||||
<Param name="path" required type="string | Array<number>">
|
||||
minimum length is `1`. [read more](../path.md)
|
||||
</Param>
|
||||
<Param name="coin" type="string">
|
||||
determines network definition specified in
|
||||
[coins.json](https://github.com/trezor/trezor-suite/blob/develop/packages/connect-common/files/coins.json)
|
||||
file. Coin `shortcut`, `name` or `label` can be used. If `coin` is not set API will try to get
|
||||
network definition from `path`.
|
||||
</Param>
|
||||
<Param name="scriptType" type="string">
|
||||
used to distinguish between various address formats (non-segwit, segwit, etc.).
|
||||
</Param>
|
||||
<Param name="ignoreXpubMagic" type="boolean">
|
||||
ignore SLIP-0132 XPUB magic, use xpub/tpub prefix for all account types.
|
||||
</Param>
|
||||
<Param name="ecdsaCurveName" type="string">
|
||||
ECDSA curve name to use
|
||||
</Param>
|
||||
<Param name="crossChain" type="boolean">
|
||||
Advanced feature. Use it only if you are know what you are doing. Allows to generate address
|
||||
between chains. For example Bitcoin path on Litecoin network will display cross chain address in
|
||||
Litecoin format.
|
||||
</Param>
|
||||
<Param
|
||||
name="unlockPath"
|
||||
type="[PROTO.UnlockPath](https://github.com/trezor/trezor-suite/blob/develop/packages/protobuf/src/messages.ts)"
|
||||
>
|
||||
the result of [TrezorConnect.unlockPath](./unlockPath.md) method.
|
||||
</Param>
|
||||
<Param name="suppressBackupWarning" type="boolean">
|
||||
By default, this method will emit an event to show a warning if the wallet does not have a
|
||||
backup. This option suppresses the message.
|
||||
</Param>
|
||||
#### Exporting bundle of public keys
|
||||
|
||||
<Param name="bundle" type="`Array` of Objects with `path`, `coin` and `crossChain` fields" />
|
||||
|
||||
---
|
||||
|
||||
### Example
|
||||
|
||||
Return public key of fifth bitcoin account:
|
||||
|
||||
```javascript
|
||||
TrezorConnect.getPublicKey({
|
||||
path: "m/49'/0'/4'",
|
||||
coin: 'btc',
|
||||
});
|
||||
```
|
||||
|
||||
Return a bundle of public keys for multiple bitcoin accounts:
|
||||
|
||||
```javascript
|
||||
TrezorConnect.getPublicKey({
|
||||
bundle: [
|
||||
{ path: "m/49'/0'/0'" }, // account 1
|
||||
{ path: "m/49'/0'/1'" }, // account 2
|
||||
{ path: "m/49'/0'/2'" }, // account 3
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
### Result
|
||||
|
||||
[HDNodeResponse type](https://github.com/trezor/trezor-suite/blob/develop/packages/connect/src/types/api/getPublicKey.ts)
|
||||
|
||||
Result with only one public key
|
||||
|
||||
```javascript
|
||||
{
|
||||
success: true,
|
||||
payload: {
|
||||
path: Array<number>, // hardended path
|
||||
serializedPath: string, // serialized path
|
||||
xpub: string, // xpub in legacy format
|
||||
xpubSegwit?: string, // optional for segwit accounts: xpub in segwit format
|
||||
chainCode: string, // BIP32 serialization format
|
||||
childNum: number, // BIP32 serialization format
|
||||
publicKey: string, // BIP32 serialization format
|
||||
fingerprint: number, // BIP32 serialization format
|
||||
depth: number, // BIP32 serialization format
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[Read more about BIP32 serialization format](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#Serialization_format)
|
||||
|
||||
Result with bundle of public keys
|
||||
|
||||
```javascript
|
||||
{
|
||||
success: true,
|
||||
payload: [
|
||||
{ path, serializedPath, xpub, xpubSegwit?, chainCode, childNum, publicKey, fingerprint, depth }, // account 1
|
||||
{ path, serializedPath, xpub, xpubSegwit?, chainCode, childNum, publicKey, fingerprint, depth }, // account 2
|
||||
{ path, serializedPath, xpub, xpubSegwit?, chainCode, childNum, publicKey, fingerprint, depth } // account 3
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Error
|
||||
|
||||
```javascript
|
||||
{
|
||||
success: false,
|
||||
payload: {
|
||||
error: string // error message
|
||||
}
|
||||
}
|
||||
```
|
||||
98
packages/connect-explorer-nextra/pages/index.mdx
Normal file
@@ -0,0 +1,98 @@
|
||||
# Trezor Connect SDK
|
||||
|
||||
There are couple of options how to integrate Trezor devices with your project. This page walks you through
|
||||
installation and lets you explore SDK API.
|
||||
|
||||
## Chose your SDK
|
||||
|
||||
Depending on your environment you need to chose the right package.
|
||||
|
||||
| package | environment |
|
||||
| :---------------------------------------------------------------------------------------------------------------- | :-------------------------------- |
|
||||
| [@trezor/connect](https://github.com/trezor/trezor-suite/tree/develop/packages/connect) | node.js |
|
||||
| [@trezor/connect-web](https://github.com/trezor/trezor-suite/tree/develop/packages/connect-web) | web based (DOM required) |
|
||||
| [@trezor/connect-webextension](https://github.com/trezor/trezor-suite/tree/develop/packages/connect-webextension) | webextension using service worker |
|
||||
|
||||
If you are still unsure which package is the right one you may refer to the following table with a collection of examples.
|
||||
|
||||
| env example | package |
|
||||
| :-------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------- |
|
||||
| [node](https://github.com/trezor/trezor-suite/tree/develop/packages/connect-examples/node) | @trezor/connect |
|
||||
| [web app](https://github.com/trezor/trezor-suite/tree/develop/packages/connect-examples/browser-inline-script) | @trezor/connect-web |
|
||||
| [web extension mv2 (foreground or background)](https://github.com/trezor/trezor-suite/tree/develop/packages/connect-examples/webextension-mv2) | @trezor/connect-web |
|
||||
| [web extension mv3 (foreground)](https://github.com/trezor/trezor-suite/tree/develop/packages/connect-examples/webextension-mv3) | @trezor/connect-web |
|
||||
| [web extension mv3 (background)](https://github.com/trezor/trezor-suite/tree/develop/packages/connect-examples/webextension-mv3-sw) | @trezor/connect-webextension |
|
||||
| [electron in main layer](https://github.com/trezor/trezor-suite/tree/develop/packages/connect-examples/electron-main-process) | @trezor/connect |
|
||||
| [electron in renderer layer with popup](https://github.com/trezor/trezor-suite/tree/develop/packages/connect-examples/electron-renderer-with-popup) | @trezor/connect-web |
|
||||
| [Trezor Suite (desktop) electron app](https://github.com/trezor/trezor-suite/blob/develop/packages/suite-desktop/README.md) | @trezor/connect |
|
||||
|
||||
## Quick start
|
||||
|
||||
Import from your selected package
|
||||
|
||||
```javascript
|
||||
// in node
|
||||
import TrezorConnect from '@trezor/connect';
|
||||
// or in web based
|
||||
import TrezorConnect from '@trezor/connect-web';
|
||||
// or in webextension service worker
|
||||
import TrezorConnect from '@trezor/connect-webextension';
|
||||
```
|
||||
|
||||
Initialize in project
|
||||
|
||||
```javascript
|
||||
TrezorConnect.init({
|
||||
lazyLoad: true, // this param will prevent iframe injection until TrezorConnect.method will be called
|
||||
manifest: {
|
||||
email: 'developer@xyz.com',
|
||||
appUrl: 'http://your.application.com',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Trezor Connect Manifest requires that you, as a Trezor Connect integrator, share your e-mail and application url with us.
|
||||
This provides us with the **ability to reach you in case of any required maintenance.**
|
||||
This subscription is mandatory. Trezor Connect raises an error that reads "Manifest not set" if manifest is not provided. It can be either set via `manifest` method or passed as a param in `init` method.
|
||||
|
||||
```javascript
|
||||
TrezorConnect.manifest({
|
||||
email: 'developer@xyz.com',
|
||||
appUrl: 'http://your.application.com',
|
||||
});
|
||||
```
|
||||
|
||||
If you need more customization, refer to [init method documentation](./methods/init.md)
|
||||
|
||||
## API methods
|
||||
|
||||
- [List of methods](methods.md)
|
||||
|
||||
## Handling events
|
||||
|
||||
- [Events](events.md)
|
||||
|
||||
## How it works under the hood
|
||||
|
||||
There is a major difference between node.js based package (`@trezor/connect`) and web based packages (`@trezor/connect-web` and `@trezor/connect-webextension`).
|
||||
In the former the entire SDK logic is a module of the 3rd party application whereas in the latter, there is strict isolation between 3rd party application code and SDK core logic.
|
||||
|
||||
### Node.js
|
||||
|
||||
In node.js core SDK is loaded as a javascript module without any specificities.
|
||||
|
||||

|
||||
|
||||
### Web
|
||||
|
||||
`@trezor/connect-web` imports only a thin layer with API description into your 3rd party application. When initiated, it injects iframe containing core SDK logic from trezor.io
|
||||
into your app. User input, if needed, is served by popup.html page opened on trezor.io on behalf of your application. This way users input such as pin or passphrase is isolated from you and persistent connection between your app and core SDK is kept so events such as device connected/disconnected or blockchain subscriptions are available.
|
||||
|
||||

|
||||
|
||||
### Webextension
|
||||
|
||||
In case of `@trezor/connect-webextension`, TrezorConnect object is created in a service worker. In this env we can't inject iframe so in order to uphold the same security model as with
|
||||
`@trezor/connect-web` we open popup.html and load core SDK logic into it. This however does not build persistent connection between SDK and 3rd party application meaning that events cannot be used.
|
||||
|
||||

|
||||
6
packages/connect-explorer-nextra/postcss.config.js
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
||||
BIN
packages/connect-explorer-nextra/public/connect_flowchart.png
Normal file
|
After Width: | Height: | Size: 66 KiB |
BIN
packages/connect-explorer-nextra/public/login_button.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
packages/connect-explorer-nextra/public/login_dialog.png
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
packages/connect-explorer-nextra/public/login_display.png
Normal file
|
After Width: | Height: | Size: 217 KiB |
BIN
packages/connect-explorer-nextra/public/login_form.png
Normal file
|
After Width: | Height: | Size: 51 KiB |
BIN
packages/connect-explorer-nextra/public/schema-connect-web.jpg
Normal file
|
After Width: | Height: | Size: 171 KiB |
|
After Width: | Height: | Size: 178 KiB |
BIN
packages/connect-explorer-nextra/public/schema-connect.jpg
Normal file
|
After Width: | Height: | Size: 65 KiB |
3
packages/connect-explorer-nextra/styles/globals.css
Normal file
@@ -0,0 +1,3 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
12
packages/connect-explorer-nextra/tailwind.config.js
Normal file
@@ -0,0 +1,12 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: [
|
||||
"./pages/**/*.{js,jsx,ts,tsx,md,mdx}",
|
||||
"./components/**/*.{js,jsx,ts,tsx,md,mdx}",
|
||||
],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
darkMode: "class",
|
||||
};
|
||||
27
packages/connect-explorer-nextra/theme.config.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
|
||||
import { DocsThemeConfig } from 'nextra-theme-docs';
|
||||
|
||||
import { TrezorLogo } from '@trezor/components';
|
||||
|
||||
const config: DocsThemeConfig = {
|
||||
logo: <TrezorLogo type="horizontal" width={150} />,
|
||||
project: {
|
||||
link: 'https://github.com/trezor/trezor-suite',
|
||||
},
|
||||
docsRepositoryBase: 'https://github.com/trezor/trezor-suite',
|
||||
darkMode: false,
|
||||
primaryHue: 140,
|
||||
primarySaturation: 40,
|
||||
useNextSeoProps() {
|
||||
return {
|
||||
titleTemplate: '%s – Trezor Connect',
|
||||
};
|
||||
},
|
||||
footer: {
|
||||
text: 'Copyright belongs to Trezor company s.r.o. All rights reserved.',
|
||||
},
|
||||
};
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default config;
|
||||
19
packages/connect-explorer-nextra/tsconfig.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"types": ["web", "node"],
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"emitDeclarationOnly": false,
|
||||
"noEmit": true
|
||||
},
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "../components"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
"publishConfig": {
|
||||
"main": "lib/index"
|
||||
},
|
||||
"main": "src/index",
|
||||
"main": "src/index.ts",
|
||||
"files": [
|
||||
"lib/",
|
||||
"!**/*.map"
|
||||
|
||||