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

Feature add gatewallet adapter #75

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 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
3 changes: 2 additions & 1 deletion demos/dev-demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@
"@tronweb3/tronwallet-adapter-ledger": "^1.1.8",
"@tronweb3/tronwallet-adapter-metamask": "^1.0.1",
"@tronweb3/tronwallet-adapter-okxwallet": "^1.0.2",
"@tronweb3/tronwallet-adapter-gatewallet": "^1.0.0",
"@tronweb3/tronwallet-adapter-react-hooks": "^1.1.7",
"@tronweb3/tronwallet-adapter-react-ui": "^1.1.8",
"@tronweb3/tronwallet-adapter-tokenpocket": "^1.0.2",
"@tronweb3/tronwallet-adapter-tronlink-evm": "^1.0.0",
"@tronweb3/tronwallet-adapters": "^1.1.9",
"@tronweb3/tronwallet-adapters": "^1.2.1",
"@types/node": "^18.19.0",
"events": "^3.3.0",
"ganache": "^7.9.0",
Expand Down
5 changes: 5 additions & 0 deletions demos/dev-demo/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { OkxWalletAdapterDemo } from './OkxWalletAdapterDemo.js';
import { MetamaskAdapterDemo } from './Metamask.js';
import { TronLinkEvmAdapter } from '@tronweb3/tronwallet-adapter-tronlink-evm';
import { TronLinkEvmAdapterDemo } from './TronLinkEvmDemo.js';
import { GateWalletAdapterDemo } from './GateWalletAdapterDemo.js';
interface TabPanelProps {
children?: React.ReactNode;
index: number;
Expand Down Expand Up @@ -50,6 +51,7 @@ function App() {
<Tab label="OkxWalletAdapter Demo" />
<Tab label="MetaMaskWalletAdapter Demo" />
<Tab label="TronlinkEvmWalletAdapter Demo" />
<Tab label="Gate WalletAdapter Demo" />
</Tabs>
</Box>
<TabPanel value={value} index={0}>
Expand Down Expand Up @@ -82,6 +84,9 @@ function App() {
<TabPanel value={value} index={9}>
<TronLinkEvmAdapterDemo></TronLinkEvmAdapterDemo>
</TabPanel>
<TabPanel value={value} index={10}>
<GateWalletAdapterDemo></GateWalletAdapterDemo>
</TabPanel>
</Box>
</div>
);
Expand Down
274 changes: 274 additions & 0 deletions demos/dev-demo/src/GateWalletAdapterDemo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,274 @@
import type { ReactNode } from 'react';
import { useEffect, useMemo, useState, useCallback } from 'react';
// import './App.css';
import { GateWalletAdapter } from '@tronweb3/tronwallet-adapters';
import type { Adapter } from '@tronweb3/tronwallet-abstract-adapter';
import { AdapterState } from '@tronweb3/tronwallet-abstract-adapter';
import { Box, Button, Typography, Tooltip, Select, MenuItem, Alert, FormControl, TextField } from '@mui/material';
import { tronWeb } from './tronweb.js';
const receiver = 'TMDKznuDWaZwfZHcM61FVFstyYNmK6Njk1';
const getTronWeb = () => window.gatewallet?.tronLink?.tronWeb as any || null;
// const getTronWeb = () => tronWeb;

export function GateWalletAdapterDemo() {
const [connectState, setConnectState] = useState(AdapterState.NotFound);
const [account, setAccount] = useState('');
const [readyState, setReadyState] = useState('');
const [chainId, setChainId] = useState<string>('');
const [selectedChainId, setSelectedChainId] = useState('0xcd8690dc');
const [open, setOpen] = useState(false);
const [signMessage, setSignMessage] = useState('Hello, Adapter');
const [signedMessage, setSignedMessage] = useState('');
const adapter = useMemo(() => new GateWalletAdapter(), []);

useEffect(() => {
setConnectState(adapter.state);
setAccount(adapter.address || '');
setReadyState(adapter.readyState);
if (adapter.connected) {
adapter.network().then((res) => {
console.log(res);
setChainId(res.chainId)
}).catch(e => {
console.log(e)
})
}

adapter.on('readyStateChanged', () => {
console.log('readyState: ', adapter.readyState)
setReadyState(adapter.readyState)
})
adapter.on('connect', () => {
console.log('connect: ', adapter.address);
setAccount(adapter.address || '');
adapter.network().then((res) => {
console.log(res);
setChainId(res.chainId)
}).catch(e => {
console.log(e)
})
});
adapter.on('stateChanged', (state) => {
console.log('stateChanged: ', state);
setConnectState(state);
});
adapter.on('accountsChanged', (data, preaddr) => {
console.log('accountsChanged: current', data,' pre: ', preaddr);
setAccount(data as string);
});

adapter.on('chainChanged', (data) => {
console.log('chainChanged: ', data);
setChainId((data as any).chainId);
});

adapter.on('disconnect', () => {
console.log('disconnect');
});

return () => {
adapter.removeAllListeners();
};
}, [adapter]);

function onSwitchChain() {
adapter.switchChain(selectedChainId);
}

async function onSignTransaction() {
const tronWeb = getTronWeb();
const transaction = await tronWeb.transactionBuilder.sendTrx(receiver, tronWeb.toSun(0.0001), adapter.address);
const signedTransaction = await adapter.signTransaction(transaction);
console.log('signedTx', signedTransaction)

// const signedTransaction = await tronWeb.trx.sign(transaction);
const res = await tronWeb.trx.sendRawTransaction(signedTransaction);
setOpen(true);
}

const onSignMessage = useCallback(
async function () {
const res = await adapter.signMessage(signMessage);
setSignedMessage(res);
},
[adapter, signMessage, setSignedMessage]
);

const onVerifyMessage = useCallback(
async function () {
const tronWeb = getTronWeb();
const address = await tronWeb.trx.verifyMessageV2(signMessage, signedMessage);
alert(address === adapter.address ? 'success verify' : 'failed verify');
},
[signMessage, signedMessage, adapter]
);

async function handleConnect() {
try {
await adapter?.connect()
} catch(e: any) {
console.log(e.error?.message || e.message);
}
}
return (
<Box sx={{ width: '100%', maxWidth: 900 }}>
<h1>GateWallet Demo</h1>
<Typography variant="h6" gutterBottom>
Your account address:
</Typography>
<Detail>{account}</Detail>

<Typography variant="h6" gutterBottom>
Current network you choose: {chainId}
</Typography>

<Typography variant="h6" gutterBottom>
ReadyState: {readyState}
</Typography>
<Typography variant="h6" gutterBottom>
Current connection status:&nbsp;&nbsp;
<span style={{ color: adapter?.connected ? '#08f108' : 'orange' }}>{connectState}</span>
</Typography>
<Typography variant="h6" gutterBottom>
<TextField label="Message to sign" size="small" value={signMessage} onChange={(e) => setSignMessage(e.target.value)}></TextField>
</Typography>
<Detail>
<Button variant="contained" disabled={adapter?.connected} onClick={handleConnect}>
Connect
</Button>

<Button variant="contained" disabled={!adapter?.connected} onClick={() => adapter?.disconnect()}>
Disconnect
</Button>

<Button variant="contained" disabled={!adapter?.connected} onClick={onSignTransaction}>
Transfer
</Button>
</Detail>
<Detail>
<Button variant="contained" onClick={onSignMessage}>
Sign Message
</Button>

<Button variant="contained" disabled={!signedMessage} onClick={onVerifyMessage}>
Verify Signed Message
</Button>
</Detail>
{open && (
<Alert onClose={() => setOpen(false)} severity="success" sx={{ width: '100%', marginTop: 1 }}>
Success! You can confirm your transfer on{' '}
<a target="_blank" rel="noreferrer" href={`https://nile.tronscan.org/#/address/${adapter.address}`}>
Tron Scan
</a>
</Alert>
)}
<MultiSignDemo address={account} adapter={adapter}></MultiSignDemo>
</Box>
);
}

export function Detail(props: { children: ReactNode }) {
return <div style={{ margin: 15 }}>{props.children}</div>;
}

function MultiSignDemo(props: { address: string; adapter: Adapter }) {
const [address1, setAddress1] = useState('');
const [open, setOpen] = useState(false);

async function onApprove() {
const tronWeb = getTronWeb();
const ownerAddress = tronWeb.address.toHex(props.address);
const ownerPermission = {
type: 0,
permission_name: 'owner',
threshold: 1,
keys: [
{
address: ownerAddress,
weight: 1,
},
],
};
const activePermission = {
type: 2,
permission_name: 'ActivePermission',
threshold: 2,
keys: [],
operations: '7fff1fc0037e0000000000000000000000000000000000000000000000000000',
} as any;

activePermission.keys.push({ address: ownerAddress, weight: 1 });
activePermission.keys.push({ address: tronWeb.address.toHex(address1), weight: 1 });

const updateTransaction = await tronWeb.transactionBuilder.updateAccountPermissions(ownerAddress, ownerPermission, null, [activePermission]);
const signed = await props.adapter.signTransaction(updateTransaction);
const res = await tronWeb.trx.sendRawTransaction(signed);
alert('update successfully.');
}

const [transferTransaction, setTransferTransaction] = useState(null);
const [canSend, setCanSend] = useState(false);

const multiSignWithAddress1 = useCallback(
async function () {
const tronWeb = getTronWeb();
const transaction = await tronWeb.transactionBuilder.sendTrx(receiver, tronWeb.toSun(0.000001), props.address, { permissionId: 2 });
const signedTransaction = await props.adapter.multiSign(transaction, null, 2);
setTransferTransaction(signedTransaction);
},
[props.adapter, setTransferTransaction, props.address]
);
const multiSignWithAddress2 = useCallback(
async function () {
console.log('first multi signed tx:', transferTransaction);
const signedTransaction = await props.adapter.multiSign(transferTransaction as any, null, 2);
console.log('second multi signed tx:', signedTransaction);
setTransferTransaction(signedTransaction);
const tronWeb = getTronWeb();
const signWeight = await tronWeb.trx.getSignWeight(signedTransaction, 2);
console.log('signWeight: ', signWeight);
if (signWeight.current_weight >= 2) {
setCanSend(true);
}
},
[transferTransaction, setTransferTransaction, setCanSend, props.adapter]
);
async function broadcast() {
const tronWeb = getTronWeb();
const res = await tronWeb.trx.broadcast(transferTransaction);
setOpen(true);
}
return (
<>
<h3>MultiSign Demo</h3>
{/* <p>You can input two address and click approve button to give them permission.</p>
<div>
<TextField size="small" label="address to approve" value={address1} onChange={(e) => setAddress1(e.target.value)}></TextField>
<Button style={{ marginLeft: 10 }} disabled={!address1} variant="contained" onClick={onApprove}>
Approve
</Button>
</div> */}

<p>You can click following buttons to multiSign and send the Transaction</p>
<div>
<Button disabled={!props.address} variant="contained" onClick={multiSignWithAddress1}>
Sign with 1st Address
</Button>
<Button disabled={!transferTransaction} style={{ marginLeft: 10 }} variant="contained" onClick={multiSignWithAddress2}>
Sign with 2nd Address
</Button>
<Button style={{ marginLeft: 10 }} variant="contained" onClick={broadcast}>
Send the transaction
</Button>
</div>
{open && (
<Alert onClose={() => setOpen(false)} severity="success" sx={{ width: '100%', marginTop: 1 }}>
Success! You can confirm your transfer on{' '}
<a target="_blank" rel="noreferrer" href={`https://nile.tronscan.org/#/address/${props.address}`}>
Tron Scan
</a>
</Alert>
)}
</>
);
}
3 changes: 2 additions & 1 deletion packages/adapters/adapters/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@
"@tronweb3/tronwallet-adapter-okxwallet": "workspace:^",
"@tronweb3/tronwallet-adapter-tokenpocket": "workspace:^",
"@tronweb3/tronwallet-adapter-tronlink": "workspace:^",
"@tronweb3/tronwallet-adapter-walletconnect": "workspace:^"
"@tronweb3/tronwallet-adapter-walletconnect": "workspace:^",
"@tronweb3/tronwallet-adapter-gatewallet": "workspace:^"
},
"devDependencies": {
"shx": "^0.3.4"
Expand Down
1 change: 1 addition & 0 deletions packages/adapters/adapters/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export * from '@tronweb3/tronwallet-adapter-ledger';
export * from '@tronweb3/tronwallet-adapter-tokenpocket';
export * from '@tronweb3/tronwallet-adapter-bitkeep';
export * from '@tronweb3/tronwallet-adapter-okxwallet';
export * from '@tronweb3/tronwallet-adapter-gatewallet';
3 changes: 3 additions & 0 deletions packages/adapters/adapters/tsconfig.all.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
{
"path": "../okxwallet/tsconfig.all.json"
},
{
"path": "../gatewallet/tsconfig.all.json"
},
{
"path": "./tsconfig.cjs.json"
},
Expand Down
20 changes: 20 additions & 0 deletions packages/adapters/gatewallet/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2022-Present, tronprotocol

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Loading