@altiuslabs/tx-sdk 0.1.19 → 0.1.21
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/README.md +269 -15
- package/package.json +1 -1
- package/src/constants.js +11 -6
- package/src/index.js +1 -1
- package/src/utils.js +28 -0
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ npm install @altiuslabs/tx-sdk
|
|
|
14
14
|
|
|
15
15
|
```javascript
|
|
16
16
|
import { TxClient, generate_private_key } from '@altiuslabs/tx-sdk';
|
|
17
|
-
import { USDA_ADDRESS } from '@
|
|
17
|
+
import { USDA_ADDRESS } from '@altiuslabs/tx-sdk';
|
|
18
18
|
|
|
19
19
|
// Generate a new wallet
|
|
20
20
|
const privateKey = generate_private_key();
|
|
@@ -56,28 +56,278 @@ const { tx_hash } = await client.send_erc20_transfer(
|
|
|
56
56
|
const receipt = await client.send_and_wait(tx, 60000);
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
+
---
|
|
60
|
+
|
|
59
61
|
## API Reference
|
|
60
62
|
|
|
61
|
-
###
|
|
63
|
+
### Wallet & Signing
|
|
62
64
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
- **RpcClient** - JSON-RPC interaction
|
|
66
|
-
- **NonceManager** - Nonce management
|
|
67
|
-
- **TxBuilder** - Transaction building
|
|
65
|
+
#### `generate_private_key() => string`
|
|
66
|
+
Generate a new random private key.
|
|
68
67
|
|
|
69
|
-
|
|
68
|
+
```javascript
|
|
69
|
+
const privateKey = generate_private_key();
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
#### `private_key_to_address(privateKey: string) => string`
|
|
73
|
+
Derive address from private key.
|
|
74
|
+
|
|
75
|
+
```javascript
|
|
76
|
+
const address = private_key_to_address('0x...');
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
#### `Wallet`
|
|
80
|
+
Wallet class for local transaction signing.
|
|
81
|
+
|
|
82
|
+
```javascript
|
|
83
|
+
import { Wallet } from '@altiuslabs/tx-sdk';
|
|
84
|
+
|
|
85
|
+
// Create wallet from private key
|
|
86
|
+
const wallet = new Wallet('0x...');
|
|
87
|
+
|
|
88
|
+
// Get address
|
|
89
|
+
console.log(wallet.address); // '0x...'
|
|
90
|
+
|
|
91
|
+
// Sign hash
|
|
92
|
+
const signature = await wallet.sign_hash('0x...');
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
### Transaction Builder
|
|
98
|
+
|
|
99
|
+
#### `create_transaction() => TxBuilder`
|
|
100
|
+
Create a new transaction builder.
|
|
101
|
+
|
|
102
|
+
```javascript
|
|
103
|
+
import { create_transaction } from '@altiuslabs/tx-sdk';
|
|
104
|
+
|
|
105
|
+
const tx = create_transaction()
|
|
106
|
+
.chain_id(1)
|
|
107
|
+
.nonce(0)
|
|
108
|
+
.gas_limit(21000)
|
|
109
|
+
.to('0x...')
|
|
110
|
+
.value(0)
|
|
111
|
+
.data('0x...')
|
|
112
|
+
.fee_token('0xa1700000000000000000000000000000000000001')
|
|
113
|
+
.max_fee_per_gas_usd(50000000000);
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
#### `TxBuilder` Methods
|
|
117
|
+
|
|
118
|
+
| Method | Description |
|
|
119
|
+
|--------|-------------|
|
|
120
|
+
| `.chain_id(id)` | Set chain ID |
|
|
121
|
+
| `.nonce(nonce)` | Set transaction nonce |
|
|
122
|
+
| `.gas_limit(limit)` | Set gas limit |
|
|
123
|
+
| `.to(address)` | Set recipient address |
|
|
124
|
+
| `.value(amount)` | Set transaction value (in wei) |
|
|
125
|
+
| `.data(calldata)` | Set input data |
|
|
126
|
+
| `.max_priority_fee_per_gas(gas)` | Set max priority fee per gas |
|
|
127
|
+
| `.max_fee_per_gas(gas)` | Set max fee per gas |
|
|
128
|
+
| `.fee_token(address)` | Set fee token address |
|
|
129
|
+
| `.fee_payer(address)` | Set fee payer address (optional, defaults to sender) |
|
|
130
|
+
| `.max_fee_per_gas_usd(usd)` | Set max fee per gas in USD attodollars |
|
|
131
|
+
| `.fee_payer_signature(signature)` | Set fee payer signature |
|
|
132
|
+
| `.erc20_transfer(token, to, amount)` | Build ERC20 transfer |
|
|
133
|
+
| `.build()` | Build transaction object |
|
|
134
|
+
| `.signature_hash()` | Compute signature hash |
|
|
135
|
+
| `.sign(wallet)` | Sign transaction with wallet |
|
|
136
|
+
|
|
137
|
+
#### `fee_payer_signature_hash(tx: object, sender: string) => string`
|
|
138
|
+
Calculate the hash that fee_payer should sign.
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
### RPC Client
|
|
143
|
+
|
|
144
|
+
#### `create_rpc_client(url: string) => RpcClient`
|
|
145
|
+
Create an RPC client.
|
|
146
|
+
|
|
147
|
+
```javascript
|
|
148
|
+
import { create_rpc_client } from '@altiuslabs/tx-sdk';
|
|
149
|
+
|
|
150
|
+
const rpc = create_rpc_client('https://rpc.altius.xyz');
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
#### `RpcClient` Methods
|
|
154
|
+
|
|
155
|
+
| Method | Description |
|
|
156
|
+
|--------|-------------|
|
|
157
|
+
| `.get_chain_id()` | Get chain ID |
|
|
158
|
+
| `.get_block_number()` | Get latest block number |
|
|
159
|
+
| `.get_balance(address)` | Get native ETH balance |
|
|
160
|
+
| `.get_nonce(address)` | Get transaction count (nonce) |
|
|
161
|
+
| `.get_code(address)` | Get contract code at address |
|
|
162
|
+
| `.call(call_object)` | Execute contract call |
|
|
163
|
+
| `.send_raw_transaction(tx)` | Send signed transaction |
|
|
164
|
+
| `.get_transaction_receipt(hash)` | Get transaction receipt |
|
|
165
|
+
| `.wait_for_receipt(hash, timeout_ms)` | Wait for transaction to be mined |
|
|
166
|
+
| `.get_erc20_balance(token, owner)` | Get ERC20 token balance |
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
### Nonce Manager
|
|
171
|
+
|
|
172
|
+
#### `create_nonce_manager(rpc: RpcClient, address: string) => NonceManager`
|
|
173
|
+
Create a nonce manager.
|
|
70
174
|
|
|
71
175
|
```javascript
|
|
72
|
-
import {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
FEE_MANAGER_ADDRESS,
|
|
76
|
-
BASE_FEE_ATTO,
|
|
77
|
-
DEFAULT_GAS_LIMIT,
|
|
78
|
-
} from '@altiuslabs/tx-sdk/constants';
|
|
176
|
+
import { create_nonce_manager } from '@altiuslabs/tx-sdk';
|
|
177
|
+
|
|
178
|
+
const nm = create_nonce_manager(rpc, address);
|
|
79
179
|
```
|
|
80
180
|
|
|
181
|
+
#### `NonceManager` Methods
|
|
182
|
+
|
|
183
|
+
| Method | Description |
|
|
184
|
+
|--------|-------------|
|
|
185
|
+
| `.get_nonce()` | Get current nonce |
|
|
186
|
+
| `.get_and_increment_nonce()` | Get and increment nonce |
|
|
187
|
+
| `.reset_nonce()` | Reset nonce cache |
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
### High-Level Client
|
|
192
|
+
|
|
193
|
+
#### `create_tx_client(privateKey: string, rpcUrl: string, feeToken: string) => TxClient`
|
|
194
|
+
Create a high-level transaction client.
|
|
195
|
+
|
|
196
|
+
```javascript
|
|
197
|
+
import { create_tx_client } from '@altiuslabs/tx-sdk';
|
|
198
|
+
import { USDA_ADDRESS } from '@altiuslabs/tx-sdk';
|
|
199
|
+
|
|
200
|
+
const client = create_tx_client(privateKey, 'https://rpc.altius.xyz', USDA_ADDRESS);
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
#### `TxClientBuilder`
|
|
204
|
+
|
|
205
|
+
```javascript
|
|
206
|
+
import { TxClientBuilder } from '@altiuslabs/tx-sdk';
|
|
207
|
+
|
|
208
|
+
const client = new TxClientBuilder(privateKey, 'https://rpc.altius.xyz')
|
|
209
|
+
.fee_token(USDA_ADDRESS)
|
|
210
|
+
.base_fee(50000000000)
|
|
211
|
+
.gas_limit(100000)
|
|
212
|
+
.build();
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
#### `TxClient` Methods
|
|
216
|
+
|
|
217
|
+
| Method | Description |
|
|
218
|
+
|--------|-------------|
|
|
219
|
+
| `.address()` | Get wallet address |
|
|
220
|
+
| `.chain_id()` | Get chain ID |
|
|
221
|
+
| `.get_nonce()` | Get current nonce |
|
|
222
|
+
| `.build_erc20_transfer(token, recipient, amount)` | Build ERC20 transfer |
|
|
223
|
+
| `.sign(tx)` | Sign transaction |
|
|
224
|
+
| `.send(tx)` | Send transaction |
|
|
225
|
+
| `.send_and_wait(tx, timeout_ms)` | Send and wait for receipt |
|
|
226
|
+
| `.send_erc20_transfer(token, recipient, amount)` | Send ERC20 transfer |
|
|
227
|
+
| `.transfer_usda(recipient, amount_micro)` | Transfer USDA (amount in microdollars) |
|
|
228
|
+
| `.fee_token_balance(address)` | Get fee token balance |
|
|
229
|
+
| `.native_balance(address)` | Get native ETH balance |
|
|
230
|
+
| `.reset_nonce()` | Reset nonce cache |
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
### Utilities
|
|
235
|
+
|
|
236
|
+
#### `keccak256(data: string | Buffer) => string`
|
|
237
|
+
Compute keccak256 hash.
|
|
238
|
+
|
|
239
|
+
```javascript
|
|
240
|
+
import { keccak256 } from '@altiuslabs/tx-sdk';
|
|
241
|
+
|
|
242
|
+
const hash = keccak256('0x...');
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
#### `pad_hex(hex: string, bytes: number) => string`
|
|
246
|
+
Pad hex string to specified length.
|
|
247
|
+
|
|
248
|
+
```javascript
|
|
249
|
+
import { pad_hex } from '@altiuslabs/tx-sdk';
|
|
250
|
+
|
|
251
|
+
pad_hex('0x1234', 32); // '0x0000000000000000000000000000000000000000000000000000000000001234'
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
#### `num_to_hex(num: number, bytes?: number) => string`
|
|
255
|
+
Convert number to padded hex.
|
|
256
|
+
|
|
257
|
+
```javascript
|
|
258
|
+
import { num_to_hex } from '@altiuslabs/tx-sdk';
|
|
259
|
+
|
|
260
|
+
num_to_hex(123, 32); // '0x000000000000000000000000000000000000000000000000000000000000007b'
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
#### `rlp_encode(items: array) => string`
|
|
264
|
+
RLP encode an array.
|
|
265
|
+
|
|
266
|
+
```javascript
|
|
267
|
+
import { rlp_encode } from '@altiuslabs/tx-sdk';
|
|
268
|
+
|
|
269
|
+
const encoded = rlp_encode([1, 2, 3]);
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
#### `computeFeeTokenAddress(creator: string, salt: string) => { address: string, index: bigint }`
|
|
273
|
+
Compute deterministic fee token address.
|
|
274
|
+
|
|
275
|
+
```javascript
|
|
276
|
+
import { computeFeeTokenAddress } from '@altiuslabs/tx-sdk';
|
|
277
|
+
|
|
278
|
+
const { address, index } = computeFeeTokenAddress(creator, salt);
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
#### `is_fee_token_prefix(address: string) => boolean`
|
|
282
|
+
Check if address has fee token prefix (0xa170...).
|
|
283
|
+
|
|
284
|
+
```javascript
|
|
285
|
+
import { is_fee_token_prefix } from '@altiuslabs/tx-sdk';
|
|
286
|
+
|
|
287
|
+
is_fee_token_prefix('0xa1700000000000000000000000000000000000001'); // true
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
#### `is_valid_fee_token_address(address: string) => boolean`
|
|
291
|
+
Check if address is valid fee token (has prefix and not zero).
|
|
292
|
+
|
|
293
|
+
```javascript
|
|
294
|
+
import { is_valid_fee_token_address } from '@altiuslabs/tx-sdk';
|
|
295
|
+
|
|
296
|
+
is_valid_fee_token_address('0xa1700000000000000000000000000000000000001'); // true
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
#### `is_index_reserved(index: bigint | number) => boolean`
|
|
300
|
+
Check if index is reserved (index < 256).
|
|
301
|
+
|
|
302
|
+
```javascript
|
|
303
|
+
import { is_index_reserved } from '@altiuslabs/tx-sdk';
|
|
304
|
+
|
|
305
|
+
is_index_reserved(100n); // true
|
|
306
|
+
is_index_reserved(300n); // false
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
### Constants
|
|
312
|
+
|
|
313
|
+
| Constant | Description |
|
|
314
|
+
|----------|-------------|
|
|
315
|
+
| `USDA_ADDRESS` | USDA Fee Token: `0xa1700000000000000000000000000000000000001` |
|
|
316
|
+
| `FEE_TOKEN_FACTORY_ADDRESS` | Fee Token Factory: `0xa170000000000000000000000000000000000000` |
|
|
317
|
+
| `FEE_MANAGER_ADDRESS` | Fee Manager: `0xFE00000000000000000000000000000000000001` |
|
|
318
|
+
| `ZERO_ADDRESS` | Zero address: `0x0000000000000000000000000000000000000000` |
|
|
319
|
+
| `BASE_FEE_ATTO` | Base fee: 50,000,000,000 (50 G-attodollars/gas) |
|
|
320
|
+
| `DEFAULT_MAX_FEE_PER_GAS` | Default max fee: 100,000,000,000 |
|
|
321
|
+
| `DEFAULT_GAS_LIMIT` | Default gas limit: 100,000 |
|
|
322
|
+
| `FAUCET_AMOUNT_MICRO` | Faucet amount: 100,000,000 microdollars |
|
|
323
|
+
| `FAUCET_AMOUNT_WEI` | Faucet amount: 100,000,000,000,000,000,000 wei |
|
|
324
|
+
| `TRANSFER_AMOUNT_MICRO` | Default transfer: 10,000,000 microdollars |
|
|
325
|
+
| `TRANSFER_AMOUNT_WEI` | Default transfer: 10,000,000,000,000,000,000 wei |
|
|
326
|
+
| `RESERVED_THRESHOLD` | Reserved threshold: 256 |
|
|
327
|
+
| `FAUCET_FEE_TOKEN` | Default faucet fee token (same as USDA_ADDRESS) |
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
81
331
|
## Security
|
|
82
332
|
|
|
83
333
|
**IMPORTANT**: Private keys never leave the client. All signing happens locally.
|
|
@@ -91,6 +341,8 @@ const signedTx = await client.sign(tx);
|
|
|
91
341
|
await rpcClient.send('eth_sendRawTransaction', [signedTx.raw_transaction]);
|
|
92
342
|
```
|
|
93
343
|
|
|
344
|
+
---
|
|
345
|
+
|
|
94
346
|
## Transaction Type
|
|
95
347
|
|
|
96
348
|
This SDK supports the USD Multi-Token fee model (0x7a transaction type):
|
|
@@ -99,6 +351,8 @@ This SDK supports the USD Multi-Token fee model (0x7a transaction type):
|
|
|
99
351
|
- **fee_payer**: Account paying the fee (optional, defaults to sender)
|
|
100
352
|
- **max_fee_per_gas_usd_attodollars**: Max gas price in USD attodollars/gas
|
|
101
353
|
|
|
354
|
+
---
|
|
355
|
+
|
|
102
356
|
## License
|
|
103
357
|
|
|
104
358
|
MIT
|
package/package.json
CHANGED
package/src/constants.js
CHANGED
|
@@ -32,15 +32,10 @@ export const FEE_TOKEN_FACTORY_ADDRESS = '0xa17000000000000000000000000000000000
|
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* Fee Manager (Independent prefix)
|
|
35
|
-
* Address:
|
|
35
|
+
* Address: 0xFE00000000000000000000000000000000000001
|
|
36
36
|
*/
|
|
37
37
|
export const FEE_MANAGER_ADDRESS = '0xFE00000000000000000000000000000000000001';
|
|
38
38
|
|
|
39
|
-
/**
|
|
40
|
-
* Fee token prefix (10 bytes) for validation
|
|
41
|
-
*/
|
|
42
|
-
export const FEE_TOKEN_PREFIX = '0xa1700000';
|
|
43
|
-
|
|
44
39
|
/**
|
|
45
40
|
* Zero address
|
|
46
41
|
*/
|
|
@@ -87,6 +82,16 @@ export const FAUCET_AMOUNT_MICRO = BigInt(100_000_000);
|
|
|
87
82
|
*/
|
|
88
83
|
export const FAUCET_AMOUNT_WEI = BigInt(100_000_000_000_000_000_000);
|
|
89
84
|
|
|
85
|
+
/**
|
|
86
|
+
* Default faucet amount in token units (100 USDA with 18 decimals)
|
|
87
|
+
*/
|
|
88
|
+
export const DEFAULT_FAUCET_AMOUNT = BigInt(100_000_000_000_000_000_000);
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Default faucet amount in microdollars
|
|
92
|
+
*/
|
|
93
|
+
export const DEFAULT_FAUCET_AMOUNT_MICRO = 100_000_000;
|
|
94
|
+
|
|
90
95
|
/**
|
|
91
96
|
* Default transfer amount in microdollars (10 USDA)
|
|
92
97
|
*/
|
package/src/index.js
CHANGED
|
@@ -26,7 +26,7 @@ export { NonceManager, create_nonce_manager } from './nonce.js';
|
|
|
26
26
|
export { TxClient, TxClientBuilder, create_tx_client } from './client.js';
|
|
27
27
|
|
|
28
28
|
// Utilities
|
|
29
|
-
export { keccak256, pad_hex, num_to_hex, rlp_encode, transaction_hash, computeFeeTokenAddress, isReservedAddress } from './utils.js';
|
|
29
|
+
export { keccak256, pad_hex, num_to_hex, rlp_encode, transaction_hash, computeFeeTokenAddress, isReservedAddress, is_fee_token_prefix, is_valid_fee_token_address, is_index_reserved } from './utils.js';
|
|
30
30
|
|
|
31
31
|
// Constants
|
|
32
32
|
export * from './constants.js';
|
package/src/utils.js
CHANGED
|
@@ -117,3 +117,31 @@ export function isReservedAddress(address, creator, salt) {
|
|
|
117
117
|
const { index } = computeFeeTokenAddress(creator, salt);
|
|
118
118
|
return index < 256n;
|
|
119
119
|
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Check if address has fee token prefix (0xa170...)
|
|
123
|
+
* @param {string} address - Address to check
|
|
124
|
+
* @returns {boolean} True if has fee token prefix
|
|
125
|
+
*/
|
|
126
|
+
export function is_fee_token_prefix(address) {
|
|
127
|
+
const clean = address.startsWith('0x') ? address.slice(2) : address;
|
|
128
|
+
return clean.startsWith('a170');
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Check if address is valid fee token (has prefix and not zero)
|
|
133
|
+
* @param {string} address - Address to check
|
|
134
|
+
* @returns {boolean} True if valid fee token address
|
|
135
|
+
*/
|
|
136
|
+
export function is_valid_fee_token_address(address) {
|
|
137
|
+
return is_fee_token_prefix(address) && address !== '0x0000000000000000000000000000000000000000';
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Check if index is reserved (index < 256)
|
|
142
|
+
* @param {bigint|number} index - Index to check
|
|
143
|
+
* @returns {boolean} True if reserved
|
|
144
|
+
*/
|
|
145
|
+
export function is_index_reserved(index) {
|
|
146
|
+
return BigInt(index) < 256n;
|
|
147
|
+
}
|