@tetherto/wdk-wallet-evm 1.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +11 -0
- package/LICENSE +176 -0
- package/README.md +420 -0
- package/bare.js +20 -0
- package/hardhat.config.cjs +16 -0
- package/index.js +31 -0
- package/package.json +67 -0
- package/src/memory-safe/hd-node-wallet.js +196 -0
- package/src/memory-safe/signing-key.js +77 -0
- package/src/wallet-account-evm.js +200 -0
- package/src/wallet-account-read-only-evm.js +191 -0
- package/src/wallet-manager-evm.js +127 -0
- package/types/index.d.ts +11 -0
- package/types/src/wallet-account-evm.d.ts +91 -0
- package/types/src/wallet-account-read-only-evm.d.ts +112 -0
- package/types/src/wallet-manager-evm.d.ts +68 -0
package/.editorconfig
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
package/README.md
ADDED
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
# @tetherto/wdk-wallet-evm
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
**Note**: This package is currently in beta. Please test thoroughly in development environments before using in production.
|
|
5
|
+
|
|
6
|
+
A simple and secure package to manage BIP-44 wallets for EVM-compatible blockchains. This package provides a clean API for creating, managing, and interacting with Ethereum-compatible wallets using BIP-39 seed phrases and EVM-specific derivation paths.
|
|
7
|
+
|
|
8
|
+
## 🔍 About WDK
|
|
9
|
+
|
|
10
|
+
This module is part of the [**WDK (Wallet Development Kit)**](https://wallet.tether.io/) project, which empowers developers to build secure, non-custodial wallets with unified blockchain access, stateless architecture, and complete user control.
|
|
11
|
+
|
|
12
|
+
For detailed documentation about the complete WDK ecosystem, visit [docs.wallet.tether.io](https://docs.wallet.tether.io).
|
|
13
|
+
|
|
14
|
+
## 🌟 Features
|
|
15
|
+
|
|
16
|
+
- **BIP-39 Seed Phrase Support**: Generate and validate BIP-39 mnemonic seed phrases
|
|
17
|
+
- **EVM Derivation Paths**: Support for BIP-44 standard derivation paths for Ethereum (m/44'/60')
|
|
18
|
+
- **Multi-Account Management**: Create and manage multiple accounts from a single seed phrase
|
|
19
|
+
- **Transaction Management**: Send transactions and get fee estimates with EIP-1559 support
|
|
20
|
+
- **ERC20 Support**: Query native token and ERC20 token balances using smart contract interactions
|
|
21
|
+
|
|
22
|
+
## ⬇️ Installation
|
|
23
|
+
|
|
24
|
+
To install the `@tetherto/wdk-wallet-evm` package, follow these instructions:
|
|
25
|
+
|
|
26
|
+
You can install it using npm:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install @tetherto/wdk-wallet-evm
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## 🚀 Quick Start
|
|
33
|
+
|
|
34
|
+
### Importing from `@tetherto/wdk-wallet-evm`
|
|
35
|
+
|
|
36
|
+
### Creating a New Wallet
|
|
37
|
+
|
|
38
|
+
```javascript
|
|
39
|
+
import WalletManagerEvm, { WalletAccountEvm, WalletAccountReadOnlyEvm } from '@tetherto/wdk-wallet-evm'
|
|
40
|
+
|
|
41
|
+
// Use a BIP-39 seed phrase (replace with your own secure phrase)
|
|
42
|
+
const seedPhrase = 'test only example nut use this real life secret phrase must random'
|
|
43
|
+
|
|
44
|
+
// Create wallet manager with provider config
|
|
45
|
+
const wallet = new WalletManagerEvm(seedPhrase, {
|
|
46
|
+
// Option 1: Using RPC URL
|
|
47
|
+
provider: 'https://eth-mainnet.g.alchemy.com/v2/your-api-key', // or any EVM RPC endpoint
|
|
48
|
+
transferMaxFee: 100000000000000 // Optional: Maximum fee in wei
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
// OR
|
|
52
|
+
|
|
53
|
+
// Option 2: Using EIP-1193 provider (e.g., from browser wallet)
|
|
54
|
+
const wallet2 = new WalletManagerEvm(seedPhrase, {
|
|
55
|
+
provider: window.ethereum, // EIP-1193 provider
|
|
56
|
+
transferMaxFee: 100000000000000 // Optional: Maximum fee in wei
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
// Get a full access account
|
|
60
|
+
const account = await wallet.getAccount(0)
|
|
61
|
+
|
|
62
|
+
// Convert to a read-only account
|
|
63
|
+
const readOnlyAccount = await account.toReadOnlyAccount()
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Managing Multiple Accounts
|
|
67
|
+
|
|
68
|
+
```javascript
|
|
69
|
+
import WalletManagerEvm from '@tetherto/wdk-wallet-evm'
|
|
70
|
+
|
|
71
|
+
// Assume wallet is already created
|
|
72
|
+
// Get the first account (index 0)
|
|
73
|
+
const account = await wallet.getAccount(0)
|
|
74
|
+
const address = await account.getAddress()
|
|
75
|
+
console.log('Account 0 address:', address)
|
|
76
|
+
|
|
77
|
+
// Get the second account (index 1)
|
|
78
|
+
const account1 = await wallet.getAccount(1)
|
|
79
|
+
const address1 = await account1.getAddress()
|
|
80
|
+
console.log('Account 1 address:', address1)
|
|
81
|
+
|
|
82
|
+
// Get account by custom derivation path
|
|
83
|
+
// Full path will be m/44'/60'/0'/0/5
|
|
84
|
+
const customAccount = await wallet.getAccountByPath("0'/0/5")
|
|
85
|
+
const customAddress = await customAccount.getAddress()
|
|
86
|
+
console.log('Custom account address:', customAddress)
|
|
87
|
+
|
|
88
|
+
// Note: All addresses are checksummed Ethereum addresses (0x...)
|
|
89
|
+
// All accounts inherit the provider configuration from the wallet manager
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Checking Balances
|
|
93
|
+
|
|
94
|
+
#### Owned Account
|
|
95
|
+
|
|
96
|
+
For accounts where you have the seed phrase and full access:
|
|
97
|
+
|
|
98
|
+
```javascript
|
|
99
|
+
import WalletManagerEvm from '@tetherto/wdk-wallet-evm'
|
|
100
|
+
|
|
101
|
+
// Assume wallet and account are already created
|
|
102
|
+
// Get native token balance (in wei)
|
|
103
|
+
const balance = await account.getBalance()
|
|
104
|
+
console.log('Native balance:', balance, 'wei') // 1 ETH = 1000000000000000000 wei
|
|
105
|
+
|
|
106
|
+
// Get ERC20 token balance
|
|
107
|
+
const tokenContract = '0x...'; // ERC20 contract address
|
|
108
|
+
const tokenBalance = await account.getTokenBalance(tokenContract);
|
|
109
|
+
console.log('Token balance:', tokenBalance);
|
|
110
|
+
|
|
111
|
+
// Note: Provider is required for balance checks
|
|
112
|
+
// Make sure wallet was created with a provider configuration
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
#### Read-Only Account
|
|
116
|
+
|
|
117
|
+
For addresses where you don't have the seed phrase:
|
|
118
|
+
|
|
119
|
+
```javascript
|
|
120
|
+
import { WalletAccountReadOnlyEvm } from '@tetherto/wdk-wallet-evm'
|
|
121
|
+
|
|
122
|
+
// Create a read-only account
|
|
123
|
+
const readOnlyAccount = new WalletAccountReadOnlyEvm('0x...', { // Ethereum address
|
|
124
|
+
provider: 'https://eth-mainnet.g.alchemy.com/v2/your-api-key' // Required for balance checks
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
// Check native token balance
|
|
128
|
+
const balance = await readOnlyAccount.getBalance()
|
|
129
|
+
console.log('Native balance:', balance, 'wei')
|
|
130
|
+
|
|
131
|
+
// Check ERC20 token balance using contract
|
|
132
|
+
const tokenBalance = await readOnlyAccount.getTokenBalance('0x...') // ERC20 contract address
|
|
133
|
+
console.log('Token balance:', tokenBalance)
|
|
134
|
+
|
|
135
|
+
// Note: ERC20 balance checks use the standard balanceOf(address) function
|
|
136
|
+
// Make sure the contract address is correct and implements the ERC20 standard
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Sending Transactions
|
|
140
|
+
|
|
141
|
+
Send native tokens and estimate fees using `WalletAccountEvm`. Supports EIP-1559 fee model.
|
|
142
|
+
|
|
143
|
+
```javascript
|
|
144
|
+
// Send native tokens
|
|
145
|
+
// Modern EIP-1559 style transaction (recommended)
|
|
146
|
+
const result = await account.sendTransaction({
|
|
147
|
+
to: '0x...', // Recipient address
|
|
148
|
+
value: 1000000000000000000n, // 1 ETH in wei
|
|
149
|
+
maxFeePerGas: 30000000000, // Optional: max fee per gas (in wei)
|
|
150
|
+
maxPriorityFeePerGas: 2000000000 // Optional: max priority fee per gas (in wei)
|
|
151
|
+
})
|
|
152
|
+
console.log('Transaction hash:', result.hash)
|
|
153
|
+
console.log('Transaction fee:', result.fee, 'wei')
|
|
154
|
+
|
|
155
|
+
// OR Legacy style transaction
|
|
156
|
+
const legacyResult = await account.sendTransaction({
|
|
157
|
+
to: '0x...',
|
|
158
|
+
value: 1000000000000000000n,
|
|
159
|
+
gasPrice: 20000000000n, // Optional: legacy gas price (in wei)
|
|
160
|
+
gasLimit: 21000 // Optional: gas limit
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
// Get transaction fee estimate
|
|
164
|
+
const quote = await account.quoteSendTransaction({
|
|
165
|
+
to: '0x...',
|
|
166
|
+
value: 1000000000000000000n
|
|
167
|
+
});
|
|
168
|
+
console.log('Estimated fee:', quote.fee, 'wei');
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Token Transfers
|
|
172
|
+
|
|
173
|
+
Transfer ERC20 tokens and estimate fees using `WalletAccountEvm`. Uses standard ERC20 `transfer` function.
|
|
174
|
+
|
|
175
|
+
```javascript
|
|
176
|
+
// Transfer ERC20 tokens
|
|
177
|
+
const transferResult = await account.transfer({
|
|
178
|
+
token: '0x...', // ERC20 contract address
|
|
179
|
+
recipient: '0x...', // Recipient's address
|
|
180
|
+
amount: 1000000n // Amount in token's base units (use BigInt for large numbers)
|
|
181
|
+
});
|
|
182
|
+
console.log('Transfer hash:', transferResult.hash);
|
|
183
|
+
console.log('Transfer fee:', transferResult.fee, 'wei');
|
|
184
|
+
|
|
185
|
+
// Quote token transfer fee
|
|
186
|
+
const transferQuote = await account.quoteTransfer({
|
|
187
|
+
token: '0x...', // ERC20 contract address
|
|
188
|
+
recipient: '0x...', // Recipient's address
|
|
189
|
+
amount: 1000000n // Amount in token's base units
|
|
190
|
+
})
|
|
191
|
+
console.log('Transfer fee estimate:', transferQuote.fee, 'wei')
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Message Signing and Verification
|
|
195
|
+
|
|
196
|
+
Sign and verify messages using `WalletAccountEvm`.
|
|
197
|
+
|
|
198
|
+
```javascript
|
|
199
|
+
// Sign a message
|
|
200
|
+
const message = 'Hello, Ethereum!'
|
|
201
|
+
const signature = await account.sign(message)
|
|
202
|
+
console.log('Signature:', signature)
|
|
203
|
+
|
|
204
|
+
// Verify a signature
|
|
205
|
+
const isValid = await account.verify(message, signature)
|
|
206
|
+
console.log('Signature valid:', isValid)
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Fee Management
|
|
210
|
+
|
|
211
|
+
Retrieve current fee rates using `WalletManagerEvm`. Supports EIP-1559 fee model.
|
|
212
|
+
|
|
213
|
+
```javascript
|
|
214
|
+
// Get current fee rates
|
|
215
|
+
const feeRates = await wallet.getFeeRates();
|
|
216
|
+
console.log('Normal fee rate:', feeRates.normal, 'wei'); // 1.1x base fee
|
|
217
|
+
console.log('Fast fee rate:', feeRates.fast, 'wei'); // 2.0x base fee
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Memory Management
|
|
221
|
+
|
|
222
|
+
Clear sensitive data from memory using `dispose` methods in `WalletAccountEvm` and `WalletManagerEvm`.
|
|
223
|
+
|
|
224
|
+
```javascript
|
|
225
|
+
// Dispose wallet accounts to clear private keys from memory
|
|
226
|
+
account.dispose()
|
|
227
|
+
|
|
228
|
+
// Dispose entire wallet manager
|
|
229
|
+
wallet.dispose()
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## 📚 API Reference
|
|
233
|
+
|
|
234
|
+
### Table of Contents
|
|
235
|
+
|
|
236
|
+
### Table of Contents
|
|
237
|
+
|
|
238
|
+
| Class | Description | Methods |
|
|
239
|
+
|-------|-------------|---------|
|
|
240
|
+
| [WalletManagerEvm](#walletmanagerevm) | Main class for managing EVM wallets. Extends `WalletManager` from `@tetherto/wdk-wallet`. | [Constructor](#constructor), [Methods](#methods) |
|
|
241
|
+
| [WalletAccountEvm](#walletaccountevm) | Individual EVM wallet account implementation. Extends `WalletAccountReadOnlyEvm` and implements `IWalletAccount` from `@tetherto/wdk-wallet`. | [Constructor](#constructor-1), [Methods](#methods-1), [Properties](#properties) |
|
|
242
|
+
| [WalletAccountReadOnlyEvm](#walletaccountreadonlyevm) | Read-only EVM wallet account. Extends `WalletAccountReadOnly` from `@tetherto/wdk-wallet`. | [Constructor](#constructor-2), [Methods](#methods-2) |
|
|
243
|
+
|
|
244
|
+
### WalletManagerEvm
|
|
245
|
+
|
|
246
|
+
The main class for managing EVM wallets.
|
|
247
|
+
Extends `WalletManager` from `@tetherto/wdk-wallet`.
|
|
248
|
+
|
|
249
|
+
#### Constructor
|
|
250
|
+
|
|
251
|
+
```javascript
|
|
252
|
+
new WalletManagerEvm(seed, config)
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
**Parameters:**
|
|
256
|
+
- `seed` (string | Uint8Array): BIP-39 mnemonic seed phrase or seed bytes
|
|
257
|
+
- `config` (object, optional): Configuration object
|
|
258
|
+
- `provider` (string | Eip1193Provider): RPC endpoint URL or EIP-1193 provider instance
|
|
259
|
+
- `transferMaxFee` (number | bigint, optional): Maximum fee amount for transfer operations (in wei)
|
|
260
|
+
|
|
261
|
+
**Example:**
|
|
262
|
+
```javascript
|
|
263
|
+
const wallet = new WalletManagerEvm(seedPhrase, {
|
|
264
|
+
provider: 'https://eth-mainnet.g.alchemy.com/v2/your-api-key',
|
|
265
|
+
transferMaxFee: '100000000000000' // Maximum fee in wei
|
|
266
|
+
})
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
#### Methods
|
|
270
|
+
|
|
271
|
+
| Method | Description | Returns |
|
|
272
|
+
|--------|-------------|---------|
|
|
273
|
+
| `getAccount(index)` | Returns a wallet account at the specified index | `Promise<WalletAccountEvm>` |
|
|
274
|
+
| `getAccountByPath(path)` | Returns a wallet account at the specified BIP-44 derivation path | `Promise<WalletAccountEvm>` |
|
|
275
|
+
| `getFeeRates()` | Returns current fee rates for transactions | `Promise<{normal: bigint, fast: bigint}>` |
|
|
276
|
+
| `dispose()` | Disposes all wallet accounts, clearing private keys from memory | `void` |
|
|
277
|
+
|
|
278
|
+
### WalletAccountEvm
|
|
279
|
+
|
|
280
|
+
Represents an individual wallet account. Implements `IWalletAccount` from `@tetherto/wdk-wallet`.
|
|
281
|
+
|
|
282
|
+
#### Constructor
|
|
283
|
+
|
|
284
|
+
```javascript
|
|
285
|
+
new WalletAccountEvm(seed, path, config)
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
**Parameters:**
|
|
289
|
+
- `seed` (string | Uint8Array): BIP-39 mnemonic seed phrase or seed bytes
|
|
290
|
+
- `path` (string): BIP-44 derivation path (e.g., "0'/0/0")
|
|
291
|
+
- `config` (object, optional): Configuration object
|
|
292
|
+
- `provider` (string | Eip1193Provider): RPC endpoint URL or EIP-1193 provider instance
|
|
293
|
+
- `transferMaxFee` (number | bigint, optional): Maximum fee amount for transfer operations (in wei)
|
|
294
|
+
|
|
295
|
+
#### Methods
|
|
296
|
+
|
|
297
|
+
| Method | Description | Returns |
|
|
298
|
+
|--------|-------------|---------|
|
|
299
|
+
| `getAddress()` | Returns the account's address | `Promise<string>` |
|
|
300
|
+
| `sign(message)` | Signs a message using the account's private key | `Promise<string>` |
|
|
301
|
+
| `verify(message, signature)` | Verifies a message signature | `Promise<boolean>` |
|
|
302
|
+
| `sendTransaction(tx)` | Sends an EVM transaction | `Promise<{hash: string, fee: bigint}>` |
|
|
303
|
+
| `quoteSendTransaction(tx)` | Estimates the fee for an EVM transaction | `Promise<{fee: bigint}>` |
|
|
304
|
+
| `transfer(options)` | Transfers ERC20 tokens to another address | `Promise<{hash: string, fee: bigint}>` |
|
|
305
|
+
| `quoteTransfer(options)` | Estimates the fee for an ERC20 transfer | `Promise<{fee: bigint}>` |
|
|
306
|
+
| `getBalance()` | Returns the native token balance (in wei) | `Promise<bigint>` |
|
|
307
|
+
| `getTokenBalance(tokenAddress)` | Returns the balance of a specific ERC20 token | `Promise<bigint>` |
|
|
308
|
+
| `dispose()` | Disposes the wallet account, clearing private keys from memory | `void` |
|
|
309
|
+
|
|
310
|
+
##### `sendTransaction(tx)`
|
|
311
|
+
Sends an EVM transaction.
|
|
312
|
+
|
|
313
|
+
**Parameters:**
|
|
314
|
+
- `tx` (object): The transaction object
|
|
315
|
+
- `to` (string): Recipient address
|
|
316
|
+
- `value` (number | bigint): Amount in wei
|
|
317
|
+
- `data` (string, optional): Transaction data in hex format
|
|
318
|
+
- `gasLimit` (number | bigint, optional): Maximum gas units
|
|
319
|
+
- `gasPrice` (number | bigint, optional): Legacy gas price in wei
|
|
320
|
+
- `maxFeePerGas` (number | bigint, optional): EIP-1559 max fee per gas in wei
|
|
321
|
+
- `maxPriorityFeePerGas` (number | bigint, optional): EIP-1559 max priority fee per gas in wei
|
|
322
|
+
|
|
323
|
+
**Returns:** `Promise<{hash: string, fee: bigint}>` - Object containing hash and fee (in wei)
|
|
324
|
+
|
|
325
|
+
#### Properties
|
|
326
|
+
|
|
327
|
+
| Property | Type | Description |
|
|
328
|
+
|----------|------|-------------|
|
|
329
|
+
| `index` | `number` | The derivation path's index of this account |
|
|
330
|
+
| `path` | `string` | The full derivation path of this account |
|
|
331
|
+
| `keyPair` | `object` | The account's key pair (⚠️ Contains sensitive data) |
|
|
332
|
+
|
|
333
|
+
⚠️ **Security Note**: The `keyPair` property contains sensitive cryptographic material. Never log, display, or expose the private key.
|
|
334
|
+
|
|
335
|
+
### WalletAccountReadOnlyEvm
|
|
336
|
+
|
|
337
|
+
Represents a read-only wallet account.
|
|
338
|
+
|
|
339
|
+
#### Constructor
|
|
340
|
+
|
|
341
|
+
```javascript
|
|
342
|
+
new WalletAccountReadOnlyEvm(address, config)
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
**Parameters:**
|
|
346
|
+
- `address` (string): The account's address
|
|
347
|
+
- `config` (object, optional): Configuration object
|
|
348
|
+
- `provider` (string | Eip1193Provider): RPC endpoint URL or EIP-1193 provider instance
|
|
349
|
+
|
|
350
|
+
#### Methods
|
|
351
|
+
|
|
352
|
+
| Method | Description | Returns |
|
|
353
|
+
|--------|-------------|---------|
|
|
354
|
+
| `getBalance()` | Returns the native token balance (in wei) | `Promise<bigint>` |
|
|
355
|
+
| `getTokenBalance(tokenAddress)` | Returns the balance of a specific ERC20 token | `Promise<bigint>` |
|
|
356
|
+
| `quoteSendTransaction(tx)` | Estimates the fee for an EVM transaction | `Promise<{fee: bigint}>` |
|
|
357
|
+
| `quoteTransfer(options)` | Estimates the fee for an ERC20 transfer | `Promise<{fee: bigint}>` |
|
|
358
|
+
|
|
359
|
+
## 🌐 Supported Networks
|
|
360
|
+
|
|
361
|
+
This package works with any EVM-compatible blockchain, including:
|
|
362
|
+
|
|
363
|
+
- **Ethereum Mainnet**
|
|
364
|
+
- **Ethereum Testnets** (Sepolia, etc.)
|
|
365
|
+
- **Layer 2 Networks** (Arbitrum, Optimism, etc.)
|
|
366
|
+
- **Other EVM Chains** (Polygon, Avalanche C-Chain, etc.)
|
|
367
|
+
|
|
368
|
+
## 🔒 Security Considerations
|
|
369
|
+
|
|
370
|
+
- **Seed Phrase Security**: Always store your seed phrase securely and never share it
|
|
371
|
+
- **Private Key Management**: The package handles private keys internally with memory safety features
|
|
372
|
+
- **Provider Security**: Use trusted RPC endpoints and consider running your own node for production
|
|
373
|
+
- **Transaction Validation**: Always validate transaction details before signing
|
|
374
|
+
- **Memory Cleanup**: Use the `dispose()` method to clear private keys from memory when done
|
|
375
|
+
- **Fee Limits**: Set `transferMaxFee` in config to prevent excessive transaction fees
|
|
376
|
+
- **Gas Estimation**: Always estimate gas before sending transactions
|
|
377
|
+
- **EIP-1559**: Consider using EIP-1559 fee model for better gas price estimation
|
|
378
|
+
- **Contract Interactions**: Verify contract addresses and token decimals before transfers
|
|
379
|
+
|
|
380
|
+
## 🛠️ Development
|
|
381
|
+
|
|
382
|
+
### Building
|
|
383
|
+
|
|
384
|
+
```bash
|
|
385
|
+
# Install dependencies
|
|
386
|
+
npm install
|
|
387
|
+
|
|
388
|
+
# Build TypeScript definitions
|
|
389
|
+
npm run build:types
|
|
390
|
+
|
|
391
|
+
# Lint code
|
|
392
|
+
npm run lint
|
|
393
|
+
|
|
394
|
+
# Fix linting issues
|
|
395
|
+
npm run lint:fix
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
### Testing
|
|
399
|
+
|
|
400
|
+
```bash
|
|
401
|
+
# Run tests
|
|
402
|
+
npm test
|
|
403
|
+
|
|
404
|
+
# Run tests with coverage
|
|
405
|
+
npm run test:coverage
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
## 📜 License
|
|
409
|
+
|
|
410
|
+
This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.
|
|
411
|
+
|
|
412
|
+
## 🤝 Contributing
|
|
413
|
+
|
|
414
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
415
|
+
|
|
416
|
+
## 🆘 Support
|
|
417
|
+
|
|
418
|
+
For support, please open an issue on the GitHub repository.
|
|
419
|
+
|
|
420
|
+
---
|
package/bare.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Copyright 2024 Tether Operations Limited
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
'use strict'
|
|
15
|
+
|
|
16
|
+
import 'bare-wdk-runtime'
|
|
17
|
+
|
|
18
|
+
export * from './index.js' with { imports: 'bare-wdk-runtime/package' }
|
|
19
|
+
|
|
20
|
+
export { default } from './index.js' with { imports: 'bare-wdk-runtime/package' }
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require('@nomicfoundation/hardhat-ethers')
|
|
2
|
+
|
|
3
|
+
/** @type {import('hardhat/config').HardhatUserConfig} */
|
|
4
|
+
module.exports = {
|
|
5
|
+
networks: {
|
|
6
|
+
hardhat: {
|
|
7
|
+
accounts: {
|
|
8
|
+
mnemonic: 'anger burst story spy face pattern whale quit delay fiction ball solve',
|
|
9
|
+
path: "m/44'/60'/0'/0",
|
|
10
|
+
initialIndex: 0,
|
|
11
|
+
count: 1,
|
|
12
|
+
accountsBalance: '1000000000000000000000'
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
package/index.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Copyright 2024 Tether Operations Limited
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
'use strict'
|
|
15
|
+
|
|
16
|
+
/** @typedef {import('ethers').TransactionReceipt} EvmTransactionReceipt */
|
|
17
|
+
|
|
18
|
+
/** @typedef {import('@tetherto/wdk-wallet').FeeRates} FeeRates */
|
|
19
|
+
/** @typedef {import('@tetherto/wdk-wallet').KeyPair} KeyPair */
|
|
20
|
+
/** @typedef {import('@tetherto/wdk-wallet').TransactionResult} TransactionResult */
|
|
21
|
+
/** @typedef {import('@tetherto/wdk-wallet').TransferOptions} TransferOptions */
|
|
22
|
+
/** @typedef {import('@tetherto/wdk-wallet').TransferResult} TransferResult */
|
|
23
|
+
|
|
24
|
+
/** @typedef {import('./src/wallet-account-read-only-evm.js').EvmTransaction} EvmTransaction */
|
|
25
|
+
/** @typedef {import('./src/wallet-account-read-only-evm.js').EvmWalletConfig} EvmWalletConfig */
|
|
26
|
+
|
|
27
|
+
export { default } from './src/wallet-manager-evm.js'
|
|
28
|
+
|
|
29
|
+
export { default as WalletAccountReadOnlyEvm } from './src/wallet-account-read-only-evm.js'
|
|
30
|
+
|
|
31
|
+
export { default as WalletAccountEvm } from './src/wallet-account-evm.js'
|