Skip to content

Commit

Permalink
feat: alph (#229)
Browse files Browse the repository at this point in the history
* feat: support alph

* fix: update version

* fix: version
  • Loading branch information
huanxiangspace authored Sep 7, 2024
1 parent 9a891bd commit 6d562e3
Show file tree
Hide file tree
Showing 12 changed files with 2,092 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/providers/inpage-providers-hub/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"@onekeyfe/cross-inpage-provider-core": "2.1.4",
"@onekeyfe/cross-inpage-provider-types": "2.1.4",
"@onekeyfe/onekey-algo-provider": "2.1.4",
"@onekeyfe/onekey-alph-provider": "2.1.4",
"@onekeyfe/onekey-aptos-provider": "2.1.4",
"@onekeyfe/onekey-btc-provider": "2.1.4",
"@onekeyfe/onekey-cardano-provider": "2.1.4",
Expand Down
11 changes: 11 additions & 0 deletions packages/providers/inpage-providers-hub/src/injectWeb3Provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { ProviderSolana, registerSolanaWallet, WalletIcon } from '@onekeyfe/onek
// import { ProviderStarcoin } from '@onekeyfe/onekey-starcoin-provider';
import { ProviderAptos, ProviderAptosMartian } from '@onekeyfe/onekey-aptos-provider';
import { ProviderConflux } from '@onekeyfe/onekey-conflux-provider';
import { ProviderAlph } from '@onekeyfe/onekey-alph-provider';
import { ProviderTron } from '@onekeyfe/onekey-tron-provider';
import { ProviderCardano, defineWindowCardanoProperty } from '@onekeyfe/onekey-cardano-provider';
// import { ProviderPrivateExternalAccount } from '@onekeyfe/onekey-private-external-account-provider';
Expand Down Expand Up @@ -46,6 +47,7 @@ export type IWindowOneKeyHub = {
ton?: ProviderTon;
unisat?: ProviderBtc;
btcwallet?: ProviderBtcWallet;
alephium?: ProviderAlph;
scdo?: ProviderScdo;
$private?: ProviderPrivate;
$walletInfo?: {
Expand Down Expand Up @@ -105,6 +107,10 @@ function injectWeb3Provider(): unknown {
bridge,
});

const alephium = new ProviderAlph({
bridge,
});

const tonconnect = new ProviderTon({
bridge,
});
Expand Down Expand Up @@ -150,6 +156,7 @@ function injectWeb3Provider(): unknown {
sui,
tonconnect,
cardano,
alephium,
cosmos,
scdo,
webln,
Expand Down Expand Up @@ -194,6 +201,10 @@ function injectWeb3Provider(): unknown {
defineWindowProperty('petra', martian, { enumerable: true });
defineWindowProperty('martian', martianProxy, { enumerable: true });
defineWindowProperty('conflux', conflux);
defineWindowProperty('alephium', alephium);
defineWindowProperty('alephiumProviders', {
alephium,
});
defineWindowProperty('tronLink', tron);
defineWindowProperty('suiWallet', sui);
defineWindowProperty('onekeyTonWallet', {
Expand Down
2 changes: 2 additions & 0 deletions packages/providers/onekey-alph-provider/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dist/
node_modules/
1 change: 1 addition & 0 deletions packages/providers/onekey-alph-provider/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# cross-inpage-provider
39 changes: 39 additions & 0 deletions packages/providers/onekey-alph-provider/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"name": "@onekeyfe/onekey-alph-provider",
"version": "2.1.4",
"keywords": [
"cross-inpage-provider"
],
"author": "[email protected]",
"repository": "https://github.com/OneKeyHQ/cross-inpage-provider",
"license": "Apache-2.0",
"publishConfig": {
"access": "public"
},
"type": "module",
"files": [
"dist/*"
],
"exports": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/cjs/index.js"
},
"types": "./dist/index.d.ts",
"module": "./dist/index.js",
"main": "./dist/cjs/index.js",
"scripts": {
"prebuild": "rm -rf dist",
"build": "tsc && tsc --project tsconfig.cjs.json",
"start": "tsc --watch"
},
"dependencies": {
"@alephium/get-extension-wallet": "^1.5.2",
"@alephium/walletconnect-provider": "^1.5.2",
"@alephium/web3": "^1.5.2",
"@onekeyfe/cross-inpage-provider-core": "2.1.4",
"@onekeyfe/cross-inpage-provider-errors": "2.1.4",
"@onekeyfe/cross-inpage-provider-types": "2.1.4",
"@onekeyfe/extension-bridge-injected": "2.1.4"
}
}
211 changes: 211 additions & 0 deletions packages/providers/onekey-alph-provider/src/OnekeyAlphProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
import { IInpageProviderConfig } from '@onekeyfe/cross-inpage-provider-core';
import { getOrCreateExtInjectedJsBridge } from '@onekeyfe/extension-bridge-injected';
import { AlephiumWindowObject, EnableOptions, RequestMessage } from '@alephium/get-extension-wallet';
import {
EnableOptionsBase,
Account,
NodeProvider,
ExplorerProvider,
SignDeployContractTxParams,
SignDeployContractTxResult,
SignExecuteScriptTxParams,
SignExecuteScriptTxResult,
SignTransferTxParams,
SignTransferTxResult,
SignUnsignedTxParams,
SignUnsignedTxResult,
SignMessageParams,
SignMessageResult,
InteractiveSignerProvider
} from '@alephium/web3';
import { ProviderAlphBase } from './ProviderAlphBase';

const PROVIDER_EVENTS = {
'disconnect': 'disconnect',
'accountChanged': 'accountChanged',
'message_low_level': 'message_low_level',
} as const;

type OneKeyTonProviderProps = IInpageProviderConfig & {
timeout?: number;
};

function isWalletEventMethodMatch({ method, name }: { method: string; name: string }) {
return method === `wallet_events_${name}`;
}

export class ProviderAlph extends InteractiveSignerProvider implements AlephiumWindowObject {
id = 'alephium';
name = 'Alephium';
icon = 'https://uni.onekey-asset.com/static/logo/onekey.png';
version = '0.0.0';
_accountInfo: Account | undefined;

_base: ProviderAlphBase

constructor(props: OneKeyTonProviderProps) {
super();

this._base = new ProviderAlphBase({
...props,
bridge: props.bridge || getOrCreateExtInjectedJsBridge({ timeout: props.timeout }),
});

this._registerEvents();
}

private bridgeRequest(data: unknown) {
return this._base.request(data);
}

on(eventName: string | symbol, listener: (...args: unknown[]) => void) {
this._base.on(eventName, listener);
}

off(eventName: string | symbol, listener: (...args: unknown[]) => void) {
this._base.off(eventName, listener);
}

emit(eventName: string, ...args: unknown[]) {
return this._base.emit(eventName, ...args);
}

private _registerEvents() {
window.addEventListener('onekey_bridge_disconnect', () => {
this._handleDisconnected();
});

this.on(PROVIDER_EVENTS.message_low_level, (payload) => {
if (!payload) return;
const { method, params } = payload as { method: string; params: unknown };

if (isWalletEventMethodMatch({ method, name: PROVIDER_EVENTS.accountChanged })) {
this._handleAccountChange(params as Account);
}
});
}

private _handleConnected(accountInfo: Account, options: { emit: boolean } = { emit: true }) {
this._accountInfo = accountInfo;
if (options.emit && this._base.isConnectionStatusChanged('connected')) {
this._base.connectionStatus = 'connected';
const address = accountInfo.address ?? null;
this.emit('accountChanged', address);
}
}

private _handleDisconnected(options: { emit: boolean } = { emit: true }) {
this._accountInfo = undefined;

if (options.emit && this._base.isConnectionStatusChanged('disconnected')) {
this._base.connectionStatus = 'disconnected';
this.emit('accountChanged', null);
}
}

private _isAccountsChanged(accountInfo: Account | undefined) {
return accountInfo?.address !== this._accountInfo?.address;
}

// trigger by bridge account change event
private _handleAccountChange(payload: Account) {
const accountInfo = payload;
if (this._isAccountsChanged(accountInfo)) {
this.emit('accountChanged', accountInfo?.address || null);
}
if (!accountInfo) {
this._handleDisconnected();
return;
}

this._handleConnected(accountInfo, { emit: false });
}

async disconnect(): Promise<void> {
await this.bridgeRequest({
method: 'disconnect',
params: [],
});
this._handleDisconnected();
}

isPreauthorized(options: EnableOptions) {
return this.bridgeRequest({
method: 'isPreauthorized',
params: options,
}) as Promise<boolean>;
}

enableIfConnected(options: EnableOptions): Promise<Account | undefined> {
return this.bridgeRequest({
method: 'enableIfConnected',
params: options,
}) as Promise<Account | undefined>;
}

get connectedAccount(): Account | undefined {
return this._accountInfo;
}

get connectedNetworkId(): "mainnet" | "testnet" | "devnet" | undefined {
return "mainnet";
}

unsafeEnable(opt?: EnableOptionsBase | undefined): Promise<Account> {
let params: Record<string, unknown> = {};
if (opt) {
if (opt.onDisconnected) {
// eslint-disable-next-line @typescript-eslint/no-misused-promises
this.on(PROVIDER_EVENTS.disconnect, opt.onDisconnected);
}
params = {}
Object.keys(opt).forEach((key) => {
if (opt[key as keyof EnableOptionsBase] instanceof Function) {
return;
}
params[key] = opt[key as keyof EnableOptionsBase];
})
}
return this.bridgeRequest({ method: 'unsafeEnable', params }) as Promise<Account>;
}

get nodeProvider(): NodeProvider | undefined {
return undefined;
}

get explorerProvider(): ExplorerProvider | undefined {
return undefined;
}

unsafeGetSelectedAccount(): Promise<Account> {
return this.bridgeRequest({ method: 'unsafeGetSelectedAccount' }) as Promise<Account>;
}

signAndSubmitDeployContractTx(params: SignDeployContractTxParams): Promise<SignDeployContractTxResult> {
return this.bridgeRequest({ method: 'signAndSubmitDeployContractTx', params }) as Promise<SignDeployContractTxResult>;
}

signAndSubmitExecuteScriptTx(params: SignExecuteScriptTxParams): Promise<SignExecuteScriptTxResult> {
return this.bridgeRequest({ method: 'signAndSubmitExecuteScriptTx', params }) as Promise<SignExecuteScriptTxResult>;
}

signAndSubmitTransferTx(params: SignTransferTxParams): Promise<SignTransferTxResult> {
return this.bridgeRequest({ method: 'signAndSubmitTransferTx', params }) as Promise<SignTransferTxResult>;
}

signAndSubmitUnsignedTx(params: SignUnsignedTxParams): Promise<SignUnsignedTxResult> {
return this.bridgeRequest({ method: 'signAndSubmitUnsignedTx', params }) as Promise<SignUnsignedTxResult>;
}

signUnsignedTx(params: SignUnsignedTxParams): Promise<SignUnsignedTxResult> {
return this.bridgeRequest({ method: 'signUnsignedTx', params }) as Promise<SignUnsignedTxResult>;
}

signMessage(params: SignMessageParams): Promise<SignMessageResult> {
return this.bridgeRequest({ method: 'signMessage', params }) as Promise<SignMessageResult>;
}

request(message: RequestMessage) {
return this.bridgeRequest({ method: 'addNewToken', params: message.params }) as Promise<boolean>;
}
}
17 changes: 17 additions & 0 deletions packages/providers/onekey-alph-provider/src/ProviderAlphBase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { IInjectedProviderNames } from '@onekeyfe/cross-inpage-provider-types';

import { ProviderBase, IInpageProviderConfig } from '@onekeyfe/cross-inpage-provider-core';

class ProviderAlphBase extends ProviderBase {
constructor(props: IInpageProviderConfig) {
super(props);
}

protected providerName = IInjectedProviderNames.alephium;

request(data: unknown) {
return this.bridgeRequest(data);
}
}

export { ProviderAlphBase };
2 changes: 2 additions & 0 deletions packages/providers/onekey-alph-provider/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './OnekeyAlphProvider';
export * from './ProviderAlphBase';
7 changes: 7 additions & 0 deletions packages/providers/onekey-alph-provider/tsconfig.cjs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../../../tsconfig.cjs.json",
"include": ["./src"],
"compilerOptions": {
"outDir": "./dist/cjs"
}
}
7 changes: 7 additions & 0 deletions packages/providers/onekey-alph-provider/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../../../tsconfig.json",
"include": ["./src"],
"compilerOptions": {
"outDir": "./dist"
}
}
Loading

0 comments on commit 6d562e3

Please sign in to comment.