@getomnichain/omnichain 0.3.6 → 0.5.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 +80 -1
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/rango_chain_names.js +209 -0
- package/dist/cjs/rango_chain_names.js.map +1 -0
- package/dist/cjs/solana/solana_chain.js +89 -25
- package/dist/cjs/solana/solana_chain.js.map +1 -1
- package/dist/cjs/solana/solana_transaction_status.js +39 -3
- package/dist/cjs/solana/solana_transaction_status.js.map +1 -1
- package/dist/cjs/utxo/btc/tools/bitcoin_core.tool.js +129 -0
- package/dist/cjs/utxo/btc/tools/bitcoin_core.tool.js.map +1 -1
- package/dist/cjs/utxo/btc/tools/esplora.tool.js +84 -0
- package/dist/cjs/utxo/btc/tools/esplora.tool.js.map +1 -1
- package/dist/cjs/utxo/utxo_chain.js +18 -49
- package/dist/cjs/utxo/utxo_chain.js.map +1 -1
- package/dist/cjs/utxo/utxo_transaction_status.js +20 -16
- package/dist/cjs/utxo/utxo_transaction_status.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/rango_chain_names.d.ts +76 -0
- package/dist/esm/rango_chain_names.d.ts.map +1 -0
- package/dist/esm/rango_chain_names.js +171 -0
- package/dist/esm/rango_chain_names.js.map +1 -0
- package/dist/esm/solana/solana_chain.d.ts.map +1 -1
- package/dist/esm/solana/solana_chain.js +90 -26
- package/dist/esm/solana/solana_chain.js.map +1 -1
- package/dist/esm/solana/solana_transaction_status.d.ts +40 -2
- package/dist/esm/solana/solana_transaction_status.d.ts.map +1 -1
- package/dist/esm/solana/solana_transaction_status.js +38 -2
- package/dist/esm/solana/solana_transaction_status.js.map +1 -1
- package/dist/esm/utxo/btc/tools/bitcoin_core.tool.d.ts +4 -1
- package/dist/esm/utxo/btc/tools/bitcoin_core.tool.d.ts.map +1 -1
- package/dist/esm/utxo/btc/tools/bitcoin_core.tool.js +129 -0
- package/dist/esm/utxo/btc/tools/bitcoin_core.tool.js.map +1 -1
- package/dist/esm/utxo/btc/tools/esplora.tool.d.ts +2 -1
- package/dist/esm/utxo/btc/tools/esplora.tool.d.ts.map +1 -1
- package/dist/esm/utxo/btc/tools/esplora.tool.js +84 -0
- package/dist/esm/utxo/btc/tools/esplora.tool.js.map +1 -1
- package/dist/esm/utxo/tools/raw_transaction_provider.d.ts +2 -1
- package/dist/esm/utxo/tools/raw_transaction_provider.d.ts.map +1 -1
- package/dist/esm/utxo/utxo.d.ts +27 -0
- package/dist/esm/utxo/utxo.d.ts.map +1 -1
- package/dist/esm/utxo/utxo_chain.d.ts.map +1 -1
- package/dist/esm/utxo/utxo_chain.js +18 -49
- package/dist/esm/utxo/utxo_chain.js.map +1 -1
- package/dist/esm/utxo/utxo_transaction_status.d.ts +21 -16
- package/dist/esm/utxo/utxo_transaction_status.d.ts.map +1 -1
- package/dist/esm/utxo/utxo_transaction_status.js +20 -16
- package/dist/esm/utxo/utxo_transaction_status.js.map +1 -1
- package/docs/README.md +1 -0
- package/docs/solana.md +23 -0
- package/package.json +3 -2
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import * as C from "./chain_ids.js";
|
|
2
|
+
const MAX_RANGO_NAME_LENGTH = 64;
|
|
3
|
+
/**
|
|
4
|
+
* Bidirectional lookup between omnichain chain ids and Rango's canonical
|
|
5
|
+
* uppercase blockchain names (the `blockchains[].name` field of Rango's
|
|
6
|
+
* `/meta` response).
|
|
7
|
+
*
|
|
8
|
+
* TypeScript-only module — no `omnichain-py` counterpart. `chain_ids.ts`
|
|
9
|
+
* mirrors the Python catalogue, but the Rango-name mapping is a
|
|
10
|
+
* TS-consumer concern and does not exist on the Python side.
|
|
11
|
+
*
|
|
12
|
+
* Source of truth: `GET https://public-api.rango.exchange/basic/meta`.
|
|
13
|
+
* The snapshot backing this module lives at
|
|
14
|
+
* `test/fixtures/rango_meta_blockchains.json`; its `fetchedAt` field is
|
|
15
|
+
* the single source-of-date. Refresh via `npm run rango:refresh`.
|
|
16
|
+
*
|
|
17
|
+
* Downstream consumers that talk to Rango should import from here
|
|
18
|
+
* instead of maintaining a local copy. `test/rango_chain_names.spec.ts`
|
|
19
|
+
* fails the suite whenever `chain_ids.ts` gains a new id that is
|
|
20
|
+
* neither mapped here nor listed in `NOT_ON_RANGO`, so a new chain
|
|
21
|
+
* forces an explicit decision. That suite runs on every PR/push via
|
|
22
|
+
* `.github/workflows/test.yml` and on `npm publish` via
|
|
23
|
+
* `prepublishOnly`. When the `test` check is required on `main` via
|
|
24
|
+
* branch protection, consumers vendoring omnichain from `main` inherit
|
|
25
|
+
* that check as their guarantee; until then, the workflow signals but
|
|
26
|
+
* does not block.
|
|
27
|
+
*
|
|
28
|
+
* Aliases (alternate spellings Rango may use in other endpoints) are
|
|
29
|
+
* deliberately out of scope; if a consumer hits one, add it as a
|
|
30
|
+
* separate decision.
|
|
31
|
+
*/
|
|
32
|
+
export const CHAIN_ID_TO_RANGO_NAME = new Map([
|
|
33
|
+
[C.CHAIN_ID_BITCOIN_MAINNET, 'BTC'],
|
|
34
|
+
[C.CHAIN_ID_LITECOIN_MAINNET, 'LTC'],
|
|
35
|
+
[C.CHAIN_ID_DOGECOIN_MAINNET, 'DOGE'],
|
|
36
|
+
[C.CHAIN_ID_DASH_MAINNET, 'DASH'],
|
|
37
|
+
[C.CHAIN_ID_ZCASH_MAINNET, 'ZCASH'],
|
|
38
|
+
[C.CHAIN_ID_BITCOIN_CASH_MAINNET, 'BCH'],
|
|
39
|
+
[C.CHAIN_ID_SOLANA_MAINNET, 'SOLANA'],
|
|
40
|
+
[C.CHAIN_ID_SUI_MAINNET, 'SUI'],
|
|
41
|
+
[C.CHAIN_ID_XRPL_MAINNET, 'XRPL'],
|
|
42
|
+
[C.CHAIN_ID_STELLAR_MAINNET, 'STELLAR'],
|
|
43
|
+
[C.CHAIN_ID_TON_MAINNET, 'TON'],
|
|
44
|
+
[C.CHAIN_ID_TRON_MAINNET, 'TRON'],
|
|
45
|
+
[C.CHAIN_ID_ETHEREUM, 'ETH'],
|
|
46
|
+
[C.CHAIN_ID_OPTIMISM, 'OPTIMISM'],
|
|
47
|
+
[C.CHAIN_ID_CRONOS, 'CRONOS'],
|
|
48
|
+
[C.CHAIN_ID_BNB_CHAIN, 'BSC'],
|
|
49
|
+
[C.CHAIN_ID_OKX_CHAIN, 'OKC'],
|
|
50
|
+
[C.CHAIN_ID_GNOSIS, 'GNOSIS'],
|
|
51
|
+
[C.CHAIN_ID_UNICHAIN, 'UNICHAIN'],
|
|
52
|
+
[C.CHAIN_ID_POLYGON, 'POLYGON'],
|
|
53
|
+
[C.CHAIN_ID_MONAD, 'MONAD'],
|
|
54
|
+
[C.CHAIN_ID_SONIC, 'SONIC'],
|
|
55
|
+
[C.CHAIN_ID_SHIMMER, 'SHIMMER'],
|
|
56
|
+
[C.CHAIN_ID_XLAYER, 'XLAYER'],
|
|
57
|
+
[C.CHAIN_ID_FANTOM, 'FANTOM'],
|
|
58
|
+
[C.CHAIN_ID_BOBA, 'BOBA'],
|
|
59
|
+
[C.CHAIN_ID_ZKSYNC, 'ZKSYNC'],
|
|
60
|
+
[C.CHAIN_ID_STABLE, 'STABLE'],
|
|
61
|
+
[C.CHAIN_ID_HYPER_EVM, 'HYPEREVM'],
|
|
62
|
+
[C.CHAIN_ID_METIS, 'METIS'],
|
|
63
|
+
[C.CHAIN_ID_POLYGON_ZKEVM, 'POLYGONZK'],
|
|
64
|
+
[C.CHAIN_ID_MOONBEAM, 'MOONBEAM'],
|
|
65
|
+
[C.CHAIN_ID_MOONRIVER, 'MOONRIVER'],
|
|
66
|
+
[C.CHAIN_ID_SONEIUM, 'SONEIUM'],
|
|
67
|
+
[C.CHAIN_ID_CITREA, 'CITREA'],
|
|
68
|
+
[C.CHAIN_ID_MEGA_ETH, 'MEGAETH'],
|
|
69
|
+
[C.CHAIN_ID_ZETACHAIN, 'ZETA_CHAIN'],
|
|
70
|
+
[C.CHAIN_ID_BASE, 'BASE'],
|
|
71
|
+
[C.CHAIN_ID_IOTA_EVM, 'IOTA'],
|
|
72
|
+
[C.CHAIN_ID_PLASMA, 'PLASMA'],
|
|
73
|
+
[C.CHAIN_ID_MODE, 'MODE'],
|
|
74
|
+
[C.CHAIN_ID_ARBITRUM, 'ARBITRUM'],
|
|
75
|
+
[C.CHAIN_ID_CELO, 'CELO'],
|
|
76
|
+
[C.CHAIN_ID_AVALANCHE_C_CHAIN, 'AVAX_CCHAIN'],
|
|
77
|
+
[C.CHAIN_ID_LINEA, 'LINEA'],
|
|
78
|
+
[C.CHAIN_ID_BERA_CHAIN, 'BERACHAIN'],
|
|
79
|
+
[C.CHAIN_ID_BLAST, 'BLAST'],
|
|
80
|
+
[C.CHAIN_ID_TAIKO, 'TAIKO'],
|
|
81
|
+
[C.CHAIN_ID_SCROLL, 'SCROLL'],
|
|
82
|
+
[C.CHAIN_ID_KATANA, 'KATANA'],
|
|
83
|
+
[C.CHAIN_ID_ZORA, 'ZORA'],
|
|
84
|
+
[C.CHAIN_ID_AURORA, 'AURORA'],
|
|
85
|
+
]);
|
|
86
|
+
/**
|
|
87
|
+
* Inverse of `CHAIN_ID_TO_RANGO_NAME`, keyed by uppercase name.
|
|
88
|
+
* Prefer `chainIdForRangoName` for case- and whitespace-tolerant lookup.
|
|
89
|
+
*/
|
|
90
|
+
export const RANGO_NAME_TO_CHAIN_ID = new Map(Array.from(CHAIN_ID_TO_RANGO_NAME, ([id, name]) => [name, id]));
|
|
91
|
+
/**
|
|
92
|
+
* Explicit decisions for chain ids omnichain declares but Rango's `/meta`
|
|
93
|
+
* does not carry, verified against the same snapshot as
|
|
94
|
+
* `CHAIN_ID_TO_RANGO_NAME`.
|
|
95
|
+
*
|
|
96
|
+
* Every id in `chain_ids.ts` must appear in either `CHAIN_ID_TO_RANGO_NAME`
|
|
97
|
+
* or here; the coverage test fails the PR check and `npm publish` (via
|
|
98
|
+
* `prepublishOnly`) otherwise. Adding an id to `chain_ids.ts` without a
|
|
99
|
+
* decision is a bug.
|
|
100
|
+
*
|
|
101
|
+
* Grouped by reason:
|
|
102
|
+
* - Testnets/devnets Rango's `/meta` intentionally omits.
|
|
103
|
+
* - Mainnet EVM chains not on Rango's `/meta` as of the snapshot; add to
|
|
104
|
+
* `CHAIN_ID_TO_RANGO_NAME` once Rango starts publishing them.
|
|
105
|
+
*/
|
|
106
|
+
export const NOT_ON_RANGO = new Set([
|
|
107
|
+
// testnets/devnets — Rango's /meta never carries these.
|
|
108
|
+
C.CHAIN_ID_BITCOIN_TESTNET,
|
|
109
|
+
C.CHAIN_ID_BITCOIN_SIGNET,
|
|
110
|
+
C.CHAIN_ID_SOLANA_TESTNET,
|
|
111
|
+
C.CHAIN_ID_SOLANA_DEVNET,
|
|
112
|
+
C.CHAIN_ID_SUI_TESTNET,
|
|
113
|
+
C.CHAIN_ID_SUI_DEVNET,
|
|
114
|
+
C.CHAIN_ID_XRPL_TESTNET,
|
|
115
|
+
C.CHAIN_ID_STELLAR_TESTNET,
|
|
116
|
+
C.CHAIN_ID_TON_TESTNET,
|
|
117
|
+
C.CHAIN_ID_TRON_SHASTA,
|
|
118
|
+
C.CHAIN_ID_GOERLI,
|
|
119
|
+
C.CHAIN_ID_SEPOLIA,
|
|
120
|
+
C.CHAIN_ID_CELO_SEPOLIA,
|
|
121
|
+
// Mainnet, absent from /meta as of the fixture snapshot — move to the map when Rango publishes them.
|
|
122
|
+
C.CHAIN_ID_OPBNB,
|
|
123
|
+
C.CHAIN_ID_WORLD_CHAIN,
|
|
124
|
+
C.CHAIN_ID_WANCHAIN,
|
|
125
|
+
C.CHAIN_ID_SEI_EVM,
|
|
126
|
+
C.CHAIN_ID_ABSTRACT,
|
|
127
|
+
C.CHAIN_ID_TEMPO,
|
|
128
|
+
C.CHAIN_ID_MANTLE,
|
|
129
|
+
C.CHAIN_ID_INK,
|
|
130
|
+
C.CHAIN_ID_BOB,
|
|
131
|
+
C.CHAIN_ID_ZKLINK_NOVA,
|
|
132
|
+
]);
|
|
133
|
+
/**
|
|
134
|
+
* Rango's canonical uppercase blockchain name for a given omnichain chain
|
|
135
|
+
* id, or `undefined` when the chain is not on Rango, when the input is not
|
|
136
|
+
* a real number (`NaN`), or when it is `null` / `undefined`.
|
|
137
|
+
*
|
|
138
|
+
* `bigint` input is rejected at runtime and returns `undefined`. Callers
|
|
139
|
+
* bridging from `ethers` v6's `Network.chainId: bigint` should narrow with
|
|
140
|
+
* `Number(x)` and check `Number.isSafeInteger` first.
|
|
141
|
+
*/
|
|
142
|
+
export function rangoNameForChainId(chainId) {
|
|
143
|
+
if (typeof chainId !== 'number' || Number.isNaN(chainId))
|
|
144
|
+
return undefined;
|
|
145
|
+
return CHAIN_ID_TO_RANGO_NAME.get(chainId);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Omnichain chain id for a Rango blockchain name. Input is normalised
|
|
149
|
+
* (`trim()` + `toUpperCase()`) so `' bsc '`, `'BSC'`, `'Bsc'` all resolve
|
|
150
|
+
* to `56`. Returns `undefined` for an unknown name, for any non-string
|
|
151
|
+
* input, for raw input longer than 64 characters (rejected before any
|
|
152
|
+
* per-character work — the bound is several times the longest name in
|
|
153
|
+
* the snapshot, so it is a DoS guard, not a contract), or for input
|
|
154
|
+
* carrying non-ASCII characters (Unicode-aware `toUpperCase` folds
|
|
155
|
+
* `'ſ' → 'S'`
|
|
156
|
+
* and `'ı' → 'I'`, which would resolve homoglyph inputs to real chain
|
|
157
|
+
* ids — the accessor fails closed instead). Callers looping over
|
|
158
|
+
* untrusted Rango feed rows can skip bad entries without a `TypeError`.
|
|
159
|
+
*/
|
|
160
|
+
export function chainIdForRangoName(name) {
|
|
161
|
+
if (typeof name !== 'string')
|
|
162
|
+
return undefined;
|
|
163
|
+
if (name.length > MAX_RANGO_NAME_LENGTH)
|
|
164
|
+
return undefined;
|
|
165
|
+
for (let i = 0; i < name.length; i++) {
|
|
166
|
+
if (name.charCodeAt(i) > 0x7f)
|
|
167
|
+
return undefined;
|
|
168
|
+
}
|
|
169
|
+
return RANGO_NAME_TO_CHAIN_ID.get(name.trim().toUpperCase());
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=rango_chain_names.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rango_chain_names.js","sourceRoot":"","sources":["../../rango_chain_names.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"solana_chain.d.ts","sourceRoot":"","sources":["../../../solana/solana_chain.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,yBAAyB,EAEzB,UAAU,EAEV,SAAS,EAET,sBAAsB,EAEvB,MAAM,iBAAiB,CAAC;AAczB,OAAO,EACL,aAAa,EACb,KAAK,EACL,qBAAqB,EACrB,gCAAgC,EAChC,wBAAwB,EACxB,6BAA6B,EAE9B,MAAM,kBAAkB,CAAC;AAK1B,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAEL,oBAAoB,EACrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,
|
|
1
|
+
{"version":3,"file":"solana_chain.d.ts","sourceRoot":"","sources":["../../../solana/solana_chain.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,yBAAyB,EAEzB,UAAU,EAEV,SAAS,EAET,sBAAsB,EAEvB,MAAM,iBAAiB,CAAC;AAczB,OAAO,EACL,aAAa,EACb,KAAK,EACL,qBAAqB,EACrB,gCAAgC,EAChC,wBAAwB,EACxB,6BAA6B,EAE9B,MAAM,kBAAkB,CAAC;AAK1B,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAEL,oBAAoB,EACrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAIL,uBAAuB,EACxB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAE7E,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,iFAAiF;IACjF,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,oGAAoG;IACpG,wBAAwB,EAAE,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,sCAAuC,SAAQ,gCAAgC;IAC9F,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,sBAAsB,EAAE,CAAC;IACvC,mBAAmB,CAAC,EAAE,yBAAyB,EAAE,CAAC;CACnD;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,UAAU,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,4DAA4D;AAC5D,MAAM,MAAM,iBAAiB,GAAG,uBAAuB,CAAC;AAExD;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,yBAAyB,CAAC;AAEnD;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe,GAAG,yBAAyB,CAAC;AAExD,MAAM,WAAW,wBAAwB;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAsB,SAAQ,qBAAqB;IAClE;;;;OAIG;IACH,6BAA6B,CAAC,EAAE,MAAM,CAAC;IACvC,yFAAyF;IACzF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAWD;;;;;;;;;;;;;GAaG;AACH,qBAAa,WAAY,SAAQ,KAAK;IACpC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9C,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,wBAAwB,EAAE,MAAM,CAAC;IAC1C,QAAQ,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAc;IAC3C,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,YAAY,CAAK;gBAEb,IAAI,EAAE,eAAe;IA2BjC,IAAI,WAAW,IAAI,WAAW,CAE7B;IAED,aAAa,IAAI,UAAU;IAO3B;;;;;;;;;;OAUG;IACG,+BAA+B,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAc1E;;;;;;OAMG;IACH,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAInD;;;;;;;;;OASG;IACH,OAAO,CAAC,0BAA0B;YAQpB,OAAO;IAerB,OAAO,CAAC,UAAU;IAyBlB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAI7C,mBAAmB,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM;IAOrD,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAIjD,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IASrC,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO;IAKnD,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAyCpE,iCAAiC,CACrC,GAAG,EAAE,qBAAqB,GACzB,OAAO,CAAC,yBAAyB,CAAC;IA2LrC;;;;;;;;;;;OAWG;IACG,qCAAqC,CAAC,GAAG,EAAE;QAC/C,IAAI,EAAE,MAAM,CAAC;QACb,YAAY,EAAE,sBAAsB,EAAE,CAAC;QACvC,6BAA6B,CAAC,EAAE,MAAM,CAAC;QACvC,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B;;;;;WAKG;QACH,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,mBAAmB,CAAC,EAAE,yBAAyB,EAAE,CAAC;KACnD,GAAG,OAAO,CAAC,yBAAyB,CAAC;IA0FtC;;;;;;OAMG;IACG,gBAAgB,CAAC,QAAQ,EAAE,yBAAyB,GAAG,OAAO,CAAC,yBAAyB,CAAC;IAwB/F;;;;;OAKG;IACG,kBAAkB,CACtB,QAAQ,EAAE,yBAAyB,GAClC,OAAO,CAAC,yBAAyB,CAAC;IAmDrC,iGAAiG;IACjG,MAAM,CAAC,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO;IAM/C,gGAAgG;IAChG,MAAM,CAAC,uBAAuB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO;IAK/C,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,wBAAwB,GAAG,OAAO,CAAC,uBAAuB,CAAC;IACvG,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,wBAAwB,GAAG,OAAO,CAAC,uBAAuB,EAAE,CAAC;YAgBrG,qBAAqB;YAuErB,mBAAmB;IA0K3B,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;IAIpC,sBAAsB,CAAC,GAAG,EAAE,6BAA6B,GAAG,OAAO,CAAC,OAAO,CAAC;IAkB5E,kBAAkB,CACtB,UAAU,GAAE,WAAW,GAAG,WAAW,GAAG,WAAyB,GAChE,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,oBAAoB,EAAE,MAAM,CAAA;KAAE,CAAC;IAOzD,mBAAmB,CACvB,MAAM,EAAE,MAAM,GAAG,UAAU,EAC3B,IAAI,CAAC,EAAE;QACL,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,sBAAsB,CAAC,EAAE,OAAO,CAAC;QACjC,UAAU,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC;QACrD,QAAQ,CAAC,EAAE;YAAE,SAAS,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC;KACpC,GACA,OAAO,CAAC;QACT,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACtB,QAAQ,CAAC,EAAE,CAAC;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,UAAU,CAAA;SAAE,GAAG,IAAI,CAAC,EAAE,CAAC;KAC9D,CAAC;IA6EI,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG;QAAE,aAAa,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAsEzJ,gBAAgB,CAAC,SAAS,EAAE,UAAU,EAAE,EAAE,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IA2D/G,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC;IACjH,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IA4FtH,yBAAyB,CAC7B,GAAG,EAAE,sCAAsC,GAC1C,OAAO,CAAC,yBAAyB,CAAC;IA8F/B,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC;IACvE,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,uBAAuB,GAAG,IAAI,CAAC,EAAE,CAAC;IA6C9E,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,kBAAkB,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAuDxH,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,yBAAyB,CAAC;IA4BrF,OAAO,CAAC,sBAAsB;IAgD9B;;;;OAIG;IACG,qBAAqB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IAoB1D,mBAAmB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;IAM3D;;;;;;OAMG;IACH,8BAA8B,CAC5B,IAAI,EAAE,SAAS,EACf,EAAE,EAAE,SAAS,EACb,QAAQ,EAAE,MAAM,GACf,sBAAsB;IAezB;;;;;;;;;;;;OAYG;IACG,4BAA4B,CAAC,GAAG,EAAE;QACtC,IAAI,EAAE,SAAS,CAAC;QAChB,EAAE,EAAE,SAAS,CAAC;QACd,IAAI,EAAE,SAAS,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B,kBAAkB,CAAC,EAAE,OAAO,CAAC;KAC9B,GAAG,OAAO,CAAC,sBAAsB,EAAE,CAAC;IA0DrC;;;;;OAKG;IACH,qBAAqB,CACnB,EAAE,EAAE,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,GACjE,oBAAoB;CAuFxB;AAwBD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM,CAkBpE;AA2CD,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAcpD"}
|
|
@@ -7,7 +7,7 @@ import { ChainError, ChainErrorKinds, sanitizeCause, sanitizeMessage } from "../
|
|
|
7
7
|
import { NetworkType, registerNonEvmChain } from "../network_type.js";
|
|
8
8
|
import { Priority } from "../priority.js";
|
|
9
9
|
import { AssetBalanceChange, } from "../transaction_status.js";
|
|
10
|
-
import { SolanaTransactionFees, SolanaTransactionStatus, } from "./solana_transaction_status.js";
|
|
10
|
+
import { SOLANA_FINALIZED_CONFIRMATIONS, SolanaTransactionFees, SolanaTransactionStatus, } from "./solana_transaction_status.js";
|
|
11
11
|
import { SolanaAddress } from "./solana_address.js";
|
|
12
12
|
import { SolanaToken } from "./solana_token.js";
|
|
13
13
|
import { UnsignedSolanaTransaction } from "./unsigned_solana_transaction.js";
|
|
@@ -579,56 +579,85 @@ export class SolanaChain extends Chain {
|
|
|
579
579
|
catch {
|
|
580
580
|
scrubUrl = null;
|
|
581
581
|
}
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
582
|
+
// RIN-296 D1: fetch `getTransaction` and `getSignatureStatus` in
|
|
583
|
+
// parallel so the common (Success) case pays one round-trip of
|
|
584
|
+
// latency instead of two. `getSignatureStatus` populates the four
|
|
585
|
+
// new finality fields (slot / confirmations / confirmationStatus /
|
|
586
|
+
// signers) on the status; `slot` and `signers` also come from
|
|
587
|
+
// `getTransaction` when it succeeds.
|
|
588
|
+
const [txResult, sigResult] = await Promise.allSettled([
|
|
589
|
+
connection.getTransaction(txHash, {
|
|
585
590
|
commitment: 'confirmed',
|
|
586
591
|
maxSupportedTransactionVersion: 0,
|
|
587
|
-
})
|
|
588
|
-
|
|
589
|
-
|
|
592
|
+
}),
|
|
593
|
+
connection.getSignatureStatus(txHash, { searchTransactionHistory: true }),
|
|
594
|
+
]);
|
|
595
|
+
if (txResult.status === 'rejected') {
|
|
596
|
+
const err = txResult.reason;
|
|
590
597
|
const rawMsg = err instanceof Error ? err.message : String(err);
|
|
591
598
|
throw new ChainError(ChainErrorKinds.RpcError, sanitizeMessage(`Failed to read Solana tx ${txHash}: ${rawMsg}`, scrubUrl), { chainId: this.chainId, txHash }, sanitizeCause(err, scrubUrl));
|
|
592
599
|
}
|
|
600
|
+
const tx = txResult.value;
|
|
601
|
+
// RIN-296 D2: sig-status failure on the Success path degrades to
|
|
602
|
+
// `null` fields rather than throwing — a working tx read must not
|
|
603
|
+
// fail because a metadata enrichment call failed.
|
|
604
|
+
const sigValue = sigResult.status === 'fulfilled' ? (sigResult.value?.value ?? null) : null;
|
|
605
|
+
const confirmationStatus = extractSolanaConfirmationStatus(sigValue?.confirmationStatus);
|
|
606
|
+
const confirmations = normaliseSolanaConfirmations(sigValue);
|
|
593
607
|
if (!tx) {
|
|
594
|
-
// Full tx not fetchable;
|
|
595
|
-
//
|
|
596
|
-
//
|
|
597
|
-
//
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
sig = await connection.getSignatureStatus(txHash, { searchTransactionHistory: true });
|
|
601
|
-
}
|
|
602
|
-
catch (err) {
|
|
608
|
+
// Full tx not fetchable; use signature status. Consume BOTH fields
|
|
609
|
+
// (`confirmationStatus` + `err`) — always returning Pending on
|
|
610
|
+
// settled-but-unfetchable would let a settled-FAILED tx poll
|
|
611
|
+
// indefinitely.
|
|
612
|
+
if (sigResult.status === 'rejected') {
|
|
613
|
+
const err = sigResult.reason;
|
|
603
614
|
const rawMsg = err instanceof Error ? err.message : String(err);
|
|
604
615
|
throw new ChainError(ChainErrorKinds.RpcError, sanitizeMessage(`Failed to read Solana signature status ${txHash}: ${rawMsg}`, scrubUrl), { chainId: this.chainId, txHash }, sanitizeCause(err, scrubUrl));
|
|
605
616
|
}
|
|
606
|
-
if (!
|
|
617
|
+
if (!sigValue)
|
|
607
618
|
return SolanaTransactionStatus.notFound(this.chainId);
|
|
608
|
-
const
|
|
609
|
-
|
|
610
|
-
if (settled &&
|
|
611
|
-
// Fees are not reconstructable from a sig-status only — factory
|
|
612
|
-
// now accepts fees: null for exactly this case.
|
|
619
|
+
const slot = sigValue.slot ?? null;
|
|
620
|
+
const settled = confirmationStatus === 'finalized' || confirmationStatus === 'confirmed';
|
|
621
|
+
if (settled && sigValue.err) {
|
|
613
622
|
return SolanaTransactionStatus.failed({
|
|
614
623
|
chainId: this.chainId,
|
|
615
624
|
inclusionAt: null,
|
|
616
|
-
error: { code: 'REVERTED', reason: JSON.stringify(
|
|
625
|
+
error: { code: 'REVERTED', reason: JSON.stringify(sigValue.err) },
|
|
617
626
|
fees: null,
|
|
627
|
+
slot,
|
|
628
|
+
confirmations,
|
|
629
|
+
confirmationStatus,
|
|
618
630
|
});
|
|
619
631
|
}
|
|
620
632
|
// settled-Success without a fetchable body OR still propagating —
|
|
621
633
|
// keep polling. NotFound here would misreport a settled deposit.
|
|
622
|
-
|
|
634
|
+
// RIN-296 D3: pass finality through so consumers polling on
|
|
635
|
+
// Pending see the tx's position toward finality.
|
|
636
|
+
return SolanaTransactionStatus.pending(this.chainId, {
|
|
637
|
+
slot,
|
|
638
|
+
confirmations,
|
|
639
|
+
confirmationStatus,
|
|
640
|
+
});
|
|
623
641
|
}
|
|
642
|
+
// RIN-296 R2: `slot` and `signers` are read from the `getTransaction`
|
|
643
|
+
// response the SDK already fetches. `signers` = the first
|
|
644
|
+
// `numRequiredSignatures` static account keys, matching
|
|
645
|
+
// omnichain-py `signer_keys = account_keys[: header.num_required_signatures]`.
|
|
646
|
+
const slot = tx.slot;
|
|
647
|
+
const accounts = tx.transaction.message.staticAccountKeys.map((k) => k.toBase58());
|
|
648
|
+
const signers = accounts.slice(0, tx.transaction.message.header.numRequiredSignatures);
|
|
624
649
|
if (!tx.meta) {
|
|
625
650
|
// A returned tx without meta is a valid RPC response shape (some
|
|
626
651
|
// very old txs or unusual nodes). Report Pending so consumers keep
|
|
627
652
|
// polling rather than throwing from a status read; matches the
|
|
628
653
|
// _decodeBalanceChanges guard at the same file.
|
|
629
|
-
return SolanaTransactionStatus.pending(this.chainId
|
|
654
|
+
return SolanaTransactionStatus.pending(this.chainId, {
|
|
655
|
+
slot,
|
|
656
|
+
confirmations,
|
|
657
|
+
confirmationStatus,
|
|
658
|
+
signers,
|
|
659
|
+
});
|
|
630
660
|
}
|
|
631
|
-
const accounts = tx.transaction.message.staticAccountKeys.map((k) => k.toBase58());
|
|
632
661
|
const feePayer = accounts[0] ?? '';
|
|
633
662
|
if (feePayer.length === 0) {
|
|
634
663
|
throw new ChainError(ChainErrorKinds.TransactionDecodeFailed, `Solana tx ${txHash} has no fee_payer account`, { chainId: this.chainId, txHash });
|
|
@@ -651,6 +680,10 @@ export class SolanaChain extends Chain {
|
|
|
651
680
|
inclusionAt,
|
|
652
681
|
error: { code: 'REVERTED', reason: JSON.stringify(tx.meta.err) },
|
|
653
682
|
fees,
|
|
683
|
+
slot,
|
|
684
|
+
confirmations,
|
|
685
|
+
confirmationStatus,
|
|
686
|
+
signers,
|
|
654
687
|
});
|
|
655
688
|
}
|
|
656
689
|
// Wrap the decoder so a malformed uiTokenAmount.amount / pre/postBalance
|
|
@@ -671,6 +704,10 @@ export class SolanaChain extends Chain {
|
|
|
671
704
|
inclusionAt,
|
|
672
705
|
balanceChanges,
|
|
673
706
|
fees,
|
|
707
|
+
slot,
|
|
708
|
+
confirmations,
|
|
709
|
+
confirmationStatus,
|
|
710
|
+
signers,
|
|
674
711
|
});
|
|
675
712
|
}
|
|
676
713
|
async getChainTipHeight() {
|
|
@@ -1288,6 +1325,33 @@ export function signatureBase58FromBytes(txBytes) {
|
|
|
1288
1325
|
return bs58encode(sigBytes);
|
|
1289
1326
|
}
|
|
1290
1327
|
const ED25519_SPKI_PREFIX = Buffer.from('302a300506032b6570032100', 'hex');
|
|
1328
|
+
/**
|
|
1329
|
+
* Narrow `getSignatureStatuses` `confirmationStatus` (a raw string) to
|
|
1330
|
+
* the known union, falling back to `null` for unknown values so a
|
|
1331
|
+
* future upstream widening doesn't lie about the type.
|
|
1332
|
+
*/
|
|
1333
|
+
function extractSolanaConfirmationStatus(raw) {
|
|
1334
|
+
if (raw === 'processed' || raw === 'confirmed' || raw === 'finalized')
|
|
1335
|
+
return raw;
|
|
1336
|
+
return null;
|
|
1337
|
+
}
|
|
1338
|
+
/**
|
|
1339
|
+
* Normalise `getSignatureStatuses` `value.confirmations` to a monotone
|
|
1340
|
+
* count consumers can gate on. Per the RPC contract, `null` means
|
|
1341
|
+
* rooted (past `finalized`); the SDK maps that to
|
|
1342
|
+
* {@link SOLANA_FINALIZED_CONFIRMATIONS} so `confirmations >= threshold`
|
|
1343
|
+
* checks behave the way callers expect. Passing a null `sigValue`
|
|
1344
|
+
* (sig-status unavailable — a metadata-enrichment failure on the
|
|
1345
|
+
* success path) returns `null` so consumers can distinguish "unknown"
|
|
1346
|
+
* from any real count.
|
|
1347
|
+
*/
|
|
1348
|
+
function normaliseSolanaConfirmations(sigValue) {
|
|
1349
|
+
if (sigValue === null)
|
|
1350
|
+
return null;
|
|
1351
|
+
if (sigValue.confirmations !== null)
|
|
1352
|
+
return sigValue.confirmations;
|
|
1353
|
+
return SOLANA_FINALIZED_CONFIRMATIONS;
|
|
1354
|
+
}
|
|
1291
1355
|
function parseSolanaSignature(raw) {
|
|
1292
1356
|
const hexCandidate = raw.startsWith('0x') ? raw.slice(2) : raw;
|
|
1293
1357
|
if (/^[0-9a-fA-F]+$/.test(hexCandidate) && hexCandidate.length === 128) {
|