@sidhujag/sysweb3-keyring 2.1.0 → 2.1.1
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/CHANGELOG.md +11 -0
- package/README.md +46 -108
- package/cjs/evm-fees.js +223 -0
- package/cjs/evm-fees.js.map +1 -0
- package/cjs/keyring-core.js +1 -227
- package/cjs/keyring-core.js.map +1 -1
- package/cjs/keyring-manager.js +4 -3
- package/cjs/keyring-manager.js.map +1 -1
- package/cjs/software.js +12 -11
- package/cjs/software.js.map +1 -1
- package/cjs/transactions/ethereum.js +194 -190
- package/cjs/transactions/ethereum.js.map +1 -1
- package/cjs/transactions/evm-local-signer.js +28 -7
- package/cjs/transactions/evm-local-signer.js.map +1 -1
- package/cjs/transactions/evm-submission.js +179 -0
- package/cjs/transactions/evm-submission.js.map +1 -0
- package/cjs/transactions/index.js +1 -0
- package/cjs/transactions/index.js.map +1 -1
- package/cjs/transactions/prepared-evm.js +2 -0
- package/cjs/transactions/prepared-evm.js.map +1 -1
- package/cjs/types.js.map +1 -1
- package/cjs/utils/derivation-paths.js +4 -3
- package/cjs/utils/derivation-paths.js.map +1 -1
- package/cjs/utils/watch-descriptor.js +3 -2
- package/cjs/utils/watch-descriptor.js.map +1 -1
- package/esm/types.js.map +1 -1
- package/esm/utils/derivation-paths.js +2 -1
- package/esm/utils/derivation-paths.js.map +1 -1
- package/package.json +24 -11
- package/types/evm-fees.d.ts +42 -0
- package/types/keyring-core.d.ts +3 -8
- package/types/keyring-manager.d.ts +8 -3
- package/types/software.d.ts +6 -11
- package/types/transactions/ethereum.d.ts +10 -8
- package/types/transactions/evm-local-signer.d.ts +4 -1
- package/types/transactions/evm-submission.d.ts +48 -0
- package/types/transactions/index.d.ts +1 -0
- package/types/types.d.ts +4 -0
- package/cjs/bip84-native.js +0 -8
- package/cjs/bip84-native.js.map +0 -1
- package/cjs/public-bip84.js +0 -157
- package/cjs/public-bip84.js.map +0 -1
- package/cjs/software-utxo-account.js +0 -12
- package/cjs/software-utxo-account.js.map +0 -1
- package/cjs/transactions/bip84-native-plan.js +0 -481
- package/cjs/transactions/bip84-native-plan.js.map +0 -1
- package/cjs/transactions/prepared-bip84.js +0 -214
- package/cjs/transactions/prepared-bip84.js.map +0 -1
- package/types/bip84-native.d.ts +0 -3
- package/types/public-bip84.d.ts +0 -39
- package/types/software-utxo-account.d.ts +0 -13
- package/types/transactions/bip84-native-plan.d.ts +0 -83
- package/types/transactions/prepared-bip84.d.ts +0 -27
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Unreleased — API removal pending release-version decision
|
|
4
|
+
|
|
5
|
+
- Remove the duplicate public BIP84 and bounded native-transfer APIs introduced in 2.1.0. Existing descriptor, SJS/HD and generic PSBT paths remain. This removes published exports and is **not** a compatible 2.1.1 patch. Historical 2.1.0 notes below describe the already-published package.
|
|
6
|
+
|
|
7
|
+
## 2.1.1
|
|
8
|
+
|
|
9
|
+
- Share the existing successful gas-estimate 20% buffer/minimum calculation through `bufferedEvmGasLimit`; SDK and mobile can use the same integer rounding without copying the formula.
|
|
10
|
+
|
|
11
|
+
- Expose dependency-free `cjs/evm-fees` for the existing standard EVM fee recommendation and make `EthereumTransactions` use the same implementation.
|
|
12
|
+
- Keep observed legacy/EIP-1559 behavior, zero tips, configured floors/multipliers, and unsupported-method-only history fallback. Add uint256/history bounds, snapshot options, synchronous host guards and cancellation checks for restricted hosts.
|
|
13
|
+
|
|
3
14
|
## 2.1.0
|
|
4
15
|
|
|
5
16
|
- Add the standalone `cjs/public-bip84` entry for strict Bitcoin/Syscoin mainnet account parsing and native SegWit address derivation. It returns public data only; an account public key does not prove ancestry or ownership.
|
package/README.md
CHANGED
|
@@ -74,114 +74,6 @@ const keyringManager = await KeyringManager.createInitialized(
|
|
|
74
74
|
);
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
-
### Offline BIP84 public account derivation
|
|
78
|
-
|
|
79
|
-
The standalone public entry accepts a bare **mainnet xpub or zpub** for a depth-3
|
|
80
|
-
account whose child number is hardened. It derives only native SegWit P2WPKH
|
|
81
|
-
addresses at `/0/index` (receive) or `/1/index` (change), with a nonhardened index
|
|
82
|
-
from 0 through 2,147,483,647. Choose `bitcoin` or `syscoin` explicitly. Testnet
|
|
83
|
-
versions, private keys, descriptors, origin/path suffixes and arbitrary networks
|
|
84
|
-
are rejected. Requests must be plain own-data objects with exactly the documented
|
|
85
|
-
fields; inherited properties, getters and extra fields are rejected. Existing
|
|
86
|
-
generic watch-descriptor and keyring APIs are unchanged.
|
|
87
|
-
|
|
88
|
-
```typescript
|
|
89
|
-
import {
|
|
90
|
-
parseBip84PublicAccount,
|
|
91
|
-
deriveBip84PublicAddress,
|
|
92
|
-
} from '@sidhujag/sysweb3-keyring/cjs/public-bip84';
|
|
93
|
-
|
|
94
|
-
const account = parseBip84PublicAccount({
|
|
95
|
-
network: 'syscoin',
|
|
96
|
-
accountKey: exportedPublicAccountKey,
|
|
97
|
-
});
|
|
98
|
-
const receive = deriveBip84PublicAddress({
|
|
99
|
-
network: account.network,
|
|
100
|
-
accountKey: account.canonicalKey,
|
|
101
|
-
branch: 0,
|
|
102
|
-
index: 0,
|
|
103
|
-
});
|
|
104
|
-
// receive.address, receive.scriptPubKey; no keyring or provider required.
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
The canonical account identity is the tuple `(network, policy, canonicalKey)`.
|
|
108
|
-
`policy` is `bip84-p2wpkh`; `canonicalKey` normalizes xpub/zpub aliases to zpub.
|
|
109
|
-
`accountIndex` is the encoded hardened child number minus 2^31. Key serialization
|
|
110
|
-
and depth cannot prove the original purpose, coin type, full ancestry or ownership.
|
|
111
|
-
In particular, the same public key can be encoded for either supported network;
|
|
112
|
-
network selection changes the address encoding and identity, not the derived
|
|
113
|
-
witness program. Require the user to verify their source wallet's BIP84 account
|
|
114
|
-
and network, and compare a known receive address before using a watch account.
|
|
115
|
-
|
|
116
|
-
Calls are synchronous and stateless: one key of at most 112 Base58 characters,
|
|
117
|
-
one account parse and two requested child derivations per address; no range scan,
|
|
118
|
-
cache, fetch, storage, RNG or wallet signing. The upstream BIP32 factory runs
|
|
119
|
-
deterministic ECC known-vector self-tests at module initialization (including
|
|
120
|
-
fixed-fixture signatures); it never receives a wallet private key here. The
|
|
121
|
-
underlying BIP32 implementation can retry an invalid child internally; a returned index mismatch is rejected instead
|
|
122
|
-
of silently changing the requested path. There is no wall-clock guarantee for
|
|
123
|
-
pathological library retries. Successful outputs are frozen objects containing
|
|
124
|
-
only strings and numbers (including a frozen nested account), never a BIP32 node.
|
|
125
|
-
Invalid input throws `PublicBip84Error` with a constant `INVALID_INPUT`,
|
|
126
|
-
`INVALID_ACCOUNT` or `INVALID_DERIVATION` code and no echoed key.
|
|
127
|
-
|
|
128
|
-
An account public key reveals all nonhardened receive and change addresses and
|
|
129
|
-
allows their activity to be linked. It cannot spend funds on its own, but remains
|
|
130
|
-
privacy-sensitive. The API performs no discovery or history lookup. A consuming
|
|
131
|
-
wallet must obtain informed consent before sharing an account key or derived
|
|
132
|
-
addresses with an indexer, own explicit discovery/page/concurrency bounds, and
|
|
133
|
-
label partial or unavailable history honestly. This library slice does not
|
|
134
|
-
implement or qualify a complete mobile watch-account feature.
|
|
135
|
-
|
|
136
|
-
### Development BIP84 native-transfer foundation
|
|
137
|
-
|
|
138
|
-
`SoftwareKeyring.deriveBip84HdPublicAccount(request, { assertCurrent })` derives
|
|
139
|
-
an explicit HD index for a captured Bitcoin/Syscoin mainnet context and returns
|
|
140
|
-
only frozen public account and receive-address data. It requires an already
|
|
141
|
-
unlocked software host; it does not select accounts, update a catalogue, store an
|
|
142
|
-
xprv, discover addresses or contact a provider. The host must supply a synchronous
|
|
143
|
-
revision/consent guard and recheck it after awaiting the operation. Labels and
|
|
144
|
-
currency strings do not choose the derivation path.
|
|
145
|
-
|
|
146
|
-
The standalone `@sidhujag/sysweb3-keyring/cjs/bip84-native` entry exports
|
|
147
|
-
`prepareBip84NativeTransaction` and its types. It builds exact unsigned version-2
|
|
148
|
-
bytes from a bounded immutable plan: one P2WPKH recipient, optional verified
|
|
149
|
-
branch-1 change, explicit RBF, locktime zero, full previous transaction data and
|
|
150
|
-
integer fee limits. Parent transactions must be ordinary version 1/2 and
|
|
151
|
-
non-coinbase. All SYS special/asset parents are excluded even when a selected
|
|
152
|
-
output appears to be native change. Missing provider asset metadata is not proof
|
|
153
|
-
that an output is safe to spend.
|
|
154
|
-
|
|
155
|
-
The planner allows at most 64 inputs/parents, 1,000,000 bytes per parent and
|
|
156
|
-
2,000,000 aggregate parent bytes. Before decoding any parent, it also enforces
|
|
157
|
-
an aggregate budget of 8,192 decoded components: parent inputs, outputs, witness
|
|
158
|
-
vectors and witness items each consume one component, including empty items.
|
|
159
|
-
This is a wallet resource policy, not a consensus limit; large scripts remain
|
|
160
|
-
subject to the separate byte limits. Wallet policy additionally caps absolute fees
|
|
161
|
-
at 10,000,000 satoshis and fee rate at 1,000 sat/vB; callers must provide limits
|
|
162
|
-
no higher than those ceilings. Maximum signature size is used only to reject
|
|
163
|
-
fees that cannot possibly satisfy the rate ceiling; the prepared signer checks
|
|
164
|
-
that ceiling again using the actual finalized virtual size. Zero fee is arithmetic-valid, not a relay guarantee.
|
|
165
|
-
Oversized valid parents are unavailable to this initial planner; no data is
|
|
166
|
-
truncated or silently omitted. Returned bytes/data are public and privacy-sensitive.
|
|
167
|
-
|
|
168
|
-
This is a development foundation, **not a native UTXO sending capability**.
|
|
169
|
-
`SoftwareKeyring.signPreparedBip84Transaction(request, { assertCurrent })` (added in 2.1.0)
|
|
170
|
-
signs only the selected HD account's exact prepared plan. It requires the SDK
|
|
171
|
-
selected type/index, requested account and seed-derived canonical public key to
|
|
172
|
-
agree. The mandatory synchronous host guard additionally binds fresh approval,
|
|
173
|
-
monotonic revision and review expiry. It rebuilds the plan, verifies complete
|
|
174
|
-
low-S SIGHASH_ALL signatures and exact unsigned bytes, and checks the final fee
|
|
175
|
-
against actual virtual size. It performs no unlock, storage, discovery or
|
|
176
|
-
broadcast and returns only frozen signed bytes, identifiers and fee/size data.
|
|
177
|
-
It does not consume or create per-account encrypted xprvs. The host still owns
|
|
178
|
-
canonical-chain/unspent checks, confirmed-input eligibility, protected collateral
|
|
179
|
-
and pending outpoint reservations, change-index persistence, fresh authentication,
|
|
180
|
-
review cancellation and eventual journal-before-broadcast behavior. Full parent
|
|
181
|
-
bytes prove an outpoint's content, not chain membership, maturity or spendability.
|
|
182
|
-
Existing generic PSBT, EVM and hardware APIs are unchanged. Native and live
|
|
183
|
-
qualification remain future work.
|
|
184
|
-
|
|
185
77
|
### Account Management
|
|
186
78
|
|
|
187
79
|
```javascript
|
|
@@ -467,3 +359,49 @@ Signatures are checked against the expected account; UTXO signatures must also
|
|
|
467
359
|
match the approved PSBT and its requested sighash coverage. The custom UTXO host
|
|
468
360
|
supports the existing Syscoin and Bitcoin app protocols. Physical-device and
|
|
469
361
|
firmware qualification remain separate from source and mocked-device tests.
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
## Shared standard EVM fees
|
|
365
|
+
|
|
366
|
+
`cjs/evm-fees` is a dependency-free read-only entry. Both the existing
|
|
367
|
+
`EthereumTransactions.getFeeDataWithDynamicMaxPriorityFeePerGas` method and
|
|
368
|
+
restricted hosts use the same calculation:
|
|
369
|
+
|
|
370
|
+
```ts
|
|
371
|
+
import { getEvmFeeData } from '@sidhujag/sysweb3-keyring/cjs/evm-fees';
|
|
372
|
+
|
|
373
|
+
const fees = await getEvmFeeData(readOnlyProvider, {
|
|
374
|
+
signal,
|
|
375
|
+
assertCurrent: () => assertSameAccountAndNetwork(),
|
|
376
|
+
});
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
The reader supplies only `getGasPrice()`, `getBlock('latest')`, and
|
|
380
|
+
`send('eth_maxPriorityFeePerGas' | 'eth_feeHistory', params)`. It must validate
|
|
381
|
+
its RPC responses and bind its endpoint/chain; this helper does not instantiate
|
|
382
|
+
a provider, estimate gas, select an account, sign or broadcast. The host must
|
|
383
|
+
retain request deadlines and perform its ordinary account/network/session
|
|
384
|
+
checks before signing.
|
|
385
|
+
|
|
386
|
+
Results are frozen bigint fields: `gasPrice`, `maxFeePerGas`, and
|
|
387
|
+
`maxPriorityFeePerGas`, with `baseFeePerGas` only when the observed header has
|
|
388
|
+
that field. An absent base fee produces the existing legacy zero sentinels for
|
|
389
|
+
the two EIP-1559 fields. A zero base fee or zero tip remains valid EIP-1559 data.
|
|
390
|
+
An explicitly unsupported priority method may use actual recent fee-history
|
|
391
|
+
rewards; other failures never turn into fallback fees. Quantities and calculated
|
|
392
|
+
fees are bounded to uint256, history to the requested five blocks, and no
|
|
393
|
+
signing authority or dependencies are loaded by this entry.
|
|
394
|
+
|
|
395
|
+
The optional `minPriorityFee` and whole-percent `feeMultiplier` preserve the
|
|
396
|
+
existing configured recommendation policy (default multiplier 250). Options
|
|
397
|
+
are snapshotted before asynchronous reads. The synchronous `assertCurrent`
|
|
398
|
+
callback must return `undefined`; an async callback is rejected. Cancellation
|
|
399
|
+
rejects pending discovery without permitting later results to produce a quote.
|
|
400
|
+
|
|
401
|
+
`bufferedEvmGasLimit(estimate: bigint, minimum?: bigint)` shares the existing
|
|
402
|
+
successful gas estimate policy used by `EthereumTransactions.getTxGasLimit`:
|
|
403
|
+
floor the estimate times120/100 and apply the configured minimum if larger.
|
|
404
|
+
It includes ordinary native transfers. The helper performs no estimation,
|
|
405
|
+
fallback request, transaction cap selection or broadcasting; callers enforce
|
|
406
|
+
the selected network's limits after applying it. The SDK's existing estimation
|
|
407
|
+
failure/fallback behavior is unchanged.
|
package/cjs/evm-fees.js
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EvmGasLimitError = void 0;
|
|
4
|
+
exports.assertEvmGasLimit = assertEvmGasLimit;
|
|
5
|
+
exports.parseEvmFeeQuantity = parseEvmFeeQuantity;
|
|
6
|
+
exports.bufferedEvmGasLimit = bufferedEvmGasLimit;
|
|
7
|
+
exports.getEvmFeeData = getEvmFeeData;
|
|
8
|
+
/** Standard EVM fee discovery shared by extension and restricted native hosts. */
|
|
9
|
+
const evm_js_1 = require("@sidhujag/sysweb3-network/cjs/evm.js");
|
|
10
|
+
const MAX_FEE = (1n << 256n) - 1n;
|
|
11
|
+
/** A validated limit failed its wire bounds or an activated protocol bound. */
|
|
12
|
+
class EvmGasLimitError extends Error {
|
|
13
|
+
constructor(code) {
|
|
14
|
+
super(code === 'SYSWEB3_EVM_GAS_LIMIT_INVALID'
|
|
15
|
+
? 'Invalid EVM gas limit'
|
|
16
|
+
: 'EVM gas limit exceeds the network limit');
|
|
17
|
+
this.code = code;
|
|
18
|
+
this.name = 'EvmGasLimitError';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.EvmGasLimitError = EvmGasLimitError;
|
|
22
|
+
/** The host supplies a verified chain and, if sampled, its block gas limit. */
|
|
23
|
+
function assertEvmGasLimit(gasLimit, chainId, sampledBlockGasLimit) {
|
|
24
|
+
if (typeof gasLimit !== 'bigint' ||
|
|
25
|
+
gasLimit <= 0n ||
|
|
26
|
+
gasLimit > MAX_FEE ||
|
|
27
|
+
typeof chainId !== 'bigint' ||
|
|
28
|
+
chainId < 0n ||
|
|
29
|
+
chainId > MAX_FEE ||
|
|
30
|
+
(sampledBlockGasLimit !== undefined &&
|
|
31
|
+
(typeof sampledBlockGasLimit !== 'bigint' ||
|
|
32
|
+
sampledBlockGasLimit <= 0n ||
|
|
33
|
+
sampledBlockGasLimit > MAX_FEE)))
|
|
34
|
+
throw new EvmGasLimitError('SYSWEB3_EVM_GAS_LIMIT_INVALID');
|
|
35
|
+
const { maxTransactionGas } = (0, evm_js_1.getEvmProtocolLimits)(chainId);
|
|
36
|
+
if ((maxTransactionGas !== undefined && gasLimit > BigInt(maxTransactionGas)) ||
|
|
37
|
+
(sampledBlockGasLimit !== undefined && gasLimit > sampledBlockGasLimit))
|
|
38
|
+
throw new EvmGasLimitError('SYSWEB3_EVM_GAS_LIMIT_EXCEEDED');
|
|
39
|
+
return gasLimit;
|
|
40
|
+
}
|
|
41
|
+
/** Accept the SDK's existing BigNumberish forms without permissive zero coercion. */
|
|
42
|
+
function parseEvmFeeQuantity(value, label = 'fee quantity') {
|
|
43
|
+
if (value !== null && typeof value === 'object') {
|
|
44
|
+
const object = value;
|
|
45
|
+
value =
|
|
46
|
+
object._hex ??
|
|
47
|
+
object.hex ??
|
|
48
|
+
(typeof object.toString === 'function' ? object.toString() : undefined);
|
|
49
|
+
if (typeof value !== 'string')
|
|
50
|
+
throw new Error(`Invalid ${label}`);
|
|
51
|
+
}
|
|
52
|
+
if (!((typeof value === 'string' &&
|
|
53
|
+
value.length <= 80 &&
|
|
54
|
+
/^(?:0x[\da-f]+|\d+)$/i.test(value)) ||
|
|
55
|
+
(typeof value === 'number' &&
|
|
56
|
+
Number.isSafeInteger(value) &&
|
|
57
|
+
value >= 0) ||
|
|
58
|
+
(typeof value === 'bigint' && value >= 0n)))
|
|
59
|
+
throw new Error(`Invalid ${label}`);
|
|
60
|
+
const quantity = BigInt(value);
|
|
61
|
+
if (quantity > MAX_FEE)
|
|
62
|
+
throw new Error(`Invalid ${label}`);
|
|
63
|
+
return quantity;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* The existing successful-estimate policy: floor(estimate * 120 / 100), then
|
|
67
|
+
* the configured minimum if larger. Callers retain chain/resource bounds.
|
|
68
|
+
*/
|
|
69
|
+
function bufferedEvmGasLimit(estimate, minimum) {
|
|
70
|
+
if (typeof estimate !== 'bigint' ||
|
|
71
|
+
estimate < 0n ||
|
|
72
|
+
(minimum !== undefined && typeof minimum !== 'bigint'))
|
|
73
|
+
throw new Error('Invalid gas estimate');
|
|
74
|
+
const buffered = (estimate * 120n) / 100n;
|
|
75
|
+
return minimum !== undefined && minimum > buffered ? minimum : buffered;
|
|
76
|
+
}
|
|
77
|
+
function unsupportedPriorityMethod(error) {
|
|
78
|
+
const unsupportedCode = (code) => code === -32601 || code === 4200;
|
|
79
|
+
if (unsupportedCode(error?.code))
|
|
80
|
+
return true;
|
|
81
|
+
if (!['UNKNOWN_ERROR', 'UNSUPPORTED_OPERATION'].includes(error?.code))
|
|
82
|
+
return false;
|
|
83
|
+
if (error?.operation != null &&
|
|
84
|
+
error.operation !== 'eth_maxPriorityFeePerGas')
|
|
85
|
+
return false;
|
|
86
|
+
return [
|
|
87
|
+
{ cause: error.error, payload: error.payload },
|
|
88
|
+
{ cause: error.info?.error, payload: error.info?.payload },
|
|
89
|
+
].some(({ cause, payload }) => cause?.name !== 'AbortError' &&
|
|
90
|
+
unsupportedCode(cause?.code) &&
|
|
91
|
+
payload?.method === 'eth_maxPriorityFeePerGas' &&
|
|
92
|
+
Array.isArray(payload.params) &&
|
|
93
|
+
payload.params.length === 0);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* No signer, transport, network registry or provider implementation is imported.
|
|
97
|
+
* Reads are serialized and guarded; RPC failures never become fabricated fees.
|
|
98
|
+
*/
|
|
99
|
+
async function getEvmFeeData(reader, options = {}) {
|
|
100
|
+
const signals = [options.signal, reader.signal].filter((signal) => signal !== undefined);
|
|
101
|
+
const assertCurrent = options.assertCurrent;
|
|
102
|
+
const check = () => {
|
|
103
|
+
if (signals.some((signal) => signal.aborted)) {
|
|
104
|
+
const error = new Error('EVM fee discovery aborted');
|
|
105
|
+
error.name = 'AbortError';
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
if (assertCurrent) {
|
|
109
|
+
const result = assertCurrent();
|
|
110
|
+
if (result !== undefined) {
|
|
111
|
+
// A void callback type also accepts async functions. Never await one.
|
|
112
|
+
void Promise.resolve(result).catch(() => undefined);
|
|
113
|
+
throw new Error('EVM fee guard must be synchronous');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (signals.some((signal) => signal.aborted)) {
|
|
117
|
+
const error = new Error('EVM fee discovery aborted');
|
|
118
|
+
error.name = 'AbortError';
|
|
119
|
+
throw error;
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
check();
|
|
123
|
+
const minPriorityFee = options.minPriorityFee == null
|
|
124
|
+
? undefined
|
|
125
|
+
: parseEvmFeeQuantity(options.minPriorityFee, 'minimum priority fee');
|
|
126
|
+
// Retain the existing zero/absent override behavior.
|
|
127
|
+
const multiplier = options.feeMultiplier || 250;
|
|
128
|
+
if (!Number.isSafeInteger(multiplier) || multiplier < 1)
|
|
129
|
+
throw new Error('Invalid fee multiplier');
|
|
130
|
+
const getGasPrice = reader.getGasPrice.bind(reader);
|
|
131
|
+
const getBlock = reader.getBlock.bind(reader);
|
|
132
|
+
const send = reader.send.bind(reader);
|
|
133
|
+
const read = async (operation) => {
|
|
134
|
+
check();
|
|
135
|
+
let cleanup = () => undefined;
|
|
136
|
+
try {
|
|
137
|
+
const interrupted = new Promise((_, reject) => {
|
|
138
|
+
const abort = () => {
|
|
139
|
+
const error = new Error('EVM fee discovery aborted');
|
|
140
|
+
error.name = 'AbortError';
|
|
141
|
+
reject(error);
|
|
142
|
+
};
|
|
143
|
+
signals.forEach((signal) => signal.addEventListener('abort', abort, { once: true }));
|
|
144
|
+
cleanup = () => {
|
|
145
|
+
signals.forEach((signal) => signal.removeEventListener('abort', abort));
|
|
146
|
+
return undefined;
|
|
147
|
+
};
|
|
148
|
+
});
|
|
149
|
+
// No asynchronous gap between the current-owner check and dispatch.
|
|
150
|
+
const result = await Promise.race([operation(), interrupted]);
|
|
151
|
+
check();
|
|
152
|
+
return result;
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
check();
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
158
|
+
finally {
|
|
159
|
+
cleanup();
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
const gasPrice = parseEvmFeeQuantity(await read(getGasPrice), 'gas price');
|
|
163
|
+
const block = await read(() => getBlock('latest'));
|
|
164
|
+
if (!block)
|
|
165
|
+
throw new Error('Block not found');
|
|
166
|
+
if (typeof block !== 'object' || Array.isArray(block))
|
|
167
|
+
throw new Error('Invalid block');
|
|
168
|
+
const rawBaseFee = block.baseFeePerGas;
|
|
169
|
+
if (rawBaseFee == null) {
|
|
170
|
+
check();
|
|
171
|
+
return Object.freeze({
|
|
172
|
+
gasPrice,
|
|
173
|
+
maxFeePerGas: 0n,
|
|
174
|
+
maxPriorityFeePerGas: 0n,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
const baseFeePerGas = parseEvmFeeQuantity(rawBaseFee, 'base fee');
|
|
178
|
+
let maxPriorityFeePerGas;
|
|
179
|
+
try {
|
|
180
|
+
maxPriorityFeePerGas = parseEvmFeeQuantity(await read(() => send('eth_maxPriorityFeePerGas', [])), 'priority fee');
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
check();
|
|
184
|
+
if (error?.code === 'SYSWEB3_RPC_RESPONSE_INVALID' ||
|
|
185
|
+
error?.name === 'AbortError' ||
|
|
186
|
+
!unsupportedPriorityMethod(error))
|
|
187
|
+
throw error;
|
|
188
|
+
const history = await read(() => send('eth_feeHistory', ['0x5', 'latest', [25, 50, 75]]));
|
|
189
|
+
const rewards = history?.reward;
|
|
190
|
+
if (!Array.isArray(rewards) || rewards.length < 1 || rewards.length > 5)
|
|
191
|
+
throw new Error('Priority fee history unavailable');
|
|
192
|
+
const recentFees = rewards
|
|
193
|
+
.map((reward) => {
|
|
194
|
+
if (!Array.isArray(reward) || reward.length !== 3)
|
|
195
|
+
throw new Error('Invalid priority fee history');
|
|
196
|
+
const parsed = reward.map((value) => parseEvmFeeQuantity(value, 'priority fee history'));
|
|
197
|
+
return parsed[1];
|
|
198
|
+
})
|
|
199
|
+
.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
|
|
200
|
+
maxPriorityFeePerGas =
|
|
201
|
+
(recentFees[Math.floor(recentFees.length / 2)] * 150n) / 100n;
|
|
202
|
+
}
|
|
203
|
+
if (minPriorityFee !== undefined && maxPriorityFeePerGas < minPriorityFee)
|
|
204
|
+
maxPriorityFeePerGas = minPriorityFee;
|
|
205
|
+
const baseline = (gasPrice * 120n) / 100n;
|
|
206
|
+
const calculated = (baseFeePerGas * BigInt(multiplier)) / 100n + maxPriorityFeePerGas;
|
|
207
|
+
let maxFeePerGas = calculated > baseline ? calculated : baseline;
|
|
208
|
+
const minimum = (maxPriorityFeePerGas * 120n) / 100n;
|
|
209
|
+
if (maxFeePerGas < minimum)
|
|
210
|
+
maxFeePerGas = minimum;
|
|
211
|
+
if (maxFeePerGas === 0n)
|
|
212
|
+
throw new Error('Invalid EIP-1559 maximum fee');
|
|
213
|
+
parseEvmFeeQuantity(maxFeePerGas, 'maximum fee');
|
|
214
|
+
parseEvmFeeQuantity(maxPriorityFeePerGas, 'priority fee');
|
|
215
|
+
check();
|
|
216
|
+
return Object.freeze({
|
|
217
|
+
gasPrice,
|
|
218
|
+
baseFeePerGas,
|
|
219
|
+
maxFeePerGas,
|
|
220
|
+
maxPriorityFeePerGas,
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=evm-fees.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evm-fees.js","sourceRoot":"","sources":["../../src/evm-fees.ts"],"names":[],"mappings":"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"}
|