mirror of
https://github.com/pezkuwichain/bizinikiwi-connect.git
synced 2026-04-22 02:57:55 +00:00
feat: initial commit for bizinikiwi-connect with clean CI
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
# @bizinikiwi/discovery
|
||||
|
||||
## 0.2.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 92316c0: chore(deps-dev): bump vitest in the npm_and_yarn group
|
||||
|
||||
Bumps the npm_and_yarn group with 1 update: [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest).
|
||||
|
||||
Updates `vitest` from 2.1.4 to 2.1.9
|
||||
|
||||
- [Release notes](https://github.com/vitest-dev/vitest/releases)
|
||||
- [Commits](https://github.com/vitest-dev/vitest/commits/v2.1.9/packages/vitest)
|
||||
|
||||
***
|
||||
|
||||
updated-dependencies:
|
||||
|
||||
- dependency-name: vitest
|
||||
dependency-type: direct:development
|
||||
dependency-group: npm_and_yarn
|
||||
...
|
||||
|
||||
Signed-off-by: dependabot[bot] <support@github.com>
|
||||
|
||||
## 0.2.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 09f1c22: chore(deps-dev): bump vitest from 2.0.5 to 2.1.4
|
||||
|
||||
Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 2.0.5 to 2.1.4.
|
||||
|
||||
- [Release notes](https://github.com/vitest-dev/vitest/releases)
|
||||
- [Commits](https://github.com/vitest-dev/vitest/commits/v2.1.4/packages/vitest)
|
||||
|
||||
***
|
||||
|
||||
updated-dependencies:
|
||||
|
||||
- dependency-name: vitest
|
||||
dependency-type: direct:development
|
||||
update-type: version-update:semver-minor
|
||||
...
|
||||
|
||||
Signed-off-by: dependabot[bot] <support@github.com>
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 198b375: chore: catalog and upgrade papi dependencies
|
||||
|
||||
## 0.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- b476e7e: update build system to tshy
|
||||
|
||||
## 0.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- e8fef4e: update docs
|
||||
@@ -0,0 +1,128 @@
|
||||
<br /><br />
|
||||
|
||||
<div align="center">
|
||||
<h1 align="center">@bizinikiwi/discovery</h1>
|
||||
<p align="center">
|
||||
<a href="https://www.npmjs.com/package/@bizinikiwi/discovery">
|
||||
<img alt="npm" src="https://img.shields.io/npm/v/@bizinikiwi/discovery" />
|
||||
</a>
|
||||
<a href="https://github.com/pezkuwichain/bizinikiwi-connect/blob/master/LICENSE">
|
||||
<img alt="GPL-3.0-or-later" src="https://img.shields.io/npm/l/@bizinikiwi/discovery" />
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<br /><br />
|
||||
|
||||
This package implements the discovery protocol that browsers use to find compliant browser extensions. It introduces a set of window `CustomEvent`s to provide a two-way communication protocol between Pezkuwi Wallet Provider libraries and injected scripts provided by browser extensions.
|
||||
|
||||
## Main Export
|
||||
|
||||
The main export is a function called `getProviders`. This function dispatches an event on the window object that compliant browser extensions (or similar) may respond to by providing back an interface of the correct shape. An array of all such interfaces that we get back will be given back to the caller of `getProviders`.
|
||||
|
||||
## How It Works
|
||||
|
||||
The discovery protocol is quite simple and can be implemented in these steps:
|
||||
|
||||
1. The extension injects an inpage script that registers a listener for the `bizinikiwiDiscovery:requestProvider` event.
|
||||
2. The listener announces the provider by invoking the `onProvider` callback from the event payload synchronously.
|
||||
3. Optionally, the script can dispatch the `bizinikiwiDiscovery:announceProvider` event with the provider details when the script is loaded.
|
||||
|
||||
Refer to `src/index.ts` in this package for an implementation of this protocol.
|
||||
|
||||
## Basic Usage Example
|
||||
|
||||
```ts
|
||||
import { getProviders } from "@bizinikiwi/discovery"
|
||||
|
||||
const providers = getProviders()
|
||||
const firstProvider = providers.length > 0 ? providers[0].provider : null
|
||||
|
||||
console.log(firstProvider)
|
||||
```
|
||||
|
||||
## Example with rDNS Filter
|
||||
|
||||
This example demonstrates how to filter providers based on a specific rDNS value. This approach is useful when you need to target specific extensions rather than all extensions matching a certain interface.
|
||||
|
||||
```ts
|
||||
import { getProviders } from "@bizinikiwi/discovery"
|
||||
|
||||
const provider = getProviders()
|
||||
.filter((detail) =>
|
||||
detail.info.rdns.startsWith("io.github.pezkuwichain.BizinikiwiConnect"),
|
||||
)
|
||||
.map((detail) => detail.provider)[0]
|
||||
|
||||
console.log(provider)
|
||||
```
|
||||
|
||||
## React Example
|
||||
|
||||
```tsx
|
||||
import React, { useEffect, useState } from "react"
|
||||
import { getProviders } from "@bizinikiwi/discovery"
|
||||
|
||||
const SmoldotProviderComponent = () => {
|
||||
const [provider, setProvider] = useState(null)
|
||||
|
||||
useEffect(() => {
|
||||
const providers = getProviders()
|
||||
if (providers.length > 0) {
|
||||
setProvider(providers[0].provider)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div>
|
||||
{provider ? <p>Provider: {provider}</p> : <p>Loading provider...</p>}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default SmoldotProviderComponent
|
||||
```
|
||||
|
||||
## Extension Example
|
||||
|
||||
```ts
|
||||
import { getLightClientProvider } from "@bizinikiwi/light-client-extension-helpers/web-page"
|
||||
|
||||
const rpc = createRpc(
|
||||
(msg: any) =>
|
||||
window.postMessage({ msg, origin: "bizinikiwi-wallet-template/web" }),
|
||||
handlers,
|
||||
).withClient<BackgroundRpcSpec>()
|
||||
window.addEventListener("message", ({ data }) => {
|
||||
if (data?.origin !== "bizinikiwi-wallet-template/extension") return
|
||||
rpc.handle(data.msg, undefined)
|
||||
})
|
||||
|
||||
const provider = await getLightClientProvider(CHANNEL_ID).then(
|
||||
(lightClientProvider) => ({
|
||||
...lightClientProvider,
|
||||
async getAccounts(chainId: string) {
|
||||
return rpc.client.getAccounts(chainId)
|
||||
},
|
||||
async createTx(chainId: string, from: string, callData: string) {
|
||||
return rpc.client.createTx(chainId, from, callData)
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
window.addEventListener(
|
||||
"bizinikiwiDiscovery:requestProvider",
|
||||
({ detail: { onProvider } }) => onProvider(detail),
|
||||
)
|
||||
|
||||
window.dispatchEvent(
|
||||
new CustomEvent("bizinikiwiDiscovery:announceProvider", {
|
||||
detail,
|
||||
}),
|
||||
)
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- The `detail.provider` can be a promise, depending on the library implementation which allows announcing provider details while the provider is being initialized.
|
||||
- The `bizinikiwiDiscovery:requestProvider` event payload uses an `onProvider` callback to respond with the provider details synchronously to the DApp, allowing to get all the providers without needing to wait for any macrotasks (e.g., `setTimeout`), microtasks, or any arbitrary time to listen to an event (e.g., `bizinikiwiDiscovery:announceProvider`).
|
||||
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"name": "@bizinikiwi/discovery",
|
||||
"version": "0.2.2",
|
||||
"author": "Parity Technologies (https://github.com/pezkuwichain)",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/pezkuwichain/bizinikiwi-connect.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"main": "./dist/commonjs/index.js",
|
||||
"types": "./dist/commonjs/index.d.ts",
|
||||
"module": "./dist/esm/index.js",
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"import": {
|
||||
"@bizinikiwi-connect/source": "./src/index.ts",
|
||||
"types": "./dist/esm/index.d.ts",
|
||||
"default": "./dist/esm/index.js"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/commonjs/index.d.ts",
|
||||
"default": "./dist/commonjs/index.js"
|
||||
}
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"tshy": {
|
||||
"project": "./tsconfig.build.json",
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
"sourceDialects": [
|
||||
"@bizinikiwi-connect/source"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"prepare": "corepack pnpm turbo build",
|
||||
"deep-clean": "npm run clean && rimraf dist node_modules",
|
||||
"clean": "rimraf dist .tshy .tshy-build",
|
||||
"build": "npm run clean && tshy",
|
||||
"dev": "pnpm build --watch",
|
||||
"lint": "prettier --check README.md \"src/**/*.{js,jsx,ts,tsx,json,md}\""
|
||||
},
|
||||
"prettier": {
|
||||
"printWidth": 80,
|
||||
"semi": false,
|
||||
"trailingComma": "all"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "5.6.2",
|
||||
"vitest": "^2.1.9"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
export type ProviderDetail = {
|
||||
kind: string
|
||||
info: ProviderInfo
|
||||
provider: unknown
|
||||
}
|
||||
|
||||
export type OnProvider = {
|
||||
onProvider(detail: ProviderDetail): void
|
||||
}
|
||||
|
||||
export type ProviderInfo = {
|
||||
uuid: string
|
||||
name: string
|
||||
icon: string
|
||||
rdns: string
|
||||
}
|
||||
|
||||
export const getProviders = (): ProviderDetail[] => {
|
||||
const providers: ProviderDetail[] = []
|
||||
|
||||
// When this event is dispatched, event listeners are expected to
|
||||
// respond immediately with a provider. This means the `providers`
|
||||
// array will be populated synchronously.
|
||||
window.dispatchEvent(
|
||||
new CustomEvent<OnProvider>("bizinikiwiDiscovery:requestProvider", {
|
||||
detail: {
|
||||
onProvider(detail) {
|
||||
providers.push(detail)
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
// slice the array to prevent further "asynchronous" updates. Providers
|
||||
// that did not respond synchronously will be dropped.
|
||||
const providersSliced = providers.slice()
|
||||
|
||||
return providersSliced
|
||||
}
|
||||
|
||||
// #region Events
|
||||
export interface AnnounceProviderEvent extends CustomEvent<ProviderDetail> {
|
||||
type: "bizinikiwiDiscovery:announceProvider"
|
||||
}
|
||||
|
||||
export interface RequestProviderEvent extends CustomEvent<OnProvider> {
|
||||
type: "bizinikiwiDiscovery:requestProvider"
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface WindowEventMap {
|
||||
"bizinikiwiDiscovery:announceProvider": AnnounceProviderEvent
|
||||
"bizinikiwiDiscovery:requestProvider": RequestProviderEvent
|
||||
}
|
||||
}
|
||||
// #endregion
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.build.json",
|
||||
"include": ["src"]
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base",
|
||||
"include": ["src", "tests"]
|
||||
}
|
||||
Reference in New Issue
Block a user