@droplinked_inc/wallet-connection 0.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 +16 -0
- package/LICENSE +21 -0
- package/README.md +142 -0
- package/THREAT_MODEL.md +180 -0
- package/dist/chains.d.ts +25 -0
- package/dist/chains.d.ts.map +1 -0
- package/dist/chains.js +153 -0
- package/dist/chains.js.map +1 -0
- package/dist/connectors/evm.d.ts +144 -0
- package/dist/connectors/evm.d.ts.map +1 -0
- package/dist/connectors/evm.js +330 -0
- package/dist/connectors/evm.js.map +1 -0
- package/dist/connectors/phantom.d.ts +167 -0
- package/dist/connectors/phantom.d.ts.map +1 -0
- package/dist/connectors/phantom.js +340 -0
- package/dist/connectors/phantom.js.map +1 -0
- package/dist/errors.d.ts +51 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +70 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +69 -0
- package/dist/index.js.map +1 -0
- package/dist/provider.d.ts +74 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +210 -0
- package/dist/provider.js.map +1 -0
- package/dist/session.d.ts +68 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +99 -0
- package/dist/session.js.map +1 -0
- package/dist/signing.d.ts +94 -0
- package/dist/signing.d.ts.map +1 -0
- package/dist/signing.js +178 -0
- package/dist/signing.js.map +1 -0
- package/dist/types.d.ts +234 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +150 -0
- package/dist/types.js.map +1 -0
- package/package.json +57 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# @droplinked_inc/wallet-connection
|
|
2
|
+
|
|
3
|
+
## 0.1.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 562318e: Initial publish of `wallet-connection` under the supply-chain rebuild sprint. Hostile-namespace replacement for `droplinked-wallet-connection`.
|
|
8
|
+
|
|
9
|
+
## 0.1.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- Initial publish. Wallet connection adapters for droplinked (MetaMask,
|
|
14
|
+
Coinbase, WalletConnect, Phantom). Hardened recover+rewrite from the
|
|
15
|
+
legacy `@droplinked/wallet-connection` source. See `README.md` and
|
|
16
|
+
`THREAT_MODEL.md` for the public surface and trust boundaries.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Droplinked Inc.
|
|
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,142 @@
|
|
|
1
|
+
# @droplinked_inc/wallet-connection
|
|
2
|
+
|
|
3
|
+
Hardened wallet-connection primitives for droplinked: MetaMask, Coinbase
|
|
4
|
+
Wallet, and Phantom. EIP-712 typed-data login with chain + origin +
|
|
5
|
+
nonce binding, zod-validated RPC boundaries, no `any`, no remote ABI
|
|
6
|
+
fetches.
|
|
7
|
+
|
|
8
|
+
This package is a clean rewrite of the original
|
|
9
|
+
`@droplinked/wallet-connection@1.0.1` (hostile-published by an external
|
|
10
|
+
actor). See `THREAT_MODEL.md` for the threat scenarios this package
|
|
11
|
+
mitigates and the test cases that exercise them.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
pnpm add @droplinked_inc/wallet-connection
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Peer-ish runtime deps:
|
|
20
|
+
|
|
21
|
+
- `viem ^2.21`
|
|
22
|
+
- `zod ^3.23`
|
|
23
|
+
|
|
24
|
+
Both are direct dependencies; you do not need to install them yourself.
|
|
25
|
+
|
|
26
|
+
## Quick start — EVM login (MetaMask)
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import {
|
|
30
|
+
EvmConnector,
|
|
31
|
+
Chain,
|
|
32
|
+
Network,
|
|
33
|
+
verifyLoginSignature,
|
|
34
|
+
buildSession,
|
|
35
|
+
saveSession,
|
|
36
|
+
} from '@droplinked_inc/wallet-connection';
|
|
37
|
+
|
|
38
|
+
const connector = new EvmConnector({
|
|
39
|
+
chain: Chain.ETH,
|
|
40
|
+
network: Network.MAINNET,
|
|
41
|
+
origin: window.location.origin,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const { address, signature } = await connector.walletLogin();
|
|
45
|
+
|
|
46
|
+
// Verify (server-side or client-side):
|
|
47
|
+
await verifyLoginSignature({
|
|
48
|
+
payload: /* the LoginPayload returned by your server */,
|
|
49
|
+
signature,
|
|
50
|
+
expectedAddress: address,
|
|
51
|
+
expectedChainId: 1,
|
|
52
|
+
expectedOrigin: window.location.origin,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
saveSession(
|
|
56
|
+
buildSession({
|
|
57
|
+
address,
|
|
58
|
+
chainId: 1,
|
|
59
|
+
origin: window.location.origin,
|
|
60
|
+
signature,
|
|
61
|
+
ttlSeconds: 60 * 60 * 8, // 8 hours
|
|
62
|
+
}),
|
|
63
|
+
);
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Quick start — Phantom (Solana) login
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import { PhantomConnector, Network } from '@droplinked_inc/wallet-connection';
|
|
70
|
+
|
|
71
|
+
const connector = new PhantomConnector(Network.MAINNET);
|
|
72
|
+
const { address, signature } = await connector.walletLogin();
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## ERC-20 transfer
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
const txHash = await connector.paymentWithToken(
|
|
79
|
+
receiverAddress,
|
|
80
|
+
1000000n, // amount as bigint
|
|
81
|
+
tokenAddress,
|
|
82
|
+
);
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Note: this issues a direct `transfer`. There is **no** `approve` API
|
|
86
|
+
exposed — drainer-style allowance flows are not reachable from this
|
|
87
|
+
package. See `THREAT_MODEL.md` §T5.
|
|
88
|
+
|
|
89
|
+
## Custom checkout calldata
|
|
90
|
+
|
|
91
|
+
The droplinked v3 checkout contract is invoked via
|
|
92
|
+
`submitRawTransaction()` with calldata produced by the droplinked
|
|
93
|
+
checkout API. The legacy direct ABI encoder is intentionally removed
|
|
94
|
+
(see `THREAT_MODEL.md` §T7 — remote ABI/address fetch was a single
|
|
95
|
+
point of supply-chain compromise).
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
const txHash = await connector.submitRawTransaction({
|
|
99
|
+
to: checkoutContractAddress,
|
|
100
|
+
data: serverProducedCalldata,
|
|
101
|
+
value: totalPriceWei,
|
|
102
|
+
gasLimit: 3_000_000n,
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Security
|
|
107
|
+
|
|
108
|
+
- All RPC responses are zod-validated. Wallets that return malformed
|
|
109
|
+
data cause a typed error, not silent corruption.
|
|
110
|
+
- Login signatures are EIP-712 typed with chain + origin + nonce +
|
|
111
|
+
issuedAt + optional expirationTime.
|
|
112
|
+
- `selectMetaMaskProvider()` and `selectCoinbaseProvider()` require the
|
|
113
|
+
wallet's own self-identification flag. There is no fallback to the
|
|
114
|
+
umbrella `window.ethereum`.
|
|
115
|
+
- Nonces use `crypto.getRandomValues()` (256 bits). If Web Crypto is
|
|
116
|
+
unavailable the call throws — there is no `Math.random()` fallback.
|
|
117
|
+
- Sessions default to `sessionStorage` (cleared on tab close), not
|
|
118
|
+
`localStorage`. They carry an explicit `expiresAt` that
|
|
119
|
+
`loadSession()` enforces.
|
|
120
|
+
|
|
121
|
+
See `THREAT_MODEL.md` for the full delta vs. the original v1.0.1 and
|
|
122
|
+
the tests that exercise each scenario.
|
|
123
|
+
|
|
124
|
+
## Status
|
|
125
|
+
|
|
126
|
+
Initial recover + harden. The original public API names are preserved
|
|
127
|
+
where feasible; the following changes are deliberate and noted in
|
|
128
|
+
`THREAT_MODEL.md`:
|
|
129
|
+
|
|
130
|
+
- Chain/Network/ChainWallet are now string-valued enums (was implicit-
|
|
131
|
+
numeric).
|
|
132
|
+
- `getNetworkProvider(chain, network, address, wallet)` is now
|
|
133
|
+
`getNetworkProvider({ chain, network, address, wallet, ... })`.
|
|
134
|
+
- `EVMProvider` is now `EvmConnector`; `SolanaProvider` is now
|
|
135
|
+
`PhantomConnector` (constructor signatures changed accordingly).
|
|
136
|
+
- `EVMPayment` (the free function) is removed; use
|
|
137
|
+
`EvmConnector.submitRawTransaction()`.
|
|
138
|
+
- Error classes now extend `Error` (regression-fixes try/catch).
|
|
139
|
+
|
|
140
|
+
## License
|
|
141
|
+
|
|
142
|
+
MIT.
|
package/THREAT_MODEL.md
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Threat Model — @droplinked_inc/wallet-connection
|
|
2
|
+
|
|
3
|
+
This document enumerates the wallet-specific threats the package is built
|
|
4
|
+
to mitigate, the design decisions taken in response, and the test cases
|
|
5
|
+
that exercise each scenario.
|
|
6
|
+
|
|
7
|
+
The starting point is a hardened rewrite of the original
|
|
8
|
+
`@droplinked/wallet-connection@1.0.1` package (hostile-published by an
|
|
9
|
+
external actor). The original is presumed compromised; behavior is not
|
|
10
|
+
trusted, only the recovered TypeScript source is used as a feature
|
|
11
|
+
reference. Every behavior carried forward was reviewed.
|
|
12
|
+
|
|
13
|
+
## Scope
|
|
14
|
+
|
|
15
|
+
In-scope: connection, signature, and routing primitives shipped by this
|
|
16
|
+
package. Out-of-scope: backend session storage, JWT issuance, payment-
|
|
17
|
+
intent reconciliation — those belong to neighboring packages.
|
|
18
|
+
|
|
19
|
+
## Threats and mitigations
|
|
20
|
+
|
|
21
|
+
### T1 — Forged signature presentation
|
|
22
|
+
|
|
23
|
+
**Scenario.** An attacker presents a signature obtained out-of-band (a
|
|
24
|
+
leak from another origin's database, a phishing site that captured a
|
|
25
|
+
sign) and tries to authenticate as the owning address.
|
|
26
|
+
|
|
27
|
+
**Mitigation.** All login signatures are EIP-712 typed data with an
|
|
28
|
+
explicit `chainId`, `domain` (host), `nonce`, and `issuedAt` field. The
|
|
29
|
+
server (or `verifyLoginSignature` client-side) refuses a signature when
|
|
30
|
+
any of these mismatch the expected values. The original v1.0.1 used a
|
|
31
|
+
`personal_sign` of a static plaintext that had none of these bindings.
|
|
32
|
+
|
|
33
|
+
**Test.** `signing.test.ts → 'tampered payload (different address) rejected'`.
|
|
34
|
+
|
|
35
|
+
### T2 — Cross-chain replay
|
|
36
|
+
|
|
37
|
+
**Scenario.** A signature obtained on chain X is replayed against the
|
|
38
|
+
server when the user thinks they're acting on chain Y. The droplinked
|
|
39
|
+
checkout contract reads a `chainLinkRoundId` so cross-chain replay can
|
|
40
|
+
mis-price an order.
|
|
41
|
+
|
|
42
|
+
**Mitigation.** `chainId` is bound into both the EIP-712 domain *and*
|
|
43
|
+
the typed message. `verifyLoginSignature` rejects with
|
|
44
|
+
`ChainMismatchError` if the payload's chainId disagrees with what the
|
|
45
|
+
server expected for that route.
|
|
46
|
+
|
|
47
|
+
**Test.** `signing.test.ts → 'cross-chain replay refused'`.
|
|
48
|
+
|
|
49
|
+
### T3 — Origin spoofing on `eth_requestAccounts`
|
|
50
|
+
|
|
51
|
+
**Scenario.** A subdomain or partner site impersonates the droplinked
|
|
52
|
+
origin, captures a signed login payload, and replays it against the
|
|
53
|
+
real droplinked backend.
|
|
54
|
+
|
|
55
|
+
**Mitigation.** The signed payload's `domain` field is set to
|
|
56
|
+
`new URL(origin).host` at build time and re-verified against the
|
|
57
|
+
expected origin host using constant-time comparison. `OriginMismatchError`
|
|
58
|
+
is thrown on disagreement.
|
|
59
|
+
|
|
60
|
+
**Test.** `signing.test.ts → 'origin spoofing refused'`.
|
|
61
|
+
|
|
62
|
+
### T4 — Phishing via deceptive wallet popups
|
|
63
|
+
|
|
64
|
+
**Scenario.** A page running multiple wallets injects `window.ethereum`
|
|
65
|
+
with `isMetaMask=true` to impersonate MetaMask and steal a sign.
|
|
66
|
+
|
|
67
|
+
**Mitigation.** `selectMetaMaskProvider()` walks the legacy
|
|
68
|
+
`ethereum.providers` array if present and only accepts the entry whose
|
|
69
|
+
`isMetaMask` flag is set. There is no fallback to the umbrella
|
|
70
|
+
`window.ethereum`. We never call `window.open('https://phantom.app/')`
|
|
71
|
+
on the user's behalf — the original v1.0.1 did, opening a side-channel
|
|
72
|
+
for tab-redirect attacks.
|
|
73
|
+
|
|
74
|
+
**Test.** `provider.test.ts → 'selectMetaMaskProvider rejects impersonation'`
|
|
75
|
+
and `phantom.test.ts → 'throws when isPhantom is false (impersonation)'`.
|
|
76
|
+
|
|
77
|
+
### T5 — Drainer-style approve-all-tokens attacks
|
|
78
|
+
|
|
79
|
+
**Scenario.** A malicious wrapper convinces the user to issue an
|
|
80
|
+
`approve(spender, uint256.max)` against an ERC-20, letting the spender
|
|
81
|
+
drain the token at any future time.
|
|
82
|
+
|
|
83
|
+
**Mitigation.** The package exposes `paymentWithToken(receiver, amount,
|
|
84
|
+
token)` which issues a direct `transfer(receiver, amount)`. There is no
|
|
85
|
+
`approve` API. Callers that need allowance-based flows must use a
|
|
86
|
+
specialized package (out of scope here) so the dangerous primitive is
|
|
87
|
+
not casually reachable. `submitRawTransaction()` is the escape hatch for
|
|
88
|
+
server-built calldata — callers explicitly opt in.
|
|
89
|
+
|
|
90
|
+
**Test.** `evm.test.ts → 'encodeErc20Transfer produces correct calldata'`
|
|
91
|
+
verifies the selector is `0xa9059cbb` (`transfer`) and not `0x095ea7b3`
|
|
92
|
+
(`approve`).
|
|
93
|
+
|
|
94
|
+
### T6 — Hardware wallet ledger-state desync (popup loop)
|
|
95
|
+
|
|
96
|
+
**Scenario.** The original v1.0.1 `handleWallet` method recursively
|
|
97
|
+
called itself after each `wallet_requestPermissions` rejection. On a
|
|
98
|
+
Ledger that has gone to sleep, this spins an infinite popup loop the
|
|
99
|
+
user cannot escape.
|
|
100
|
+
|
|
101
|
+
**Mitigation.** The new `EvmConnector.handleWallet` is iterative with a
|
|
102
|
+
hard bound of 3 attempts, after which `AccountChangedException` is
|
|
103
|
+
thrown. No recursive self-call.
|
|
104
|
+
|
|
105
|
+
**Test.** `evm.test.ts → 'handleWallet does NOT recurse forever on
|
|
106
|
+
persistent account mismatch'`.
|
|
107
|
+
|
|
108
|
+
### T7 — Supply-chain compromise via remote ABI/address fetch
|
|
109
|
+
|
|
110
|
+
**Scenario.** The original v1.0.1 fetched the on-chain contract address
|
|
111
|
+
from `https://apiv3dev.droplinked.com/storage/<chain><network>ContractAddress`
|
|
112
|
+
at every payment. Anyone who compromises that endpoint (DNS hijack,
|
|
113
|
+
storage write, internal-CI compromise, or — historically — a hostile
|
|
114
|
+
npm publisher who can also touch that endpoint) can redirect every
|
|
115
|
+
customer payment to an attacker's address.
|
|
116
|
+
|
|
117
|
+
**Mitigation.** Remote address discovery is fully removed.
|
|
118
|
+
`EvmConnector.payment()` requires `checkoutContractAddress` at
|
|
119
|
+
construction time. The legacy direct ABI encode path is intentionally
|
|
120
|
+
disabled in favor of `submitRawTransaction()` with server-built
|
|
121
|
+
calldata, so the address validation lives behind the backend's signed
|
|
122
|
+
order.
|
|
123
|
+
|
|
124
|
+
**Test.** `evm.test.ts → "payment() refuses without contract address
|
|
125
|
+
(no remote fetch)"`.
|
|
126
|
+
|
|
127
|
+
### T8 — Session reuse after wallet rotation
|
|
128
|
+
|
|
129
|
+
**Scenario.** A user signs in, the page caches the session in
|
|
130
|
+
`localStorage`, the user disconnects/changes their wallet — the cached
|
|
131
|
+
session can be replayed by a later visitor on a shared device.
|
|
132
|
+
|
|
133
|
+
**Mitigation.** Sessions default to `sessionStorage` (cleared on tab
|
|
134
|
+
close), are zod-validated on read, and carry an `expiresAt` that
|
|
135
|
+
`loadSession` enforces. Corrupt or expired blobs are scrubbed on read.
|
|
136
|
+
|
|
137
|
+
**Test.** `session.test.ts → 'expired session is dropped on load'` and
|
|
138
|
+
`'corrupt JSON drops session'`.
|
|
139
|
+
|
|
140
|
+
### T9 — Nonce predictability
|
|
141
|
+
|
|
142
|
+
**Scenario.** A weak PRNG produces predictable nonces, allowing a
|
|
143
|
+
replay window where the attacker can pre-compute a server-acceptable
|
|
144
|
+
nonce.
|
|
145
|
+
|
|
146
|
+
**Mitigation.** `generateNonce()` uses `crypto.getRandomValues()` with
|
|
147
|
+
256 bits of entropy. If Web Crypto is unavailable we throw — no fallback
|
|
148
|
+
to `Math.random()`.
|
|
149
|
+
|
|
150
|
+
**Test.** `signing.test.ts → 'generateNonce produces unique url-safe
|
|
151
|
+
strings'` and the property test `'nonce always url-safe and unique
|
|
152
|
+
within batch'`.
|
|
153
|
+
|
|
154
|
+
### T10 — Error swallowed in framework error boundaries
|
|
155
|
+
|
|
156
|
+
**Scenario.** The original v1.0.1 error classes did not extend `Error`.
|
|
157
|
+
React error boundaries and Node uncaughtException handlers would not
|
|
158
|
+
match them, so wallet errors silently slipped through to incorrect
|
|
159
|
+
"success" states.
|
|
160
|
+
|
|
161
|
+
**Mitigation.** All error classes extend a common
|
|
162
|
+
`WalletConnectionError` which extends native `Error`. Stack traces and
|
|
163
|
+
`instanceof` both work.
|
|
164
|
+
|
|
165
|
+
**Test.** `errors.test.ts → 'errors propagate through try/catch
|
|
166
|
+
(regression: v1.0.1 did not extend Error)'`.
|
|
167
|
+
|
|
168
|
+
## Out of scope (tracked for follow-ups)
|
|
169
|
+
|
|
170
|
+
- WalletConnect v2 connector — placeholder factory exposed; needs a
|
|
171
|
+
dedicated Reown/AppKit integration PR.
|
|
172
|
+
- Solana SPL token transfer — the original v1.0.1 used the deprecated
|
|
173
|
+
`@solana/spl-token` v0.1 Token-class API. Re-implementing against
|
|
174
|
+
v0.4 is queued separately so this PR can land clean.
|
|
175
|
+
- Sui connector — listed in the package description; no recovered
|
|
176
|
+
source exists. Will land in a follow-up.
|
|
177
|
+
- Ledger device address-confirmation prompts — out of scope until the
|
|
178
|
+
WalletConnect path lands.
|
|
179
|
+
- Server-side signature verification rate limiting / per-IP brute force
|
|
180
|
+
controls — backend concern.
|
package/dist/chains.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chain metadata. Read-only registry that powers chain-add/chain-switch
|
|
3
|
+
* RPC calls. No remote fetches — the original v1.0.1 reached out to
|
|
4
|
+
* `apiv3dev.droplinked.com/storage/...` to discover contract addresses,
|
|
5
|
+
* which is a supply-chain vulnerability (any compromise of that endpoint
|
|
6
|
+
* could redirect every customer payment to an attacker address). The new
|
|
7
|
+
* design takes contract addresses as explicit caller-provided arguments.
|
|
8
|
+
*/
|
|
9
|
+
import { Chain, Network } from './types.js';
|
|
10
|
+
export interface ChainMetadata {
|
|
11
|
+
readonly chainName: string;
|
|
12
|
+
/** 0x-hex chainId, e.g. "0x89". */
|
|
13
|
+
readonly chainIdHex: `0x${string}`;
|
|
14
|
+
/** Decimal chainId for EIP-712 / viem. */
|
|
15
|
+
readonly chainIdNumber: number;
|
|
16
|
+
readonly nativeCurrency: {
|
|
17
|
+
name: string;
|
|
18
|
+
decimals: number;
|
|
19
|
+
symbol: string;
|
|
20
|
+
};
|
|
21
|
+
readonly rpcUrls: readonly string[];
|
|
22
|
+
}
|
|
23
|
+
export declare function getChainMetadata(chain: Chain, network: Network): ChainMetadata;
|
|
24
|
+
export declare function hasChainMetadata(chain: Chain, network: Network): boolean;
|
|
25
|
+
//# sourceMappingURL=chains.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chains.d.ts","sourceRoot":"","sources":["../src/chains.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG5C,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,mCAAmC;IACnC,QAAQ,CAAC,UAAU,EAAE,KAAK,MAAM,EAAE,CAAC;IACnC,0CAA0C;IAC1C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,cAAc,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5E,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAsID,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,GAAG,aAAa,CAS9E;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAExE"}
|
package/dist/chains.js
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chain metadata. Read-only registry that powers chain-add/chain-switch
|
|
3
|
+
* RPC calls. No remote fetches — the original v1.0.1 reached out to
|
|
4
|
+
* `apiv3dev.droplinked.com/storage/...` to discover contract addresses,
|
|
5
|
+
* which is a supply-chain vulnerability (any compromise of that endpoint
|
|
6
|
+
* could redirect every customer payment to an attacker address). The new
|
|
7
|
+
* design takes contract addresses as explicit caller-provided arguments.
|
|
8
|
+
*/
|
|
9
|
+
import { Chain, Network } from './types.js';
|
|
10
|
+
import { ChainNotImplementedException } from './errors.js';
|
|
11
|
+
const CHAIN_TABLE = {
|
|
12
|
+
[Chain.BINANCE]: {
|
|
13
|
+
[Network.TESTNET]: {
|
|
14
|
+
chainName: 'Smart Chain - Testnet',
|
|
15
|
+
chainIdHex: '0x61',
|
|
16
|
+
chainIdNumber: 97,
|
|
17
|
+
nativeCurrency: { name: 'BNB', decimals: 18, symbol: 'BNB' },
|
|
18
|
+
rpcUrls: ['https://data-seed-prebsc-1-s1.binance.org:8545/'],
|
|
19
|
+
},
|
|
20
|
+
[Network.MAINNET]: {
|
|
21
|
+
chainName: 'Smart Chain',
|
|
22
|
+
chainIdHex: '0x38',
|
|
23
|
+
chainIdNumber: 56,
|
|
24
|
+
nativeCurrency: { name: 'BNB', decimals: 18, symbol: 'BNB' },
|
|
25
|
+
rpcUrls: ['https://bsc-dataseed.binance.org/'],
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
[Chain.POLYGON]: {
|
|
29
|
+
[Network.TESTNET]: {
|
|
30
|
+
chainName: 'Polygon Amoy',
|
|
31
|
+
chainIdHex: '0x13882',
|
|
32
|
+
chainIdNumber: 80002,
|
|
33
|
+
nativeCurrency: { name: 'MATIC', decimals: 18, symbol: 'MATIC' },
|
|
34
|
+
rpcUrls: ['https://rpc-amoy.polygon.technology'],
|
|
35
|
+
},
|
|
36
|
+
[Network.MAINNET]: {
|
|
37
|
+
chainName: 'Polygon Mainnet',
|
|
38
|
+
chainIdHex: '0x89',
|
|
39
|
+
chainIdNumber: 137,
|
|
40
|
+
nativeCurrency: { name: 'MATIC', decimals: 18, symbol: 'MATIC' },
|
|
41
|
+
rpcUrls: ['https://polygon-rpc.com/'],
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
[Chain.BASE]: {
|
|
45
|
+
[Network.TESTNET]: {
|
|
46
|
+
chainName: 'Base Sepolia',
|
|
47
|
+
chainIdHex: '0x14a34',
|
|
48
|
+
chainIdNumber: 84532,
|
|
49
|
+
nativeCurrency: { name: 'ETH', decimals: 18, symbol: 'ETH' },
|
|
50
|
+
rpcUrls: ['https://sepolia.base.org'],
|
|
51
|
+
},
|
|
52
|
+
[Network.MAINNET]: {
|
|
53
|
+
chainName: 'Base Mainnet',
|
|
54
|
+
chainIdHex: '0x2105',
|
|
55
|
+
chainIdNumber: 8453,
|
|
56
|
+
nativeCurrency: { name: 'ETH', decimals: 18, symbol: 'ETH' },
|
|
57
|
+
rpcUrls: ['https://mainnet.base.org/'],
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
[Chain.LINEA]: {
|
|
61
|
+
[Network.MAINNET]: {
|
|
62
|
+
chainName: 'Linea',
|
|
63
|
+
chainIdHex: '0xe708',
|
|
64
|
+
chainIdNumber: 59144,
|
|
65
|
+
nativeCurrency: { name: 'ETH', decimals: 18, symbol: 'LineaETH' },
|
|
66
|
+
rpcUrls: ['https://rpc.linea.build'],
|
|
67
|
+
},
|
|
68
|
+
[Network.TESTNET]: {
|
|
69
|
+
chainName: 'Linea Sepolia',
|
|
70
|
+
chainIdHex: '0xe705',
|
|
71
|
+
chainIdNumber: 59141,
|
|
72
|
+
nativeCurrency: { name: 'ETH', decimals: 18, symbol: 'LineaETH' },
|
|
73
|
+
rpcUrls: ['https://rpc.sepolia.linea.build'],
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
[Chain.ETH]: {
|
|
77
|
+
[Network.MAINNET]: {
|
|
78
|
+
chainName: 'Ethereum',
|
|
79
|
+
chainIdHex: '0x1',
|
|
80
|
+
chainIdNumber: 1,
|
|
81
|
+
nativeCurrency: { name: 'ETH', decimals: 18, symbol: 'ETH' },
|
|
82
|
+
rpcUrls: ['https://eth.llamarpc.com'],
|
|
83
|
+
},
|
|
84
|
+
[Network.TESTNET]: {
|
|
85
|
+
chainName: 'Sepolia',
|
|
86
|
+
chainIdHex: '0xaa36a7',
|
|
87
|
+
chainIdNumber: 11155111,
|
|
88
|
+
nativeCurrency: { name: 'ETH', decimals: 18, symbol: 'ETH' },
|
|
89
|
+
rpcUrls: ['https://eth-sepolia.public.blastapi.io/'],
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
[Chain.NEAR]: {
|
|
93
|
+
[Network.TESTNET]: {
|
|
94
|
+
chainName: 'Aurora Testnet',
|
|
95
|
+
chainIdHex: '0x4e454153',
|
|
96
|
+
chainIdNumber: 1313161555,
|
|
97
|
+
nativeCurrency: { name: 'ETH', decimals: 18, symbol: 'ETH' },
|
|
98
|
+
rpcUrls: ['https://testnet.aurora.dev'],
|
|
99
|
+
},
|
|
100
|
+
[Network.MAINNET]: {
|
|
101
|
+
chainName: 'Aurora Mainnet',
|
|
102
|
+
chainIdHex: '0x4e454152',
|
|
103
|
+
chainIdNumber: 1313161554,
|
|
104
|
+
nativeCurrency: { name: 'ETH', decimals: 18, symbol: 'ETH' },
|
|
105
|
+
rpcUrls: ['https://mainnet.aurora.dev'],
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
[Chain.XRPLSIDECHAIN]: {
|
|
109
|
+
[Network.TESTNET]: {
|
|
110
|
+
chainName: 'XRPL EVM Sidechain',
|
|
111
|
+
chainIdHex: '0x15f902',
|
|
112
|
+
chainIdNumber: 1440002,
|
|
113
|
+
nativeCurrency: { name: 'XRP', decimals: 18, symbol: 'XRP' },
|
|
114
|
+
rpcUrls: ['https://rpc-evm-sidechain.xrpl.org'],
|
|
115
|
+
},
|
|
116
|
+
[Network.MAINNET]: {
|
|
117
|
+
chainName: 'XRPL EVM Sidechain',
|
|
118
|
+
chainIdHex: '0x15f902',
|
|
119
|
+
chainIdNumber: 1440002,
|
|
120
|
+
nativeCurrency: { name: 'XRP', decimals: 18, symbol: 'XRP' },
|
|
121
|
+
rpcUrls: ['https://rpc-evm-sidechain.xrpl.org'],
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
[Chain.SKALE]: {
|
|
125
|
+
[Network.TESTNET]: {
|
|
126
|
+
chainName: 'SKALE Calypso Testnet',
|
|
127
|
+
chainIdHex: '0x3a14269b',
|
|
128
|
+
chainIdNumber: 974399131,
|
|
129
|
+
nativeCurrency: { name: 'sFUEL', decimals: 18, symbol: 'sFUEL' },
|
|
130
|
+
rpcUrls: ['https://testnet.skalenodes.com/v1/giant-half-dual-testnet'],
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
[Chain.STACKS]: {
|
|
134
|
+
// Stacks is not EVM. The original v1.0.1 stuffed BSC metadata in here.
|
|
135
|
+
// We intentionally leave this empty — Stacks integration requires a
|
|
136
|
+
// separate native-protocol connector, not EVM RPC tricks.
|
|
137
|
+
},
|
|
138
|
+
[Chain.SOLANA]: {
|
|
139
|
+
// Solana is not EVM. Handled by SolanaProvider, not by this table.
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
export function getChainMetadata(chain, network) {
|
|
143
|
+
const networkTable = CHAIN_TABLE[chain];
|
|
144
|
+
const meta = networkTable[network];
|
|
145
|
+
if (meta === undefined) {
|
|
146
|
+
throw new ChainNotImplementedException(`Chain ${chain} on network ${network} is not implemented`);
|
|
147
|
+
}
|
|
148
|
+
return meta;
|
|
149
|
+
}
|
|
150
|
+
export function hasChainMetadata(chain, network) {
|
|
151
|
+
return CHAIN_TABLE[chain][network] !== undefined;
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=chains.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chains.js","sourceRoot":"","sources":["../src/chains.ts"],"names":[],"mappings":"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"}
|