Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into dev
Browse files Browse the repository at this point in the history
# Conflicts:
#	embed-basic/package.json
  • Loading branch information
LinkinStars committed Nov 18, 2024
2 parents 57eabcb + d7f7b2e commit 71af46b
Show file tree
Hide file tree
Showing 43 changed files with 1,053 additions and 40 deletions.
37 changes: 37 additions & 0 deletions connector-wallet/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parser: '@typescript-eslint/parser',
plugins: ['react-refresh'],
rules: {
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
}
8 changes: 8 additions & 0 deletions connector-wallet/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"trailingComma": "all",
"tabWidth": 2,
"singleQuote": true,
"jsxBracketSameLine": true,
"printWidth": 80,
"endOfLine": "auto"
}
33 changes: 33 additions & 0 deletions connector-wallet/Component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import WalletProvider from './WalletProvider';
import WalletAuthorizer from './WalletAuthorizer';

const Component = () => {
return (
<WalletProvider>
<div style={{ margin: '0 auto', paddingTop: '8rem', maxWidth: 480 }}>
<WalletAuthorizer />
</div>
</WalletProvider>
);
};

export default Component;
33 changes: 33 additions & 0 deletions connector-wallet/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Wallet connector
> Wallet connector is a OAuth plug-in designed to support Wallet OAuth login.
## How to use

### Build
```bash
./answer build --with github.com/apache/incubator-answer-plugins/connector-wallet
```

### Use Case

- Step 1: Install the wallet plug-in on your chrome/firefox browser. ex:MetaMask,BitgetWallet.

![./imgs/install.png](./imgs/install.png)

- Step 2: Generate your web3 wallet.

![./imgs/create.png](./imgs/create.png)

![./imgs/wallet.png](./imgs/wallet.png)


- Step3: Build your answer with golang and register the plugin.

![./imgs/activate.png](./imgs/activate.png)

- Step4: Log in through your wallet and bind to your email.
![./imgs/click1.png](./imgs/click1.png)

![./imgs/click2.png](./imgs/click2.png)

![./imgs/bind.png](./imgs/bind.png)
107 changes: 107 additions & 0 deletions connector-wallet/WalletAuthorizer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { ConnectButton } from '@rainbow-me/rainbowkit';
import { useConfig, useSwitchChain, useSignMessage } from 'wagmi';
import { sha256 } from 'js-sha256';
import { useTranslation } from 'react-i18next';
import { Button } from 'react-bootstrap';

function getSearchParamValue(key: string, defaultValue: string = '') {
return location.search && new URLSearchParams(location.search.slice()).get(key) || defaultValue;
}

function WalletAuthorizer() {
const { chains } = useConfig();
const { switchChain } = useSwitchChain();
const { signMessageAsync } = useSignMessage();

const { t } = useTranslation('plugin', {
keyPrefix: 'wallet_connector.frontend',
});

return (
<ConnectButton.Custom>
{({
account,
chain,
openAccountModal,
openChainModal,
openConnectModal,
authenticationStatus,
mounted,
}) => {
const ready = mounted && authenticationStatus !== 'loading';
const connected = ready && account && chain && (!authenticationStatus || authenticationStatus === 'authenticated');
const { address } = account || { address: '' };

const handleSwitchNetwork = () => {
if (chains.length === 1) {
switchChain({ chainId: chains[0].id });
} else {
openChainModal();
}
};

const handleAuthorize = async () => {
const nonce = getSearchParamValue('nonce', sha256(address));
const signature = await signMessageAsync({ message: nonce });

location.href = `/answer/api/v1/connector/redirect/wallet?message=${nonce}&signature=${signature}&address=${address}&redirect=${getSearchParamValue('redirect')}`;
}

return (
<div>
{(() => {
let description: React.ReactNode;
let actionList: React.ReactNode;

if (!connected) {
description = <>{t('wallet_needed')}</>;
actionList = <Button onClick={() => openConnectModal()}>{t('connect_button')}</Button>;
} else if (chain.unsupported) {
description = <>{t('wrong_network')}</>;
actionList = <Button onClick={handleSwitchNetwork}>{t('switch_button')}</Button>;
} else {
const translatedArr = t('connected_wallet').split('${ADDRESS}') as React.ReactNode[];
translatedArr.splice(1, 0, <strong style={{ cursor: 'pointer' }} onClick={() => openAccountModal()}>{address.replace(address.slice(6, -4), '...')}</strong>);
description = <>{translatedArr.map((c, i) => <span key={i}>{c}</span>)}</>;
actionList = (
<>
<Button onClick={handleAuthorize}>{t('authorize_button')}</Button>
<Button variant="outline-secondary" onClick={() => openAccountModal()}>{t('disconnect_button')}</Button>
</>
);
}

return (
<>
<p>{description}</p>
<div className="d-grid gap-2">{actionList}</div>
</>
);
})()}
</div>
);
}}
</ConnectButton.Custom>
);
}

export default WalletAuthorizer;
46 changes: 46 additions & 0 deletions connector-wallet/WalletProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import '@rainbow-me/rainbowkit/styles.css';
import { getDefaultConfig, RainbowKitProvider } from '@rainbow-me/rainbowkit';
import { WagmiProvider } from 'wagmi';
import { mainnet } from 'wagmi/chains';
import { QueryClientProvider, QueryClient } from '@tanstack/react-query';

const config = getDefaultConfig({
appName: 'Apache Answer',
projectId: 'xxx',
chains: [mainnet], // There's no on-chain operations, so only ETH mainnet is enough.
});

const queryClient = new QueryClient();

function WalletProvider({ children }: React.PropsWithChildren) {
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
<RainbowKitProvider>
{children}
</RainbowKitProvider>
</QueryClientProvider>
</WagmiProvider>
);
}

export default WalletProvider;
50 changes: 50 additions & 0 deletions connector-wallet/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
module github.com/apache/incubator-answer-plugins/connector-wallet

go 1.22

require (
github.com/apache/incubator-answer v1.4.0
github.com/apache/incubator-answer-plugins/util v1.0.2
github.com/i-lucifer/crypto v0.0.2
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
)

require (
github.com/LinkinStars/go-i18n/v2 v2.2.2 // indirect
github.com/aymerick/douceur v0.2.0 // indirect
github.com/bytedance/sonic v1.9.1 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/gin-gonic/gin v1.9.1 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.14.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/google/wire v0.5.0 // indirect
github.com/gorilla/css v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/microcosm-cc/bluemonday v1.0.21 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/segmentfault/pacman v1.0.5-0.20230822083413-c0075a2d401f // indirect
github.com/segmentfault/pacman/contrib/i18n v0.0.0-20230516093754-b76aef1c1150 // indirect
github.com/stretchr/testify v1.9.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/arch v0.3.0 // indirect
golang.org/x/crypto v0.22.0 // indirect
golang.org/x/net v0.24.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)
Loading

0 comments on commit 71af46b

Please sign in to comment.