Skip to content
Snippets Groups Projects
Commit b54833a9 authored by Mateusz Tyszczak's avatar Mateusz Tyszczak :scroll: Committed by Bartek Wrona
Browse files

Implement hb-auth signer extension

parent 03714b74
No related branches found
No related tags found
1 merge request!292Add other signature providers
......@@ -12,7 +12,7 @@ export const test = base.extend<{
}>({
context: async ({}, use) => {
console.log('Launched browser');
const browserContext = await chromium.launchPersistentContext('');
const browserContext = await chromium.launchPersistentContext('', { headless: typeof process.env.PLAYWRIGHT_HEADLESS === "undefined" });
console.log('Before use browserContext');
await use(browserContext);
......
......@@ -3,6 +3,10 @@ import { expect, Page } from "@playwright/test";
test.describe('Signature extension tests', () => {
test('Should be able to sign transction using key chain extension.', async ({ page, extensionId, context, baseDirectoryPath, testedAccountAuthorityData}) => {
page.on("console", (msg) => {
console.log(`[${msg.type()}]>> Page console: ${msg.text()}`);
});
page.setViewportSize({ width: 500, height: 700 });
//////////////// Import settings begin (containing mirrornet endpoint configuration)
......
......@@ -9,8 +9,10 @@
},
"dependencies": {
"@hiveio/beekeeper": "1.27.10-stable.250305202831",
"@hiveio/hb-auth": "0.0.1-stable.250131124251",
"@hiveio/wax": "file:../../../ts",
"@hiveio/wax-signers-beekeeper": "file:../../../ts/packages/signers-beekeeper",
"@hiveio/wax-signers-hb-auth": "file:../../../ts/packages/signers-hb-auth",
"@hiveio/wax-signers-keychain": "file:../../../ts/packages/signers-keychain",
"@hiveio/wax-signers-metamask": "file:../../../ts/packages/signers-metamask",
"@hiveio/wax-signers-peakvault": "file:../../../ts/packages/signers-peakvault"
......
../node_modules/@hiveio/hb-auth/dist/worker.js
\ No newline at end of file
......@@ -14,6 +14,7 @@
<button onclick="usePeakVault()">Use Peak Vault</button>
<button onclick="useMetaMask()">Use MetaMask</button>
<button onclick="useBeekeeper()">Use Beekeeper</button>
<button onclick="useHbAuth()">Use HBAuth</button>
<pre><code id="operating-private-key"></code></pre>
<pre><code id="tx-result"></code></pre>
......@@ -26,6 +27,8 @@
import PeakVaultProvider from "@hiveio/wax-signers-peakvault";
import MetaMaskProvider from "@hiveio/wax-signers-metamask";
import BeekeeperProvider from "@hiveio/wax-signers-beekeeper";
import HBAuthProvider from "@hiveio/wax-signers-hb-auth";
import { OfflineClient } from "@hiveio/hb-auth";
const txResult = document.getElementById('tx-result');
const operatingPrivateKeyPlaceholder = document.getElementById('operating-private-key');
......@@ -34,21 +37,6 @@
(async()=> {
const testEnv = await prepareTestingEnvironemnt();
const accountName = testEnv.accountName;
const keychainProvider = KeychainProvider.for(accountName, testEnv.role);
let beekeeperProvider;
try {
beekeeperProvider = await BeekeeperProvider.for(testEnv.preparedBeekeeperWallet, testEnv.publicKey);
} catch (error) {
console.error('Beekeeper provider not available', error);
}
const peakVaultProvider = PeakVaultProvider.for(accountName, testEnv.role);
let metaMaskProvider;
try {
metaMaskProvider = await MetaMaskProvider.for(0);
await metaMaskProvider.installSnap();
} catch (error) {
console.error('Metamask provider not available', error);
}
operatingPrivateKeyPlaceholder.textContent = `${accountName}@${testEnv.role} private key to be imported to wallets: ${testEnv.privateKey}`;
......@@ -97,15 +85,51 @@
await tx.sign(provider);
await verifySignature(tx);
} catch (error) {
console.error(error);
console.error('Error signing transaction:', error);
txResult.textContent = `Error: ${error.message}`;
}
};
const keychainProvider = KeychainProvider.for(accountName, testEnv.role);
window.useKeychain = () => void sign(keychainProvider);
let beekeeperProvider;
try {
beekeeperProvider = await BeekeeperProvider.for(testEnv.preparedBeekeeperWallet, testEnv.publicKey);
} catch (error) {
console.error('Beekeeper provider not available', error);
}
const hbAuthClient = new OfflineClient({
chainId: testEnv.configuredChain.chainId,
node: testEnv.configuredChain.endpointUrl,
workerUrl: new URL('./hb-auth-worker.js', import.meta.url),
sessionTimeout: 900
});
const hbAuthProvider = await HBAuthProvider.for(hbAuthClient);
try {
await hbAuthClient.initialize();
const registeredUser = await hbAuthClient.getRegisteredUserByUsername(accountName);
if (registeredUser)
await hbAuthClient.authenticate(accountName, "password", testEnv.role);
else
await hbAuthClient.register(accountName, "password", testEnv.privateKey, testEnv.role);
} catch (error) {
console.error('Could not initialize hb-auth', error);
}
const peakVaultProvider = PeakVaultProvider.for(accountName, testEnv.role);
let metaMaskProvider;
try {
metaMaskProvider = await MetaMaskProvider.for(0);
await metaMaskProvider.installSnap();
} catch (error) {
console.error('Metamask provider not available', error);
}
window.usePeakVault = () => void sign(peakVaultProvider);
window.useMetaMask = () => void sign(metaMaskProvider);
window.useBeekeeper = () => void sign(beekeeperProvider);
window.useHbAuth = () => void sign(hbAuthProvider);
})();
</script>
</body>
......
# @hiveio/wax-signers-hbauth
Wax signer library extending transaction signing possibilities by a 3rd party Web-only extension - hb-auth
## Example usage
```ts
import { createHiveChain } from "@hiveio/wax";
import HBAuthProvider from "@hiveio/wax-signers-hb-auth";
const chain = await createHiveChain();
const provider = HBAuthProvider.for(hbAuthClient);
// Create a transaction using the Wax Hive chain instance
const tx = await chain.createTransaction();
// Perform some operations, e.g. push the vote operation:
tx.pushOperation({
vote: {
voter: "alice",
author: "bob",
permlink: "example-post",
weight: 10000
}
});
// Wait for the keychain to sign the transaction
await tx.sign(provider);
// broadcast the transaction
await chain.broadcast(tx);
```
## License
See license in [LICENSE.md](LICENSE.md) file
{
"name": "@hiveio/wax-signers-hb-auth",
"version": "0.0.0-Run-Prepack",
"description": "Wax signer library extending transaction signing possibilities by a 3rd party Web-only extension - hb-auth",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"type": "module",
"private": false,
"scripts": {
"build": "tsc",
"prepack": "jq --argfile source ../../package.json '.version = $source.version | .publishConfig.registry = $source.publishConfig.registry | .publishConfig.tag = $source.publishConfig.tag' package.json > package.json.tmp && mv package.json.tmp package.json"
},
"devDependencies": {
"typescript": "catalog:typescript-toolset"
},
"dependencies": {
"@hiveio/wax": "workspace:../..",
"@hiveio/hb-auth": "0.0.1-stable.250131124251"
},
"files": [
"dist/index.d.ts",
"dist/index.js",
"README.md",
"LICENSE.md"
],
"license": "SEE LICENSE IN LICENSE.md",
"keywords": [
"wax",
"blockchain",
"hive"
],
"repository": {
"type": "git",
"url": "https://gitlab.syncad.com/hive/wax.git"
},
"publishConfig": {
"registry": "https://RegistryPlaceholder",
"tag": "DistTagPlaceholder"
}
}
\ No newline at end of file
import type { IOnlineSignatureProvider, ITransaction } from "@hiveio/wax";
import { type OfflineClient, type OnlineClient } from "@hiveio/hb-auth";
// We do not extend from WaxError to avoid runtime dependencies, such as: /vite or /web - without it we can import only types
export class WaxHBAuthProviderError extends Error {}
/**
* Wax transaction signature provider using the hb-auth.
*
* @example
* ```
* const provider = HBAuthProvider.for(hbAuthClient);
*
* // Create a transaction using the Wax Hive chain instance
* const tx = await chain.createTransaction();
*
* // Perform some operations, e.g. pushing operations...
*
* // Sign the transaction
* await tx.sign(provider);
*
* // broadcast
* await chain.broadcast(tx);
* ```
*/
class HBAuthProvider implements IOnlineSignatureProvider {
private constructor(
public readonly client: OnlineClient | OfflineClient,
public readonly username?: string
) {}
public static for(client: OnlineClient | OfflineClient, username?: string): HBAuthProvider {
return new HBAuthProvider(client, username);
}
public async signTransaction(transaction: ITransaction): Promise<void> {
const requiredAuthorities = transaction.requiredAuthorities;
const signatures: string[] = [];
const digest = transaction.sigDigest;
for(const auth in requiredAuthorities)
if (auth !== "other")
for(const actor of requiredAuthorities[auth])
if (this.username === undefined || actor === this.username)
signatures.push(await this.client.sign(actor, digest, auth as 'posting' | 'active' | 'owner'));
if (signatures.length === 0)
throw new WaxHBAuthProviderError(`Failed to sign the transaction`);
for(const signature of signatures)
transaction.sign(signature);
}
}
export interface WaxHBAuthProviderCreator {
/**
* We assume you already called #initialize() on the client and client has imported the keys.
*
* @param client - The hb-auth client instance.
* @param username - The username to sign the transaction with. If not provided - every user imported to the hb-auth will be allowed to sign the transaction.
*/
for(client: OnlineClient | OfflineClient, username?: string): HBAuthProvider;
}
export default HBAuthProvider as WaxHBAuthProviderCreator;
{
"extends": "../../npm-common-config/ts-common/tsconfig.base.json",
"compilerOptions": {
"rootDir": "./src",
"baseUrl": ".",
"outDir": "./dist",
"incremental": true,
"tsBuildInfoFile": "./dist/.tsbuildinfo",
"skipLibCheck": true
},
"include": [
"./src"
]
}
\ No newline at end of file
......@@ -54,6 +54,9 @@ class KeychainProvider implements IOnlineSignatureProvider {
}
public async signTransaction(transaction: ITransaction): Promise<void> {
if (!(await KeychainProvider.keychain.isKeychainInstalled()))
throw new WaxKeychainProviderError(`Keychain is not installed`);
const data = await KeychainProvider.keychain.signTx({
method: this.role,
username: this.accountName,
......
......@@ -201,6 +201,19 @@ importers:
specifier: catalog:typescript-toolset
version: 5.7.3
packages/signers-hb-auth:
dependencies:
'@hiveio/hb-auth':
specifier: 0.0.1-stable.250131124251
version: 0.0.1-stable.250131124251
'@hiveio/wax':
specifier: workspace:../..
version: link:../..
devDependencies:
typescript:
specifier: catalog:typescript-toolset
version: 5.7.3
packages/signers-keychain:
dependencies:
'@hiveio/wax':
......@@ -428,9 +441,20 @@ packages:
resolution: {integrity: sha1-mPx0QrDh3NSPSOYGyR1SUyi3lyA=, tarball: https://gitlab.syncad.com/api/v4/projects/198/packages/npm/@hiveio/beekeeper/-/@hiveio/beekeeper-1.27.10-stable.250305202831.tgz}
engines: {node: ^20.11 || >= 21.2}
'@hiveio/beekeeper@1.27.8-stable.250131103618':
resolution: {integrity: sha1-0IYuFBbxIIKfRTrI6ZZc7Jf+qLA=, tarball: https://gitlab.syncad.com/api/v4/projects/198/packages/npm/@hiveio/beekeeper/-/@hiveio/beekeeper-1.27.8-stable.250131103618.tgz}
engines: {node: ^20.11 || >= 21.2}
'@hiveio/dhive@1.3.2':
resolution: {integrity: sha512-kJjp3TbpIlODxjJX4BWwvOf+cMxT8CFH/mNQ40RRjR2LP0a4baSWae1G+U/q/NtgjsIQz6Ja40tvnw6KF12I+g==, tarball: https://registry.npmjs.org/@hiveio/dhive/-/dhive-1.3.2.tgz}
'@hiveio/hb-auth@0.0.1-stable.250131124251':
resolution: {integrity: sha1-HX9GbxRjpo+ezDR5SAvuEIVr6II=, tarball: https://gitlab.syncad.com/api/v4/projects/429/packages/npm/@hiveio/hb-auth/-/@hiveio/hb-auth-0.0.1-stable.250131124251.tgz}
'@hiveio/wax@1.27.6-rc7-stable.250131113706':
resolution: {integrity: sha1-Xi2VV8y9T6MdBHOBSzxZNpmGnF8=, tarball: https://gitlab.syncad.com/api/v4/projects/419/packages/npm/@hiveio/wax/-/@hiveio/wax-1.27.6-rc7-stable.250131113706.tgz}
engines: {node: ^20.11 || >= 21.2}
'@isaacs/cliui@8.0.2':
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
engines: {node: '>=12'}
......@@ -978,6 +1002,9 @@ packages:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'}
comlink@4.4.2:
resolution: {integrity: sha512-OxGdvBmJuNKSCMO4NTl1L47VRp6xn2wG4F/2hYzB6tiCb709otOxtEYCSvK80PtjODfXXZu8ds+Nw5kVCjqd2g==}
commander@2.20.3:
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
......@@ -2589,6 +2616,8 @@ snapshots:
'@hiveio/beekeeper@1.27.10-stable.250305202831': {}
'@hiveio/beekeeper@1.27.8-stable.250131103618': {}
'@hiveio/dhive@1.3.2':
dependencies:
'@ecency/bytebuffer': 6.0.0
......@@ -2607,6 +2636,17 @@ snapshots:
transitivePeerDependencies:
- encoding
'@hiveio/hb-auth@0.0.1-stable.250131124251':
dependencies:
'@hiveio/wax': 1.27.6-rc7-stable.250131113706
comlink: 4.4.2
'@hiveio/wax@1.27.6-rc7-stable.250131113706':
dependencies:
'@hiveio/beekeeper': 1.27.8-stable.250131103618
events: 3.3.0
long: 5.2.3
'@isaacs/cliui@8.0.2':
dependencies:
string-width: 5.1.2
......@@ -3189,6 +3229,8 @@ snapshots:
dependencies:
delayed-stream: 1.0.0
comlink@4.4.2: {}
commander@2.20.3: {}
commondir@1.0.1: {}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment