Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 4 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@

/** @typedef {import('./src/wallet-account-evm.js').ApproveOptions} ApproveOptions */

/** @typedef {import('./src/utils/tx-populator-evm.js').UnsignedEvmTransaction} UnsignedEvmTransaction */

export { default } from './src/wallet-manager-evm.js'

export { default as WalletAccountReadOnlyEvm } from './src/wallet-account-read-only-evm.js'

export { default as WalletAccountEvm } from './src/wallet-account-evm.js'

export { ISigner } from '@tetherto/wdk-wallet'

export { ISignerEvm } from './src/signers/signer-evm.js'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should export the 'ISignerEvm' interface only out of /src/signers/index.js.

7 changes: 3 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"dependencies": {
"@noble/hashes": "1.8.0",
"@noble/secp256k1": "2.2.3",
"@tetherto/wdk-wallet": "1.0.0-beta.13",
"@tetherto/wdk-wallet": "github:claudiovb/wdk-wallet#fix/universal-signer",
"@tetherto/wdk-failover-provider": "1.0.0-beta.2",
"bare-node-runtime": "^1.5.0",
"bip39": "3.1.0",
Expand Down Expand Up @@ -62,6 +62,7 @@
},
"./signers": {
"types": "./types/src/signers/index.d.ts",
"bare": "./src/signers/bare.js",
"default": "./src/signers/index.js"
},
"./package": {
Expand All @@ -75,6 +76,7 @@
"standard": {
"ignore": [
"bare.js",
"src/signers/bare.js",
"tests/**/*.js"
]
}
Expand Down
20 changes: 20 additions & 0 deletions src/signers/bare.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2024 Tether Operations Limited
//
// Licensed 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.
'use strict'

import 'bare-node-runtime/global'

export * from './index.js' with { imports: 'bare-node-runtime/imports' }

export { default } from './index.js' with { imports: 'bare-node-runtime/imports' }
4 changes: 2 additions & 2 deletions src/signers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
/**
* Barrel exports for EVM signers.
*
* - `ISignerEvm`: the interface implemented by all EVM signers.
* - `SeedSignerEvm`: derives accounts from a BIP-39 seed (BIP-44 path).
* - `PrivateKeySignerEvm`: memory-safe wrapper around a raw private key.
*/

/** @typedef {import('../utils/tx-populator-evm.js').UnsignedEvmTransaction} UnsignedEvmTransaction */

export { ISignerEvm } from './signer-evm.js'
export { default, default as SeedSignerEvm } from './seed-signer-evm.js'
export { default as PrivateKeySignerEvm } from './private-key-signer-evm.js'
52 changes: 33 additions & 19 deletions src/signers/private-key-signer-evm.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,28 @@ import { BaseWallet } from 'ethers'
import { SignerError } from '@tetherto/wdk-wallet'

import MemorySafeSigningKey from '../memory-safe/signing-key.js'
import { ISignerEvm } from './seed-signer-evm.js'

/** @typedef {import('../utils/tx-populator-evm.js').UnsignedEvmTransaction} UnsignedEvmTransaction */
/** @typedef {import('./signer-evm.js').ISignerEvm} ISignerEvm */
/** @typedef {import('@tetherto/wdk-wallet').KeyPair} KeyPair */
/** @typedef {import('ethers').TransactionLike} TransactionLike */
/** @typedef {import('ethers').AuthorizationRequest} AuthorizationRequest */
/** @typedef {import('ethers').Authorization} Authorization */
/** @typedef {import('../wallet-account-read-only-evm.js').TypedData} TypedData */

/**
* @extends {ISignerEvm}
* Signer that wraps a raw private key in a memory-safe buffer, exposing a minimal
* interface for signing messages, transactions and typed data. This signer does
* not support derivation and always represents a single account.
*
* @implements {ISignerEvm}
*/
export default class PrivateKeySignerEvm extends ISignerEvm {
export default class PrivateKeySignerEvm {
/**
* Create a signer from a raw private key.
*
* @param {string|Uint8Array} privateKey - Hex string (with/without 0x) or raw key bytes.
*/
constructor (privateKey) {
super()

// Expect a Uint8Array buffer; accept hex string as convenience
let privateKeyBuffer = privateKey
if (typeof privateKey === 'string') {
Expand All @@ -61,30 +60,36 @@ export default class PrivateKeySignerEvm extends ISignerEvm {
/**
* Whether this signer can derive child signers. Always false: a private-key signer is a
* single standalone account and is bound directly to a wallet account.
*
* @type {boolean}
*/
get isDerivable () { return false }

/**
* The account index. Always undefined for private key signers: a raw key has no
* BIP-44 position, so reporting an index would be misleading.
*
* @type {number|undefined}
*/
get index () { return undefined }

/**
* The derivation path. Always undefined for private key signers.
*
* @type {string|undefined}
*/
get path () { return this._path }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The path and index will always be null for a private key signer.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Private key signers don't need a path property so you can get rid of it:

Suggested change
/**
* The derivation path. Always undefined for private key signers.
*
* @type {string|undefined}
*/
get path () { return this._path }
/**
* The BIP 0044 derivation path.
*
* @type {string | null}
*/
get path () { return null }


/**
* The account's address.
*
* @type {string}
*/
get address () { return this._address }

/**
* The account's key pair (private and public key buffers).
*
* @type {KeyPair}
*/
get keyPair () {
Expand All @@ -95,15 +100,21 @@ export default class PrivateKeySignerEvm extends ISignerEvm {
}

/**
* PrivateKeySignerEvm is not a hierarchical signer and cannot derive.
* @returns {Promise<never>}
* Derive a child signer using a relative path (e.g., "0'/0/0").
*
* @param {string} relPath - The relative derivation path.
* @returns {Promise<never>} Never resolves; private-key signers cannot derive.
* @throws {SignerError} Always — private-key signers do not support derivation.
*/
async derive () {
async derive (relPath) {
Comment on lines 97 to +99

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#40 (comment)
The specification of the method should be equal to the superclass's except for the return value which should correctly be 'Promise'.

This should be:

Suggested change
/**
* PrivateKeySignerEvm is not a hierarchical signer and cannot derive.
* @returns {Promise<never>}
* Derive a child signer using a relative path (e.g., "0'/0/0").
*
* @param {string} relPath - The relative derivation path.
* @returns {Promise<never>} Never resolves; private-key signers cannot derive.
* @throws {SignerError} Always private-key signers do not support derivation.
*/
async derive () {
async derive (relPath) {
/**
* Derive a child signer using a relative path (e.g., "0'/0/0").
*
* @param {string} relPath - The relative derivation path.
* @returns {Promise<never>} The derived signer.
* @throws {SignerError} If the signer does not support derivation.
*/
async derive (relPath) {

throw new SignerError('PrivateKeySignerEvm does not support derivation.')
}

/** @returns {Promise<string>} */
/**
* Returns the account's address.
*
* @returns {Promise<string>} The account's address.
*/
async getAddress () {
return this._address
}
Expand All @@ -119,13 +130,13 @@ export default class PrivateKeySignerEvm extends ISignerEvm {
}

/**
* Signs a transaction and returns the serialized signed transaction hex.
* Signs a transaction.
*
* @param {UnsignedEvmTransaction} unsignedTx - The unsigned transaction object.
* @returns {Promise<string>}
* @param {TransactionLike} tx - The transaction to sign.
* @returns {Promise<string>} The signed transaction as a hex string.
*/
async signTransaction (unsignedTx) {
return this._wallet.signTransaction(unsignedTx)
async signTransaction (tx) {
return this._wallet.signTransaction(tx)
}

/**
Expand All @@ -139,15 +150,18 @@ export default class PrivateKeySignerEvm extends ISignerEvm {
}

/**
* Sign an ERC-7702 authorization tuple.
* @param {AuthorizationRequest} auth
* @returns {Promise<Authorization>}
* Signs an ERC-7702 authorization tuple.
*
* @param {AuthorizationRequest} auth - The authorization request.
* @returns {Promise<Authorization>} The signed authorization.
*/
async signAuthorization (auth) {
return this._wallet.authorizeSync(auth)
}

/** Dispose secrets from memory. */
/**
* Disposes the signer, erasing its secrets from memory.
*/
dispose () {
if (this._signingKey) this._signingKey.dispose()
this._signingKey = undefined
Expand Down
Loading