@getomnichain/omnichain 0.2.0
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/LICENSE +21 -0
- package/README.md +66 -0
- package/dist/abstract_gas_pricing.d.ts +31 -0
- package/dist/abstract_gas_pricing.d.ts.map +1 -0
- package/dist/abstract_gas_pricing.js +22 -0
- package/dist/abstract_gas_pricing.js.map +1 -0
- package/dist/address.d.ts +10 -0
- package/dist/address.d.ts.map +1 -0
- package/dist/address.factory.d.ts +26 -0
- package/dist/address.factory.d.ts.map +1 -0
- package/dist/address.factory.js +75 -0
- package/dist/address.factory.js.map +1 -0
- package/dist/address.js +13 -0
- package/dist/address.js.map +1 -0
- package/dist/address_field.decorator.d.ts +17 -0
- package/dist/address_field.decorator.d.ts.map +1 -0
- package/dist/address_field.decorator.js +34 -0
- package/dist/address_field.decorator.js.map +1 -0
- package/dist/chain.base.d.ts +79 -0
- package/dist/chain.base.d.ts.map +1 -0
- package/dist/chain.base.js +113 -0
- package/dist/chain.base.js.map +1 -0
- package/dist/chain_ids.d.ts +122 -0
- package/dist/chain_ids.d.ts.map +1 -0
- package/dist/chain_ids.js +193 -0
- package/dist/chain_ids.js.map +1 -0
- package/dist/errors.d.ts +42 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +62 -0
- package/dist/errors.js.map +1 -0
- package/dist/evm/evm_address.d.ts +11 -0
- package/dist/evm/evm_address.d.ts.map +1 -0
- package/dist/evm/evm_address.js +56 -0
- package/dist/evm/evm_address.js.map +1 -0
- package/dist/evm/evm_chain.d.ts +123 -0
- package/dist/evm/evm_chain.d.ts.map +1 -0
- package/dist/evm/evm_chain.js +685 -0
- package/dist/evm/evm_chain.js.map +1 -0
- package/dist/evm/evm_chains.d.ts +83 -0
- package/dist/evm/evm_chains.d.ts.map +1 -0
- package/dist/evm/evm_chains.js +493 -0
- package/dist/evm/evm_chains.js.map +1 -0
- package/dist/evm/evm_gas_estimate.d.ts +45 -0
- package/dist/evm/evm_gas_estimate.d.ts.map +1 -0
- package/dist/evm/evm_gas_estimate.js +70 -0
- package/dist/evm/evm_gas_estimate.js.map +1 -0
- package/dist/evm/evm_gas_pricing.d.ts +40 -0
- package/dist/evm/evm_gas_pricing.d.ts.map +1 -0
- package/dist/evm/evm_gas_pricing.js +56 -0
- package/dist/evm/evm_gas_pricing.js.map +1 -0
- package/dist/evm/evm_token.d.ts +7 -0
- package/dist/evm/evm_token.d.ts.map +1 -0
- package/dist/evm/evm_token.js +22 -0
- package/dist/evm/evm_token.js.map +1 -0
- package/dist/evm/evm_tokens.d.ts +81 -0
- package/dist/evm/evm_tokens.d.ts.map +1 -0
- package/dist/evm/evm_tokens.js +104 -0
- package/dist/evm/evm_tokens.js.map +1 -0
- package/dist/evm/evm_transaction_status.d.ts +108 -0
- package/dist/evm/evm_transaction_status.d.ts.map +1 -0
- package/dist/evm/evm_transaction_status.js +177 -0
- package/dist/evm/evm_transaction_status.js.map +1 -0
- package/dist/evm/index.d.ts +10 -0
- package/dist/evm/index.d.ts.map +1 -0
- package/dist/evm/index.js +10 -0
- package/dist/evm/index.js.map +1 -0
- package/dist/evm/unsigned_evm_transaction.d.ts +19 -0
- package/dist/evm/unsigned_evm_transaction.d.ts.map +1 -0
- package/dist/evm/unsigned_evm_transaction.js +18 -0
- package/dist/evm/unsigned_evm_transaction.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/is_address.decorator.d.ts +3 -0
- package/dist/is_address.decorator.d.ts.map +1 -0
- package/dist/is_address.decorator.js +51 -0
- package/dist/is_address.decorator.js.map +1 -0
- package/dist/network_type.d.ts +73 -0
- package/dist/network_type.d.ts.map +1 -0
- package/dist/network_type.js +144 -0
- package/dist/network_type.js.map +1 -0
- package/dist/priority.d.ts +23 -0
- package/dist/priority.d.ts.map +1 -0
- package/dist/priority.js +23 -0
- package/dist/priority.js.map +1 -0
- package/dist/solana/index.d.ts +9 -0
- package/dist/solana/index.d.ts.map +1 -0
- package/dist/solana/index.js +9 -0
- package/dist/solana/index.js.map +1 -0
- package/dist/solana/solana_address.d.ts +20 -0
- package/dist/solana/solana_address.d.ts.map +1 -0
- package/dist/solana/solana_address.js +45 -0
- package/dist/solana/solana_address.js.map +1 -0
- package/dist/solana/solana_chain.d.ts +213 -0
- package/dist/solana/solana_chain.d.ts.map +1 -0
- package/dist/solana/solana_chain.js +704 -0
- package/dist/solana/solana_chain.js.map +1 -0
- package/dist/solana/solana_chains.d.ts +24 -0
- package/dist/solana/solana_chains.d.ts.map +1 -0
- package/dist/solana/solana_chains.js +84 -0
- package/dist/solana/solana_chains.js.map +1 -0
- package/dist/solana/solana_gas_pricing.d.ts +30 -0
- package/dist/solana/solana_gas_pricing.d.ts.map +1 -0
- package/dist/solana/solana_gas_pricing.js +26 -0
- package/dist/solana/solana_gas_pricing.js.map +1 -0
- package/dist/solana/solana_token.d.ts +19 -0
- package/dist/solana/solana_token.d.ts.map +1 -0
- package/dist/solana/solana_token.js +34 -0
- package/dist/solana/solana_token.js.map +1 -0
- package/dist/solana/solana_tokens.d.ts +22 -0
- package/dist/solana/solana_tokens.d.ts.map +1 -0
- package/dist/solana/solana_tokens.js +26 -0
- package/dist/solana/solana_tokens.js.map +1 -0
- package/dist/solana/solana_transaction_status.d.ts +59 -0
- package/dist/solana/solana_transaction_status.d.ts.map +1 -0
- package/dist/solana/solana_transaction_status.js +144 -0
- package/dist/solana/solana_transaction_status.js.map +1 -0
- package/dist/solana/unsigned_solana_transaction.d.ts +31 -0
- package/dist/solana/unsigned_solana_transaction.d.ts.map +1 -0
- package/dist/solana/unsigned_solana_transaction.js +26 -0
- package/dist/solana/unsigned_solana_transaction.js.map +1 -0
- package/dist/token.d.ts +35 -0
- package/dist/token.d.ts.map +1 -0
- package/dist/token.js +62 -0
- package/dist/token.js.map +1 -0
- package/dist/ton/index.d.ts +2 -0
- package/dist/ton/index.d.ts.map +1 -0
- package/dist/ton/index.js +2 -0
- package/dist/ton/index.js.map +1 -0
- package/dist/ton/ton_address.d.ts +10 -0
- package/dist/ton/ton_address.d.ts.map +1 -0
- package/dist/ton/ton_address.js +53 -0
- package/dist/ton/ton_address.js.map +1 -0
- package/dist/transaction_status.d.ts +140 -0
- package/dist/transaction_status.d.ts.map +1 -0
- package/dist/transaction_status.js +271 -0
- package/dist/transaction_status.js.map +1 -0
- package/dist/unsigned_transaction.d.ts +7 -0
- package/dist/unsigned_transaction.d.ts.map +1 -0
- package/dist/unsigned_transaction.js +9 -0
- package/dist/unsigned_transaction.js.map +1 -0
- package/dist/utxo/btc/btc_address.d.ts +15 -0
- package/dist/utxo/btc/btc_address.d.ts.map +1 -0
- package/dist/utxo/btc/btc_address.js +39 -0
- package/dist/utxo/btc/btc_address.js.map +1 -0
- package/dist/utxo/btc/btc_chain.d.ts +34 -0
- package/dist/utxo/btc/btc_chain.d.ts.map +1 -0
- package/dist/utxo/btc/btc_chain.js +62 -0
- package/dist/utxo/btc/btc_chain.js.map +1 -0
- package/dist/utxo/btc/btc_chains.d.ts +25 -0
- package/dist/utxo/btc/btc_chains.d.ts.map +1 -0
- package/dist/utxo/btc/btc_chains.js +43 -0
- package/dist/utxo/btc/btc_chains.js.map +1 -0
- package/dist/utxo/btc/btc_token.d.ts +6 -0
- package/dist/utxo/btc/btc_token.d.ts.map +1 -0
- package/dist/utxo/btc/btc_token.js +11 -0
- package/dist/utxo/btc/btc_token.js.map +1 -0
- package/dist/utxo/btc/index.d.ts +14 -0
- package/dist/utxo/btc/index.d.ts.map +1 -0
- package/dist/utxo/btc/index.js +14 -0
- package/dist/utxo/btc/index.js.map +1 -0
- package/dist/utxo/btc/network_params.d.ts +50 -0
- package/dist/utxo/btc/network_params.d.ts.map +1 -0
- package/dist/utxo/btc/network_params.js +188 -0
- package/dist/utxo/btc/network_params.js.map +1 -0
- package/dist/utxo/btc/tools/asset_outpoint.d.ts +7 -0
- package/dist/utxo/btc/tools/asset_outpoint.d.ts.map +1 -0
- package/dist/utxo/btc/tools/asset_outpoint.js +12 -0
- package/dist/utxo/btc/tools/asset_outpoint.js.map +1 -0
- package/dist/utxo/btc/tools/bitcoin_core.tool.d.ts +41 -0
- package/dist/utxo/btc/tools/bitcoin_core.tool.d.ts.map +1 -0
- package/dist/utxo/btc/tools/bitcoin_core.tool.js +172 -0
- package/dist/utxo/btc/tools/bitcoin_core.tool.js.map +1 -0
- package/dist/utxo/btc/tools/esplora.tool.d.ts +27 -0
- package/dist/utxo/btc/tools/esplora.tool.d.ts.map +1 -0
- package/dist/utxo/btc/tools/esplora.tool.js +113 -0
- package/dist/utxo/btc/tools/esplora.tool.js.map +1 -0
- package/dist/utxo/btc/tools/inscription_index.d.ts +6 -0
- package/dist/utxo/btc/tools/inscription_index.d.ts.map +1 -0
- package/dist/utxo/btc/tools/inscription_index.js +2 -0
- package/dist/utxo/btc/tools/inscription_index.js.map +1 -0
- package/dist/utxo/btc/tools/ordiscan.tool.d.ts +19 -0
- package/dist/utxo/btc/tools/ordiscan.tool.d.ts.map +1 -0
- package/dist/utxo/btc/tools/ordiscan.tool.js +53 -0
- package/dist/utxo/btc/tools/ordiscan.tool.js.map +1 -0
- package/dist/utxo/btc/tools/rare_sat_index.d.ts +6 -0
- package/dist/utxo/btc/tools/rare_sat_index.d.ts.map +1 -0
- package/dist/utxo/btc/tools/rare_sat_index.js +2 -0
- package/dist/utxo/btc/tools/rare_sat_index.js.map +1 -0
- package/dist/utxo/btc/tools/rune_index.d.ts +6 -0
- package/dist/utxo/btc/tools/rune_index.d.ts.map +1 -0
- package/dist/utxo/btc/tools/rune_index.js +2 -0
- package/dist/utxo/btc/tools/rune_index.js.map +1 -0
- package/dist/utxo/btc/tools/unisat.tool.d.ts +18 -0
- package/dist/utxo/btc/tools/unisat.tool.d.ts.map +1 -0
- package/dist/utxo/btc/tools/unisat.tool.js +49 -0
- package/dist/utxo/btc/tools/unisat.tool.js.map +1 -0
- package/dist/utxo/coin_selection.d.ts +29 -0
- package/dist/utxo/coin_selection.d.ts.map +1 -0
- package/dist/utxo/coin_selection.js +156 -0
- package/dist/utxo/coin_selection.js.map +1 -0
- package/dist/utxo/doge/doge_chains.d.ts +17 -0
- package/dist/utxo/doge/doge_chains.d.ts.map +1 -0
- package/dist/utxo/doge/doge_chains.js +28 -0
- package/dist/utxo/doge/doge_chains.js.map +1 -0
- package/dist/utxo/doge/index.d.ts +3 -0
- package/dist/utxo/doge/index.d.ts.map +1 -0
- package/dist/utxo/doge/index.js +3 -0
- package/dist/utxo/doge/index.js.map +1 -0
- package/dist/utxo/doge/network_params.d.ts +4 -0
- package/dist/utxo/doge/network_params.d.ts.map +1 -0
- package/dist/utxo/doge/network_params.js +24 -0
- package/dist/utxo/doge/network_params.js.map +1 -0
- package/dist/utxo/ecc.d.ts +2 -0
- package/dist/utxo/ecc.d.ts.map +1 -0
- package/dist/utxo/ecc.js +11 -0
- package/dist/utxo/ecc.js.map +1 -0
- package/dist/utxo/fee.d.ts +12 -0
- package/dist/utxo/fee.d.ts.map +1 -0
- package/dist/utxo/fee.js +51 -0
- package/dist/utxo/fee.js.map +1 -0
- package/dist/utxo/index.d.ts +20 -0
- package/dist/utxo/index.d.ts.map +1 -0
- package/dist/utxo/index.js +20 -0
- package/dist/utxo/index.js.map +1 -0
- package/dist/utxo/ltc/index.d.ts +3 -0
- package/dist/utxo/ltc/index.d.ts.map +1 -0
- package/dist/utxo/ltc/index.js +3 -0
- package/dist/utxo/ltc/index.js.map +1 -0
- package/dist/utxo/ltc/ltc_chains.d.ts +17 -0
- package/dist/utxo/ltc/ltc_chains.d.ts.map +1 -0
- package/dist/utxo/ltc/ltc_chains.js +28 -0
- package/dist/utxo/ltc/ltc_chains.js.map +1 -0
- package/dist/utxo/ltc/network_params.d.ts +4 -0
- package/dist/utxo/ltc/network_params.d.ts.map +1 -0
- package/dist/utxo/ltc/network_params.js +27 -0
- package/dist/utxo/ltc/network_params.js.map +1 -0
- package/dist/utxo/script.d.ts +16 -0
- package/dist/utxo/script.d.ts.map +1 -0
- package/dist/utxo/script.js +52 -0
- package/dist/utxo/script.js.map +1 -0
- package/dist/utxo/tools/broadcaster.d.ts +6 -0
- package/dist/utxo/tools/broadcaster.d.ts.map +1 -0
- package/dist/utxo/tools/broadcaster.js +2 -0
- package/dist/utxo/tools/broadcaster.js.map +1 -0
- package/dist/utxo/tools/chain_tip_provider.d.ts +5 -0
- package/dist/utxo/tools/chain_tip_provider.d.ts.map +1 -0
- package/dist/utxo/tools/chain_tip_provider.js +2 -0
- package/dist/utxo/tools/chain_tip_provider.js.map +1 -0
- package/dist/utxo/tools/fee_estimator.d.ts +6 -0
- package/dist/utxo/tools/fee_estimator.d.ts.map +1 -0
- package/dist/utxo/tools/fee_estimator.js +2 -0
- package/dist/utxo/tools/fee_estimator.js.map +1 -0
- package/dist/utxo/tools/raw_transaction_provider.d.ts +8 -0
- package/dist/utxo/tools/raw_transaction_provider.d.ts.map +1 -0
- package/dist/utxo/tools/raw_transaction_provider.js +2 -0
- package/dist/utxo/tools/raw_transaction_provider.js.map +1 -0
- package/dist/utxo/tools/utxo_provider.d.ts +7 -0
- package/dist/utxo/tools/utxo_provider.d.ts.map +1 -0
- package/dist/utxo/tools/utxo_provider.js +2 -0
- package/dist/utxo/tools/utxo_provider.js.map +1 -0
- package/dist/utxo/unsigned_utxo_transaction.d.ts +32 -0
- package/dist/utxo/unsigned_utxo_transaction.d.ts.map +1 -0
- package/dist/utxo/unsigned_utxo_transaction.js +32 -0
- package/dist/utxo/unsigned_utxo_transaction.js.map +1 -0
- package/dist/utxo/utxo.d.ts +43 -0
- package/dist/utxo/utxo.d.ts.map +1 -0
- package/dist/utxo/utxo.js +2 -0
- package/dist/utxo/utxo.js.map +1 -0
- package/dist/utxo/utxo_chain.d.ts +102 -0
- package/dist/utxo/utxo_chain.d.ts.map +1 -0
- package/dist/utxo/utxo_chain.js +524 -0
- package/dist/utxo/utxo_chain.js.map +1 -0
- package/dist/utxo/utxo_chains.d.ts +29 -0
- package/dist/utxo/utxo_chains.d.ts.map +1 -0
- package/dist/utxo/utxo_chains.js +63 -0
- package/dist/utxo/utxo_chains.js.map +1 -0
- package/dist/utxo/utxo_gas_pricing.d.ts +22 -0
- package/dist/utxo/utxo_gas_pricing.d.ts.map +1 -0
- package/dist/utxo/utxo_gas_pricing.js +20 -0
- package/dist/utxo/utxo_gas_pricing.js.map +1 -0
- package/dist/utxo/utxo_network_params.d.ts +25 -0
- package/dist/utxo/utxo_network_params.d.ts.map +1 -0
- package/dist/utxo/utxo_network_params.js +15 -0
- package/dist/utxo/utxo_network_params.js.map +1 -0
- package/dist/utxo/utxo_transaction_status.d.ts +73 -0
- package/dist/utxo/utxo_transaction_status.d.ts.map +1 -0
- package/dist/utxo/utxo_transaction_status.js +89 -0
- package/dist/utxo/utxo_transaction_status.js.map +1 -0
- package/docs/PUBLISHING.md +119 -0
- package/docs/README.md +273 -0
- package/docs/evm.md +205 -0
- package/docs/solana.md +220 -0
- package/docs/utxo.md +364 -0
- package/package.json +94 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 getomnichain
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# @getomnichain/omnichain
|
|
2
|
+
|
|
3
|
+
Multi-chain TypeScript SDK. One `Chain` / `Token` / `Address` / `UnsignedTransaction` shape for EVM, UTXO (BTC/LTC/DOGE/DASH/ZEC/BCH), Solana, TON, and Tron. Line-for-line parity port of Python's [`omnichain-py`](https://github.com/getomnichain/omnichain-py).
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install @getomnichain/omnichain decimal.js
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
`decimal.js` is a required peer install — the package imports it at the root and consumer builds fail at import time if it's missing.
|
|
10
|
+
|
|
11
|
+
## Quick start
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { arbitrumChain, isSuccess, Priority } from '@getomnichain/omnichain';
|
|
15
|
+
import Decimal from 'decimal.js';
|
|
16
|
+
|
|
17
|
+
const chain = arbitrumChain({ rpcUrl: process.env.ARBITRUM_RPC_URL });
|
|
18
|
+
|
|
19
|
+
const unsigned = await chain.createTransferUnsignedTransaction({
|
|
20
|
+
from: senderAddress,
|
|
21
|
+
to: recipientAddress,
|
|
22
|
+
tokenIdentifier: usdcAddress,
|
|
23
|
+
amountHr: new Decimal('1.5'),
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const status = await chain.getTransactionStatus(txHash);
|
|
27
|
+
if (isSuccess(status)) {
|
|
28
|
+
for (const [wallet, perAsset] of status.balanceChanges) {
|
|
29
|
+
for (const { token, change } of perAsset.values()) {
|
|
30
|
+
console.log(wallet, token.symbol, change.balanceChangeMr, change.balanceChangeHr.toFixed());
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const gas = await chain.suggestGas(Priority.NORMAL);
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Consumer TypeScript setup: `module: "NodeNext"` + `moduleResolution: "NodeNext"`. The package ships compiled `.js` + `.d.ts` under `dist/`; the source is `.ts` on GitHub for anyone who wants to read the implementation.
|
|
39
|
+
|
|
40
|
+
## What this SDK does NOT do
|
|
41
|
+
|
|
42
|
+
- **Hold keys** — signing happens in the consumer service. The SDK only emits `UnsignedTransaction` objects.
|
|
43
|
+
- **Read environment variables** — every constructor takes an explicit config object. The one exception is RPC URL fallback resolution (`<NAME>_RPC_URL` / `EVM_<chainId>_RPC_URL` / `SOLANA_<chainId>_RPC_URL`), documented per chain.
|
|
44
|
+
- **Decide chain IDs** — non-EVM chains have no universal numeric ID; consumers can seed a synthetic scheme via `registerNonEvmChain(id, family)`.
|
|
45
|
+
- **Ship infrastructure** — RPC URLs, indexer keys, Bitcoin Core / Esplora endpoints are consumer-owned.
|
|
46
|
+
|
|
47
|
+
## Solana raw-instruction helpers
|
|
48
|
+
|
|
49
|
+
`SolanaChain` exposes two raw-instruction builders alongside `createTransferUnsignedTransaction`, for callers that will compile the transaction downstream:
|
|
50
|
+
|
|
51
|
+
- `buildNativeTransferInstruction(from, to, lamports)` — sync; wraps `SystemProgram.transfer`.
|
|
52
|
+
- `buildSplTransferInstructions({from, to, mint, amount, includeCreateAta?, allowOwnerOffCurve?})` — async; returns `[createATA-idempotent?, transferChecked]`. Uses the idempotent ATA form (not probe-then-create) because the downstream compiler runs instructions blindly and a probe would race with execution. `allowOwnerOffCurve` applies to both source and destination ATA derivation for PDA-owned wallets.
|
|
53
|
+
|
|
54
|
+
`createTransferUnsignedTransaction`'s compiled-tx surface uses probe-then-create for its own end-to-end signing path.
|
|
55
|
+
|
|
56
|
+
## Documentation
|
|
57
|
+
|
|
58
|
+
- [docs/README.md](./docs/README.md) — full module guide
|
|
59
|
+
- [docs/evm.md](./docs/evm.md) — EVM chains and ERC-20
|
|
60
|
+
- [docs/utxo.md](./docs/utxo.md) — Bitcoin / Litecoin / Dogecoin, fee estimation, BTC asset filtering
|
|
61
|
+
- [docs/solana.md](./docs/solana.md) — Solana, SPL Token, Token-2022, priority-fee model
|
|
62
|
+
- [docs/PUBLISHING.md](./docs/PUBLISHING.md) — release + npm publish workflow
|
|
63
|
+
|
|
64
|
+
## License
|
|
65
|
+
|
|
66
|
+
MIT — see [LICENSE](./LICENSE).
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { NetworkType } from './network_type.ts';
|
|
2
|
+
import { FeePriority } from './priority.ts';
|
|
3
|
+
/**
|
|
4
|
+
* Base for chain-specific *explicit* fee overrides — mirrors Python's
|
|
5
|
+
* `AbstractGasPricing(pydantic.BaseModel)` at `base/base.py:141-158`.
|
|
6
|
+
* A subclass declares its `networkType` and carries the concrete fee
|
|
7
|
+
* fields for that chain (`EvmGasPricing`, `SolanaGasPricing`,
|
|
8
|
+
* `UtxoGasPricing`).
|
|
9
|
+
*
|
|
10
|
+
* A caller who wants exact numeric control passes an `AbstractGasPricing`
|
|
11
|
+
* subclass to `createTransferUnsignedTransaction`; passing a
|
|
12
|
+
* `FeePriority` tier (SLOW/NORMAL/FAST) instead defers to each chain's
|
|
13
|
+
* `suggest*` estimator. See `GasPricingType`.
|
|
14
|
+
*/
|
|
15
|
+
export declare abstract class AbstractGasPricing {
|
|
16
|
+
abstract readonly networkType: NetworkType;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The gas-pricing argument accepted by every
|
|
20
|
+
* `createTransferUnsignedTransaction`. Mirrors Python's
|
|
21
|
+
* `GasPricingType = Union[FeePriority, AbstractGasPricing]` at
|
|
22
|
+
* `base/base.py:162`. Consumers use `FeePriority.NORMAL` by default;
|
|
23
|
+
* explicit overrides use a per-chain subclass.
|
|
24
|
+
*/
|
|
25
|
+
export type GasPricingType = FeePriority | AbstractGasPricing;
|
|
26
|
+
/**
|
|
27
|
+
* Runtime discriminator for `GasPricingType`. `FeePriority` is a
|
|
28
|
+
* string enum; `AbstractGasPricing` is a class instance.
|
|
29
|
+
*/
|
|
30
|
+
export declare function isAbstractGasPricing(value: GasPricingType): value is AbstractGasPricing;
|
|
31
|
+
//# sourceMappingURL=abstract_gas_pricing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abstract_gas_pricing.d.ts","sourceRoot":"","sources":["../abstract_gas_pricing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C;;;;;;;;;;;GAWG;AACH,8BAAsB,kBAAkB;IACtC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;CAC5C;AAED;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,kBAAkB,CAAC;AAE9D;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,cAAc,GAAG,KAAK,IAAI,kBAAkB,CAEvF"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base for chain-specific *explicit* fee overrides — mirrors Python's
|
|
3
|
+
* `AbstractGasPricing(pydantic.BaseModel)` at `base/base.py:141-158`.
|
|
4
|
+
* A subclass declares its `networkType` and carries the concrete fee
|
|
5
|
+
* fields for that chain (`EvmGasPricing`, `SolanaGasPricing`,
|
|
6
|
+
* `UtxoGasPricing`).
|
|
7
|
+
*
|
|
8
|
+
* A caller who wants exact numeric control passes an `AbstractGasPricing`
|
|
9
|
+
* subclass to `createTransferUnsignedTransaction`; passing a
|
|
10
|
+
* `FeePriority` tier (SLOW/NORMAL/FAST) instead defers to each chain's
|
|
11
|
+
* `suggest*` estimator. See `GasPricingType`.
|
|
12
|
+
*/
|
|
13
|
+
export class AbstractGasPricing {
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Runtime discriminator for `GasPricingType`. `FeePriority` is a
|
|
17
|
+
* string enum; `AbstractGasPricing` is a class instance.
|
|
18
|
+
*/
|
|
19
|
+
export function isAbstractGasPricing(value) {
|
|
20
|
+
return value instanceof AbstractGasPricing;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=abstract_gas_pricing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abstract_gas_pricing.js","sourceRoot":"","sources":["../abstract_gas_pricing.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AACH,MAAM,OAAgB,kBAAkB;CAEvC;AAWD;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAqB;IACxD,OAAO,KAAK,YAAY,kBAAkB,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { NetworkType } from './network_type.ts';
|
|
2
|
+
export declare abstract class Address {
|
|
3
|
+
protected readonly raw: string;
|
|
4
|
+
protected constructor(raw: string);
|
|
5
|
+
abstract canonical(): string;
|
|
6
|
+
abstract get networkType(): NetworkType;
|
|
7
|
+
equals(other: Address): boolean;
|
|
8
|
+
toString(): string;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=address.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"address.d.ts","sourceRoot":"","sources":["../address.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,8BAAsB,OAAO;IACL,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM;IAApD,SAAS,aAAgC,GAAG,EAAE,MAAM;IAEpD,QAAQ,CAAC,SAAS,IAAI,MAAM;IAC5B,QAAQ,KAAK,WAAW,IAAI,WAAW,CAAC;IAExC,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO;IAM/B,QAAQ,IAAI,MAAM;CAGnB"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Address } from './address.ts';
|
|
2
|
+
export declare function addressFor(chainId: number, raw: string): Address;
|
|
3
|
+
export declare function canonicalizeAddress(chainId: number, raw: string): string;
|
|
4
|
+
/**
|
|
5
|
+
* Total function — never throws. Returns the raw input on any failure
|
|
6
|
+
* (address-format error, unsupported chain, malformed args).
|
|
7
|
+
*
|
|
8
|
+
* Callers that need to fail loudly on stale/unsupported chainIds while
|
|
9
|
+
* still tolerating address-format errors should use
|
|
10
|
+
* `canonicalizeAddressStrict` instead.
|
|
11
|
+
*/
|
|
12
|
+
export declare function tryCanonicalizeAddress(chainId: number, raw: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Swallows address-format errors (returns raw input) but re-throws
|
|
15
|
+
* `ChainError(ChainNotSupported)` so a stale chainId (e.g. un-migrated
|
|
16
|
+
* legacy Solana `-100`) fails loudly rather than passing a bogus routing
|
|
17
|
+
* signal downstream. Use in application code where an unsupported chain
|
|
18
|
+
* is a hard error the caller wants to surface, and address-format
|
|
19
|
+
* errors are reported by a separate validation layer.
|
|
20
|
+
*
|
|
21
|
+
* NOT for class-transformer `@Transform` callbacks — a throw there also
|
|
22
|
+
* fires during response serialization when an entity carries a stale
|
|
23
|
+
* chainId, killing every read of a legacy row.
|
|
24
|
+
*/
|
|
25
|
+
export declare function canonicalizeAddressStrict(chainId: number, raw: string): string;
|
|
26
|
+
//# sourceMappingURL=address.factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"address.factory.d.ts","sourceRoot":"","sources":["../address.factory.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAOvC,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAiChE;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAExE;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAM3E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAO9E"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { ChainError, ChainErrorKinds, isChainError } from "./errors.js";
|
|
2
|
+
import { NetworkType, networkTypeOf } from "./network_type.js";
|
|
3
|
+
import { EvmAddress } from "./evm/evm_address.js";
|
|
4
|
+
import { SolanaAddress } from "./solana/solana_address.js";
|
|
5
|
+
import { TonAddress } from "./ton/ton_address.js";
|
|
6
|
+
import { BtcAddress } from "./utxo/btc/btc_address.js";
|
|
7
|
+
import { btcParamsForChainId } from "./utxo/btc/network_params.js";
|
|
8
|
+
export function addressFor(chainId, raw) {
|
|
9
|
+
const family = networkTypeOf(chainId);
|
|
10
|
+
switch (family) {
|
|
11
|
+
case NetworkType.EVM:
|
|
12
|
+
return new EvmAddress(raw);
|
|
13
|
+
case NetworkType.SOLANA:
|
|
14
|
+
return new SolanaAddress(raw);
|
|
15
|
+
case NetworkType.BTC:
|
|
16
|
+
return new BtcAddress(raw, btcParamsForChainId(BigInt(chainId)));
|
|
17
|
+
case NetworkType.TON:
|
|
18
|
+
return new TonAddress(raw);
|
|
19
|
+
// TRON / COSMOS have no in-repo Address class yet. Rather than fall through
|
|
20
|
+
// to EvmAddress (which would silently accept a valid EVM address for a
|
|
21
|
+
// Tron chain and un-canonicalize base58 T… addresses), fail closed until
|
|
22
|
+
// the concrete implementations land.
|
|
23
|
+
case NetworkType.TRON:
|
|
24
|
+
case NetworkType.COSMOS:
|
|
25
|
+
throw new ChainError(ChainErrorKinds.ChainNotSupported, `${family} address parsing is not implemented for chainId ${chainId}`, { chainId });
|
|
26
|
+
default: {
|
|
27
|
+
// Exhaustiveness guard — a new NetworkType value should force this
|
|
28
|
+
// switch to be updated rather than fall through to EVM.
|
|
29
|
+
const exhaustive = family;
|
|
30
|
+
throw new ChainError(ChainErrorKinds.ChainNotSupported, `Unhandled NetworkType ${String(exhaustive)} for chainId ${chainId}`, { chainId });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function canonicalizeAddress(chainId, raw) {
|
|
35
|
+
return addressFor(chainId, raw).canonical();
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Total function — never throws. Returns the raw input on any failure
|
|
39
|
+
* (address-format error, unsupported chain, malformed args).
|
|
40
|
+
*
|
|
41
|
+
* Callers that need to fail loudly on stale/unsupported chainIds while
|
|
42
|
+
* still tolerating address-format errors should use
|
|
43
|
+
* `canonicalizeAddressStrict` instead.
|
|
44
|
+
*/
|
|
45
|
+
export function tryCanonicalizeAddress(chainId, raw) {
|
|
46
|
+
try {
|
|
47
|
+
return canonicalizeAddress(chainId, raw);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return raw;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Swallows address-format errors (returns raw input) but re-throws
|
|
55
|
+
* `ChainError(ChainNotSupported)` so a stale chainId (e.g. un-migrated
|
|
56
|
+
* legacy Solana `-100`) fails loudly rather than passing a bogus routing
|
|
57
|
+
* signal downstream. Use in application code where an unsupported chain
|
|
58
|
+
* is a hard error the caller wants to surface, and address-format
|
|
59
|
+
* errors are reported by a separate validation layer.
|
|
60
|
+
*
|
|
61
|
+
* NOT for class-transformer `@Transform` callbacks — a throw there also
|
|
62
|
+
* fires during response serialization when an entity carries a stale
|
|
63
|
+
* chainId, killing every read of a legacy row.
|
|
64
|
+
*/
|
|
65
|
+
export function canonicalizeAddressStrict(chainId, raw) {
|
|
66
|
+
try {
|
|
67
|
+
return canonicalizeAddress(chainId, raw);
|
|
68
|
+
}
|
|
69
|
+
catch (e) {
|
|
70
|
+
if (isChainError(e, ChainErrorKinds.ChainNotSupported))
|
|
71
|
+
throw e;
|
|
72
|
+
return raw;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=address.factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"address.factory.js","sourceRoot":"","sources":["../address.factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAG/D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAEnE,MAAM,UAAU,UAAU,CAAC,OAAe,EAAE,GAAW;IACrD,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACtC,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,WAAW,CAAC,GAAG;YAClB,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;QAC7B,KAAK,WAAW,CAAC,MAAM;YACrB,OAAO,IAAI,aAAa,CAAC,GAAG,CAAC,CAAC;QAChC,KAAK,WAAW,CAAC,GAAG;YAClB,OAAO,IAAI,UAAU,CAAC,GAAG,EAAE,mBAAmB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACnE,KAAK,WAAW,CAAC,GAAG;YAClB,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;QAC7B,4EAA4E;QAC5E,uEAAuE;QACvE,yEAAyE;QACzE,qCAAqC;QACrC,KAAK,WAAW,CAAC,IAAI,CAAC;QACtB,KAAK,WAAW,CAAC,MAAM;YACrB,MAAM,IAAI,UAAU,CAClB,eAAe,CAAC,iBAAiB,EACjC,GAAG,MAAM,mDAAmD,OAAO,EAAE,EACrE,EAAE,OAAO,EAAE,CACZ,CAAC;QACJ,OAAO,CAAC,CAAC,CAAC;YACR,mEAAmE;YACnE,wDAAwD;YACxD,MAAM,UAAU,GAAU,MAAM,CAAC;YACjC,MAAM,IAAI,UAAU,CAClB,eAAe,CAAC,iBAAiB,EACjC,yBAAyB,MAAM,CAAC,UAAU,CAAC,gBAAgB,OAAO,EAAE,EACpE,EAAE,OAAO,EAAE,CACZ,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAe,EAAE,GAAW;IAC9D,OAAO,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC;AAC9C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAe,EAAE,GAAW;IACjE,IAAI,CAAC;QACH,OAAO,mBAAmB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,yBAAyB,CAAC,OAAe,EAAE,GAAW;IACpE,IAAI,CAAC;QACH,OAAO,mBAAmB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,YAAY,CAAC,CAAC,EAAE,eAAe,CAAC,iBAAiB,CAAC;YAAE,MAAM,CAAC,CAAC;QAChE,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC"}
|
package/dist/address.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export class Address {
|
|
2
|
+
raw;
|
|
3
|
+
constructor(raw) {
|
|
4
|
+
this.raw = raw;
|
|
5
|
+
}
|
|
6
|
+
equals(other) {
|
|
7
|
+
return (this.networkType === other.networkType && this.canonical() === other.canonical());
|
|
8
|
+
}
|
|
9
|
+
toString() {
|
|
10
|
+
return this.canonical();
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=address.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"address.js","sourceRoot":"","sources":["../address.ts"],"names":[],"mappings":"AAEA,MAAM,OAAgB,OAAO;IACc;IAAzC,YAAyC,GAAW;QAAX,QAAG,GAAH,GAAG,CAAQ;IAAG,CAAC;IAKxD,MAAM,CAAC,KAAc;QACnB,OAAO,CACL,IAAI,CAAC,WAAW,KAAK,KAAK,CAAC,WAAW,IAAI,IAAI,CAAC,SAAS,EAAE,KAAK,KAAK,CAAC,SAAS,EAAE,CACjF,CAAC;IACJ,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC;IAC1B,CAAC;CACF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Combines a `class-transformer` `@Transform` that canonicalizes the address
|
|
3
|
+
* value with an `@IsAddress` validator.
|
|
4
|
+
*
|
|
5
|
+
* The transform uses `tryCanonicalizeAddress` — a total function that
|
|
6
|
+
* swallows **every** failure (including `ChainNotSupported`) and returns the
|
|
7
|
+
* raw input. `@IsAddress` is the sole reporter of the failure at DTO
|
|
8
|
+
* validation time. This is deliberate: a `@Transform` also runs during
|
|
9
|
+
* `instanceToPlain` (response serialization), and a throw there would fail
|
|
10
|
+
* every read of a legacy-chainId entity row.
|
|
11
|
+
*
|
|
12
|
+
* For application code outside a class-transformer boundary that wants
|
|
13
|
+
* `ChainNotSupported` to fail loud (e.g. a service layer processing a
|
|
14
|
+
* migration queue), use `canonicalizeAddressStrict` instead.
|
|
15
|
+
*/
|
|
16
|
+
export declare function AddressField(chainIdProperty: string): PropertyDecorator;
|
|
17
|
+
//# sourceMappingURL=address_field.decorator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"address_field.decorator.d.ts","sourceRoot":"","sources":["../address_field.decorator.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,eAAe,EAAE,MAAM,GAAG,iBAAiB,CAYvE"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Transform } from 'class-transformer';
|
|
2
|
+
import { tryCanonicalizeAddress } from "./address.factory.js";
|
|
3
|
+
import { IsAddress } from "./is_address.decorator.js";
|
|
4
|
+
/**
|
|
5
|
+
* Combines a `class-transformer` `@Transform` that canonicalizes the address
|
|
6
|
+
* value with an `@IsAddress` validator.
|
|
7
|
+
*
|
|
8
|
+
* The transform uses `tryCanonicalizeAddress` — a total function that
|
|
9
|
+
* swallows **every** failure (including `ChainNotSupported`) and returns the
|
|
10
|
+
* raw input. `@IsAddress` is the sole reporter of the failure at DTO
|
|
11
|
+
* validation time. This is deliberate: a `@Transform` also runs during
|
|
12
|
+
* `instanceToPlain` (response serialization), and a throw there would fail
|
|
13
|
+
* every read of a legacy-chainId entity row.
|
|
14
|
+
*
|
|
15
|
+
* For application code outside a class-transformer boundary that wants
|
|
16
|
+
* `ChainNotSupported` to fail loud (e.g. a service layer processing a
|
|
17
|
+
* migration queue), use `canonicalizeAddressStrict` instead.
|
|
18
|
+
*/
|
|
19
|
+
export function AddressField(chainIdProperty) {
|
|
20
|
+
const transform = Transform(({ obj, value }) => {
|
|
21
|
+
if (typeof value !== 'string')
|
|
22
|
+
return value;
|
|
23
|
+
const chainId = obj[chainIdProperty];
|
|
24
|
+
if (typeof chainId !== 'number')
|
|
25
|
+
return value;
|
|
26
|
+
return tryCanonicalizeAddress(chainId, value);
|
|
27
|
+
});
|
|
28
|
+
const validate = IsAddress(chainIdProperty);
|
|
29
|
+
return (target, propertyKey) => {
|
|
30
|
+
transform(target, propertyKey);
|
|
31
|
+
validate(target, propertyKey);
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=address_field.decorator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"address_field.decorator.js","sourceRoot":"","sources":["../address_field.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAEtD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,YAAY,CAAC,eAAuB;IAClD,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE;QAC7C,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC5C,MAAM,OAAO,GAAI,GAA+B,CAAC,eAAe,CAAC,CAAC;QAClE,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC9C,OAAO,sBAAsB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,SAAS,CAAC,eAAe,CAAC,CAAC;IAC5C,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE;QAC7B,SAAS,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QAC/B,QAAQ,CAAC,MAAM,EAAE,WAAqB,CAAC,CAAC;IAC1C,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { Decimal } from 'decimal.js';
|
|
2
|
+
import { GasPricingType } from './abstract_gas_pricing.ts';
|
|
3
|
+
import { NetworkType } from './network_type.ts';
|
|
4
|
+
import { Token } from './token.ts';
|
|
5
|
+
import { TransactionStatus } from './transaction_status.ts';
|
|
6
|
+
import { UnsignedTransaction } from './unsigned_transaction.ts';
|
|
7
|
+
/**
|
|
8
|
+
* Amount contract — Python parity with `create_transfer_transaction`
|
|
9
|
+
* (base/base.py:529-539) which takes `amount_hr: Decimal` +
|
|
10
|
+
* `is_full_balance: bool`. TS accepts either:
|
|
11
|
+
*
|
|
12
|
+
* - `amount: bigint` — minor units (existing SDK-native form)
|
|
13
|
+
* - `amountHr: Decimal` — human-readable (Python-native form)
|
|
14
|
+
* - `isFullBalance: true` — sweep the sender's whole balance
|
|
15
|
+
*
|
|
16
|
+
* Exactly one of the three must be supplied. `resolveTransferAmount`
|
|
17
|
+
* enforces this and throws `ChainError(InvalidArgument)` on ambiguous
|
|
18
|
+
* input.
|
|
19
|
+
*/
|
|
20
|
+
export interface CreateTransferRequest {
|
|
21
|
+
from?: string;
|
|
22
|
+
to: string;
|
|
23
|
+
tokenIdentifier?: string;
|
|
24
|
+
amount?: bigint;
|
|
25
|
+
amountHr?: Decimal;
|
|
26
|
+
isFullBalance?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Gas-pricing knob — Python's `gas_pricing: GasPricingType`. The type
|
|
29
|
+
* surface is in place (Python parity) but per-chain builders **do
|
|
30
|
+
* not consume it yet** in Wave 2B — passing ANY value (including
|
|
31
|
+
* `FeePriority.NORMAL`) throws `ChainError(InvalidArgument)`. Wiring
|
|
32
|
+
* to each chain's `suggestGas` / `suggestPriorityFeeMicroLamports` /
|
|
33
|
+
* `suggestFeeRate` estimator lands in a follow-up card. Until then
|
|
34
|
+
* use the existing per-chain option fields (Solana:
|
|
35
|
+
* `priorityFeeMicroLamportsPerCu` / `computeUnitLimit`; UTXO:
|
|
36
|
+
* `feeRateSatsPerVByte` / `feeTargetBlocks`; EVM: `UnsignedEvmTransaction`
|
|
37
|
+
* builder options).
|
|
38
|
+
*/
|
|
39
|
+
gasPricing?: GasPricingType;
|
|
40
|
+
memo?: string;
|
|
41
|
+
}
|
|
42
|
+
export type ResolvedTransferAmount = {
|
|
43
|
+
kind: 'exact';
|
|
44
|
+
amountMr: bigint;
|
|
45
|
+
} | {
|
|
46
|
+
kind: 'full';
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Validates that exactly one of `{amount, amountHr, isFullBalance}` was
|
|
50
|
+
* supplied and normalizes to a common shape the chain builders consume.
|
|
51
|
+
* Chain-agnostic — the caller supplies `decimals` (from the resolved
|
|
52
|
+
* token). Rounds `amountHr` via `Decimal.trunc()` matching Python's
|
|
53
|
+
* `hr_to_mr`.
|
|
54
|
+
*
|
|
55
|
+
* Non-integer decimals / negative amount / etc. throw
|
|
56
|
+
* `ChainError(InvalidArgument)`.
|
|
57
|
+
*/
|
|
58
|
+
export declare function resolveTransferAmount(req: CreateTransferRequest, decimals: number): ResolvedTransferAmount;
|
|
59
|
+
export declare abstract class Chain {
|
|
60
|
+
readonly chainId: number;
|
|
61
|
+
readonly name: string;
|
|
62
|
+
readonly networkType: NetworkType;
|
|
63
|
+
readonly blockTimeSeconds: number;
|
|
64
|
+
readonly nativeSymbol: string;
|
|
65
|
+
readonly explorerBaseUrl: string;
|
|
66
|
+
protected constructor(chainId: number, name: string, networkType: NetworkType, blockTimeSeconds: number, nativeSymbol: string, explorerBaseUrl: string);
|
|
67
|
+
abstract get nativeToken(): Token;
|
|
68
|
+
abstract getWalletExplorerUrl(address: string): string;
|
|
69
|
+
abstract getTokenExplorerUrl(tokenIdentifier?: string): string;
|
|
70
|
+
abstract getTransactionExplorerUrl(txHash: string): string;
|
|
71
|
+
abstract validateAddress(raw: string): boolean;
|
|
72
|
+
abstract validateTokenIdentifier(raw: string | undefined): boolean;
|
|
73
|
+
abstract getBalance(owner: string, tokenIdentifier?: string): Promise<bigint>;
|
|
74
|
+
abstract createTransferUnsignedTransaction(req: CreateTransferRequest): Promise<UnsignedTransaction>;
|
|
75
|
+
abstract getTransactionStatus(txHash: string): Promise<TransactionStatus>;
|
|
76
|
+
abstract getChainTipHeight(): Promise<number>;
|
|
77
|
+
toString(): string;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=chain.base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chain.base.d.ts","sourceRoot":"","sources":["../chain.base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAErC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAEhE;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,sBAAsB,GAC9B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAErB;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,qBAAqB,EAC1B,QAAQ,EAAE,MAAM,GACf,sBAAsB,CA4GxB;AAED,8BAAsB,KAAK;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IAEjC,SAAS,aACP,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,WAAW,EACxB,gBAAgB,EAAE,MAAM,EACxB,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM;IAazB,QAAQ,KAAK,WAAW,IAAI,KAAK,CAAC;IAElC,QAAQ,CAAC,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IACtD,QAAQ,CAAC,mBAAmB,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM;IAC9D,QAAQ,CAAC,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAE1D,QAAQ,CAAC,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAC9C,QAAQ,CAAC,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO;IAElE,QAAQ,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAE7E,QAAQ,CAAC,iCAAiC,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAEpG,QAAQ,CAAC,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAEzE,QAAQ,CAAC,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;IAE7C,QAAQ,IAAI,MAAM;CAGnB"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { Decimal } from 'decimal.js';
|
|
2
|
+
import { ChainError, ChainErrorKinds } from "./errors.js";
|
|
3
|
+
import { hrDecimalToMinorUnits } from "./transaction_status.js";
|
|
4
|
+
/**
|
|
5
|
+
* Validates that exactly one of `{amount, amountHr, isFullBalance}` was
|
|
6
|
+
* supplied and normalizes to a common shape the chain builders consume.
|
|
7
|
+
* Chain-agnostic — the caller supplies `decimals` (from the resolved
|
|
8
|
+
* token). Rounds `amountHr` via `Decimal.trunc()` matching Python's
|
|
9
|
+
* `hr_to_mr`.
|
|
10
|
+
*
|
|
11
|
+
* Non-integer decimals / negative amount / etc. throw
|
|
12
|
+
* `ChainError(InvalidArgument)`.
|
|
13
|
+
*/
|
|
14
|
+
export function resolveTransferAmount(req, decimals) {
|
|
15
|
+
// Upfront typeof gate for isFullBalance — silently coercing a non-boolean
|
|
16
|
+
// to "unset" here would let `{amount, isFullBalance: 'true'}` (JSON boundary
|
|
17
|
+
// realistic) take the amount branch instead of failing the exactly-one-of.
|
|
18
|
+
if (req.isFullBalance !== undefined && typeof req.isFullBalance !== 'boolean') {
|
|
19
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `CreateTransferRequest.isFullBalance must be a boolean (got ${typeof req.isFullBalance})`);
|
|
20
|
+
}
|
|
21
|
+
const provided = [];
|
|
22
|
+
if (req.amount !== undefined)
|
|
23
|
+
provided.push('amount');
|
|
24
|
+
if (req.amountHr !== undefined)
|
|
25
|
+
provided.push('amountHr');
|
|
26
|
+
if (req.isFullBalance === true)
|
|
27
|
+
provided.push('isFullBalance');
|
|
28
|
+
if (provided.length === 0) {
|
|
29
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, 'CreateTransferRequest: one of {amount, amountHr, isFullBalance} is required');
|
|
30
|
+
}
|
|
31
|
+
if (provided.length > 1) {
|
|
32
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `CreateTransferRequest: exactly one of {amount, amountHr, isFullBalance} may be set (got ${provided.join(', ')})`);
|
|
33
|
+
}
|
|
34
|
+
if (req.isFullBalance === true)
|
|
35
|
+
return { kind: 'full' };
|
|
36
|
+
if (req.amount !== undefined) {
|
|
37
|
+
// Explicit typeof check: JS mixed-type comparison lets '1000000' <= 0n
|
|
38
|
+
// return false (`StringToBigInt`), so a string/number amount would
|
|
39
|
+
// otherwise pass this guard and land verbatim in tx.value /
|
|
40
|
+
// lamports / ERC-20 calldata. Realistic vector: consumers
|
|
41
|
+
// deserializing amounts from HTTP/DB JSON.
|
|
42
|
+
if (typeof req.amount !== 'bigint') {
|
|
43
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `CreateTransferRequest.amount must be a bigint (got ${typeof req.amount})`);
|
|
44
|
+
}
|
|
45
|
+
if (req.amount <= 0n) {
|
|
46
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `CreateTransferRequest.amount must be > 0, got ${req.amount}`);
|
|
47
|
+
}
|
|
48
|
+
return { kind: 'exact', amountMr: req.amount };
|
|
49
|
+
}
|
|
50
|
+
// amountHr branch. Cross-copy-safe structural probe: `instanceof
|
|
51
|
+
// Decimal` and `Decimal.isDecimal` both key off constructor identity
|
|
52
|
+
// in practice (isDecimal's toStringTag branch is dead against the
|
|
53
|
+
// shipped prototype), so a `Decimal` from a nested/duplicated copy of
|
|
54
|
+
// decimal.js in the consumer tree would falsely reject. Instead:
|
|
55
|
+
// probe for the two methods we actually need (`toFixed`, `isFinite`),
|
|
56
|
+
// then normalize via `Decimal.prototype.toString` — an exact,
|
|
57
|
+
// always-reparseable serialization — into our own Decimal instance.
|
|
58
|
+
const rawHr = req.amountHr;
|
|
59
|
+
if (rawHr === null ||
|
|
60
|
+
typeof rawHr !== 'object' ||
|
|
61
|
+
typeof rawHr.toFixed !== 'function' ||
|
|
62
|
+
typeof rawHr.isFinite !== 'function' ||
|
|
63
|
+
typeof rawHr.toString !== 'function') {
|
|
64
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, 'CreateTransferRequest.amountHr must be a Decimal value (structural probe: needs toFixed + isFinite + toString)');
|
|
65
|
+
}
|
|
66
|
+
let hr;
|
|
67
|
+
try {
|
|
68
|
+
hr = new Decimal(rawHr.toString());
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, 'CreateTransferRequest.amountHr: string round-trip failed', undefined, err instanceof Error ? err : undefined);
|
|
72
|
+
}
|
|
73
|
+
if (!hr.isFinite()) {
|
|
74
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `CreateTransferRequest.amountHr must be finite, got ${hr.toString()}`);
|
|
75
|
+
}
|
|
76
|
+
if (!Number.isInteger(decimals) || decimals < 0) {
|
|
77
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `CreateTransferRequest.amountHr requires a non-negative integer decimals, got ${decimals}`);
|
|
78
|
+
}
|
|
79
|
+
if (hr.isNegative()) {
|
|
80
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `CreateTransferRequest.amountHr must be >= 0, got ${hr.toString()}`);
|
|
81
|
+
}
|
|
82
|
+
// Exact conversion via string-shift (bypasses decimal.js's 20-sig-digit
|
|
83
|
+
// precision limit that would silently round the last wei on 18-decimal
|
|
84
|
+
// amounts ≥ ~100 tokens).
|
|
85
|
+
const amountMr = hrDecimalToMinorUnits(hr, decimals);
|
|
86
|
+
if (amountMr <= 0n) {
|
|
87
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `CreateTransferRequest.amountHr must convert to > 0 minor units, got ${amountMr} (from ${hr.toString()} @ ${decimals} decimals)`);
|
|
88
|
+
}
|
|
89
|
+
return { kind: 'exact', amountMr };
|
|
90
|
+
}
|
|
91
|
+
export class Chain {
|
|
92
|
+
chainId;
|
|
93
|
+
name;
|
|
94
|
+
networkType;
|
|
95
|
+
blockTimeSeconds;
|
|
96
|
+
nativeSymbol;
|
|
97
|
+
explorerBaseUrl;
|
|
98
|
+
constructor(chainId, name, networkType, blockTimeSeconds, nativeSymbol, explorerBaseUrl) {
|
|
99
|
+
if (!Number.isInteger(chainId)) {
|
|
100
|
+
throw new Error('Chain chainId must be an integer');
|
|
101
|
+
}
|
|
102
|
+
this.chainId = chainId;
|
|
103
|
+
this.name = name;
|
|
104
|
+
this.networkType = networkType;
|
|
105
|
+
this.blockTimeSeconds = blockTimeSeconds;
|
|
106
|
+
this.nativeSymbol = nativeSymbol;
|
|
107
|
+
this.explorerBaseUrl = explorerBaseUrl.replace(/\/$/, '');
|
|
108
|
+
}
|
|
109
|
+
toString() {
|
|
110
|
+
return `Chain[chainId=${this.chainId}, name=${this.name}, networkType=${this.networkType}]`;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=chain.base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chain.base.js","sourceRoot":"","sources":["../chain.base.ts"],"names":[],"mappings":"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"}
|