@usebutr/polkadot 1.0.1 → 1.1.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/dist/index.d.ts +19 -51
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +82 -84
- package/dist/index.js.map +1 -1
- package/package.json +3 -4
package/dist/index.d.ts
CHANGED
|
@@ -38,10 +38,9 @@ type WalletStandardPolkadotCapabilityInput = {
|
|
|
38
38
|
};
|
|
39
39
|
};
|
|
40
40
|
/**
|
|
41
|
-
* injectedWeb3
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* because injectedWeb3 wallets advertise no chains of their own.
|
|
41
|
+
* injectedWeb3 always exposes `signer.signRaw` and `accounts.subscribe`, so
|
|
42
|
+
* those flags are unconditional. The chain count comes from butr's own
|
|
43
|
+
* registry because injectedWeb3 wallets advertise no chains.
|
|
45
44
|
*/
|
|
46
45
|
declare const resolveInjectedPolkadotCapabilities: () => WalletCapabilities;
|
|
47
46
|
/**
|
|
@@ -53,11 +52,9 @@ declare const resolveWalletStandardPolkadotCapabilities: (input: WalletStandardP
|
|
|
53
52
|
//#endregion
|
|
54
53
|
//#region src/injected/injected-web3.d.ts
|
|
55
54
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* `@polkadot/extension-inject
|
|
59
|
-
* posture as `@usebutr/bitcoin`'s `UnisatProvider`. These narrow the
|
|
60
|
-
* spec to only the fields butr reads.
|
|
55
|
+
* Local narrowing of the `@polkadot/extension-dapp` injectedWeb3 standard
|
|
56
|
+
* to the fields butr reads, so the connector takes no dependency on
|
|
57
|
+
* `@polkadot/extension-inject`.
|
|
61
58
|
*/
|
|
62
59
|
/** A single account the extension exposes. Addresses are SS58; accounts
|
|
63
60
|
* are chain-agnostic across Substrate. */
|
|
@@ -107,13 +104,8 @@ type PolkadotSignerHandle = {
|
|
|
107
104
|
extensionName: string;
|
|
108
105
|
};
|
|
109
106
|
/**
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
* `enable()` triggers the authorization prompt, so it runs lazily in
|
|
113
|
-
* `connect()`. Before connect, `getAccount` returns null.
|
|
114
|
-
*
|
|
115
|
-
* `id` is `injected:polkadot:<slug>` so consumers can distinguish the
|
|
116
|
-
* injected channel from the Wallet Standard one in their picker.
|
|
107
|
+
* The provider is not enabled at construction: `enable()` raises the
|
|
108
|
+
* extension's authorization prompt, so it runs lazily in `connect()`.
|
|
117
109
|
*/
|
|
118
110
|
declare const buildInjectedPolkadotAdapter: (extensionName: string, displayName: string, provider: InjectedWindowProvider) => PolkadotAdapter;
|
|
119
111
|
//#endregion
|
|
@@ -126,13 +118,9 @@ type InjectedPolkadotDiscoveryOptions = {
|
|
|
126
118
|
target?: InjectedWindow | null;
|
|
127
119
|
};
|
|
128
120
|
/**
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
* lazily.
|
|
133
|
-
*
|
|
134
|
-
* Extensions inject at different times during page load, so we read
|
|
135
|
-
* immediately and re-check on a short poll schedule, deduping by key.
|
|
121
|
+
* Adapters are built without calling `enable()`, which would raise the
|
|
122
|
+
* extension's authorization prompt at discovery time. Extensions inject at
|
|
123
|
+
* different points during page load, hence the poll schedule.
|
|
136
124
|
*/
|
|
137
125
|
declare const discoverInjectedPolkadotAdapters: (onAdapter: (adapter: WalletAdapter) => void, options?: InjectedPolkadotDiscoveryOptions) => (() => void);
|
|
138
126
|
//#endregion
|
|
@@ -150,50 +138,30 @@ type PolkadotSignMessageFeature = {
|
|
|
150
138
|
};
|
|
151
139
|
//#endregion
|
|
152
140
|
//#region src/wallet-standard-adapter.d.ts
|
|
153
|
-
/**
|
|
154
|
-
* Adapt a Wallet Standard wallet advertising `polkadot:*` features into a
|
|
155
|
-
* butr `WalletAdapter`. Returns `null` for wallets that don't advertise a
|
|
156
|
-
* polkadot chain or `standard:connect`. butr ships no RPC, so
|
|
157
|
-
* sendTx/getBalance/getTransactionReceipt are placeholders; transaction
|
|
158
|
-
* signing goes through `getSigner()` (returns the Wallet Standard wallet).
|
|
159
|
-
*/
|
|
160
141
|
declare const buildPolkadotWalletStandardAdapter: (wallet: WalletStandardWallet,
|
|
161
142
|
/** Optional. Called with a function that pushes a synthetic
|
|
162
143
|
* `disconnected` event to all current subscribers. The discovery
|
|
163
144
|
* layer invokes it on Wallet Standard `unregister`. */
|
|
164
145
|
registerDisconnector?: (emit: () => void) => void) => WalletAdapter | null;
|
|
165
146
|
/**
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
* as the FALLBACK channel; see `polkadotDiscoverer`. Requires the
|
|
169
|
-
* optional `@wallet-standard/app` peer dep; absent → no-op.
|
|
147
|
+
* The fallback channel; see `polkadotDiscoverer`. Requires the optional
|
|
148
|
+
* `@wallet-standard/app` peer dep and no-ops without it.
|
|
170
149
|
*/
|
|
171
150
|
declare const discoverPolkadotWalletStandardAdapters: (onAdapter: (adapter: WalletAdapter) => void) => (() => void);
|
|
172
151
|
//#endregion
|
|
173
152
|
//#region src/discoverer.d.ts
|
|
174
153
|
/**
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
* - FALLBACK is Wallet Standard `polkadot:*`. It defers when the primary
|
|
179
|
-
* channel already produced an adapter for the session
|
|
180
|
-
* (`hasAnyPrimaryAdapter`). Since Wallet Standard support is always
|
|
181
|
-
* additive on Polkadot today (Talisman/SubWallet expose both), the
|
|
182
|
-
* discovery-bus also dedups overlaps and the defer prevents
|
|
183
|
-
* double-listing.
|
|
154
|
+
* Primary is injectedWeb3; Wallet Standard `polkadot:*` is the fallback. Its
|
|
155
|
+
* defer is the only thing preventing double-listing: a wallet on both
|
|
156
|
+
* channels mints two unrelated ids the discovery bus cannot collapse.
|
|
184
157
|
*/
|
|
185
158
|
declare const polkadotDiscoverer: PlatformDiscoverer;
|
|
186
159
|
//#endregion
|
|
187
160
|
//#region src/signer-augmentation.d.ts
|
|
188
161
|
/**
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
* the
|
|
192
|
-
* - injectedWeb3 (primary) → `PolkadotSignerHandle` (`extensionName` +
|
|
193
|
-
* `address` + `extension`). Bridge to polkadot-api via
|
|
194
|
-
* `connectInjectedExtension(extensionName)`.
|
|
195
|
-
* - Wallet Standard (fallback) → the `WalletStandardWallet`, narrowed by
|
|
196
|
-
* the consumer via its `features` map.
|
|
162
|
+
* The `getSigner()` shape depends on the discovery channel: injectedWeb3
|
|
163
|
+
* yields a `PolkadotSignerHandle` to bridge into polkadot-api's
|
|
164
|
+
* `connectInjectedExtension`, Wallet Standard yields the raw wallet.
|
|
197
165
|
*/
|
|
198
166
|
declare module "@usebutr/core" {
|
|
199
167
|
interface SignerForPlatform {
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/chains.ts","../src/capabilities.ts","../src/injected/injected-web3.ts","../src/injected/adapter.ts","../src/injected/index.ts","../src/wallet-standard-types.ts","../src/wallet-standard-adapter.ts","../src/discoverer.ts","../src/signer-augmentation.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/chains.ts","../src/capabilities.ts","../src/injected/injected-web3.ts","../src/injected/adapter.ts","../src/injected/index.ts","../src/wallet-standard-types.ts","../src/wallet-standard-adapter.ts","../src/discoverer.ts","../src/signer-augmentation.ts"],"mappings":";;;cAEM;;;;;;;;;;;;;;;;;;;;;;;;;;cA2BA,sBAAsB,cAAc;;;KCxBrC;EACH;EACA;IACE;IACA;;;;;;;;cASE,2CAA0C;;;;;;cAe1C,4CACJ,OAAO,0CACN;;;;;;;;;;KC3BE;EACH;EACA;EACA;EACA;;;;KAKG;EACH,WAAW;IACT;IACA;IACA;QACI;IAAU;IAAY;;;;KAIzB;EACH;IACE,WAAW,QAAQ,cAAc;IACjC,aAAa,KAAK,UAAU,cAAc;;EAE5C,QAAQ;;;KAIL;EACH,SAAS,mBAAmB,QAAQ;EACpC;;KAGG;EACH,eAAe,eAAe;;;;;;;;KClB3B;EACH;EACA,WAAW;EACX;;;;;;cAiCI,+BACJ,uBACA,qBACA,UAAU,2BACT;;;KC1CE;;;EAGH,SAAS;;EAET,SAAS;;;;;;;cAUL,mCACJ,YAAY,SAAS,wBACrB,UAAS;;;KC/BN;EACH,SAAS;EACT,SAAS;;KAGN;EACH,WAAW;EACX,gBAAgB;;KAGb;EACH,cAAc,OAAO,6BAA6B,QAAQ;;;;cCAtD,qCACJ,QAAQ,sBAIR;;;;AAAA,wBAAwB,8BACvB;;;;;cAmDG,yCACJ,YAAY,SAAS;;;;;;;;cClEjB,oBAAoB;;;;;;;;;YCCd;IACR,UAAU,uBAAuB"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { buildWalletCapabilities, createWalletStandardCore, discoverWalletStandard, getFeature, slugify } from "@usebutr/wallet-standard-shared";
|
|
2
|
-
import { bytesToHexPrefixed as bytesToHex, hexToBytes, sanitizeIcon } from "@usebutr/core";
|
|
2
|
+
import { bytesToHexPrefixed as bytesToHex, hexToBytes, logWarn, sanitizeIcon } from "@usebutr/core";
|
|
3
3
|
|
|
4
4
|
//#region src/chains.ts
|
|
5
5
|
const POLKADOT_CHAINS = {
|
|
@@ -29,14 +29,18 @@ const POLKADOT_CHAINS = {
|
|
|
29
29
|
}
|
|
30
30
|
};
|
|
31
31
|
const POLKADOT_CHAINS_LIST = Object.values(POLKADOT_CHAINS);
|
|
32
|
+
const POLKADOT_CHAIN_BY_ID = new Map(POLKADOT_CHAINS_LIST.map((chain) => [chain.id, chain]));
|
|
33
|
+
/** Chains a wallet advertising several networks should resolve to first.
|
|
34
|
+
* Kusama sits alongside Polkadot because it carries real value; Westend
|
|
35
|
+
* and Paseo are faucet testnets and must never win the default. */
|
|
36
|
+
const POLKADOT_MAINNET_IDS = [POLKADOT_CHAINS.polkadot.id, POLKADOT_CHAINS.kusama.id];
|
|
32
37
|
|
|
33
38
|
//#endregion
|
|
34
39
|
//#region src/capabilities.ts
|
|
35
40
|
/**
|
|
36
|
-
* injectedWeb3
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* because injectedWeb3 wallets advertise no chains of their own.
|
|
41
|
+
* injectedWeb3 always exposes `signer.signRaw` and `accounts.subscribe`, so
|
|
42
|
+
* those flags are unconditional. The chain count comes from butr's own
|
|
43
|
+
* registry because injectedWeb3 wallets advertise no chains.
|
|
40
44
|
*/
|
|
41
45
|
const resolveInjectedPolkadotCapabilities = () => buildWalletCapabilities({
|
|
42
46
|
chainCount: POLKADOT_CHAINS_LIST.length,
|
|
@@ -63,13 +67,9 @@ const resolveWalletStandardPolkadotCapabilities = (input) => buildWalletCapabili
|
|
|
63
67
|
//#endregion
|
|
64
68
|
//#region src/no-rpc.ts
|
|
65
69
|
/**
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* `capabilities.getBalance` / `getTransactionReceipt === false`);
|
|
70
|
-
* transaction submission rejects with a hint to drive polkadot-api via
|
|
71
|
-
* `getSigner()`. Both discovery channels (injectedWeb3 + Wallet Standard)
|
|
72
|
-
* share these so the invariant lives in one place.
|
|
70
|
+
* Building an extrinsic or reading on-chain state both need chain metadata
|
|
71
|
+
* butr doesn't fetch, so it ships no Polkadot RPC. The neutral balance and
|
|
72
|
+
* receipt values are gated behind the matching `capabilities` flags.
|
|
73
73
|
*/
|
|
74
74
|
const POLKADOT_SEND_TX_HINT = "Polkadot sendTx is unsupported: use getSigner() with polkadot-api to build and submit extrinsics";
|
|
75
75
|
const POLKADOT_SEND_TX_TO_CHAIN_HINT = "Polkadot sendTxToChain is unsupported: use getSigner() with polkadot-api to build and submit extrinsics";
|
|
@@ -108,15 +108,9 @@ const readInjectedWindow = (target) => {
|
|
|
108
108
|
//#region src/injected/adapter.ts
|
|
109
109
|
const DAPP_NAME = "butr";
|
|
110
110
|
/**
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
* injected Polkadot channel prefix.
|
|
115
|
-
*
|
|
116
|
-
* This is intentionally NOT the wallet-standard-shared `slugify` helper;
|
|
117
|
-
* that helper embeds the `wallet-standard:` scheme which is wrong for
|
|
118
|
-
* the injected channel. The ID convention for injected adapters is
|
|
119
|
-
* `injected:polkadot:<slug>`.
|
|
111
|
+
* Deliberately not wallet-standard-shared's `slugify`: that helper embeds
|
|
112
|
+
* the `wallet-standard:` scheme, while injected adapter ids follow the
|
|
113
|
+
* `injected:polkadot:<slug>` convention.
|
|
120
114
|
*/
|
|
121
115
|
const toKebab = (name) => name.trim().toLowerCase().replaceAll(new RegExp("[^a-z0-9]+", "gv"), "-").replaceAll(new RegExp("^-|-$", "gv"), "");
|
|
122
116
|
const buildPolkadotAccount = (address, chain) => ({
|
|
@@ -125,36 +119,73 @@ const buildPolkadotAccount = (address, chain) => ({
|
|
|
125
119
|
walletAddress: address
|
|
126
120
|
});
|
|
127
121
|
/**
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
* `enable()` triggers the authorization prompt, so it runs lazily in
|
|
131
|
-
* `connect()`. Before connect, `getAccount` returns null.
|
|
132
|
-
*
|
|
133
|
-
* `id` is `injected:polkadot:<slug>` so consumers can distinguish the
|
|
134
|
-
* injected channel from the Wallet Standard one in their picker.
|
|
122
|
+
* The provider is not enabled at construction: `enable()` raises the
|
|
123
|
+
* extension's authorization prompt, so it runs lazily in `connect()`.
|
|
135
124
|
*/
|
|
136
125
|
const buildInjectedPolkadotAdapter = (extensionName, displayName, provider) => {
|
|
137
126
|
const capabilities = resolveInjectedPolkadotCapabilities();
|
|
138
|
-
let
|
|
127
|
+
let session = null;
|
|
139
128
|
let chain = POLKADOT_CHAINS.polkadot;
|
|
140
129
|
const listenersSet = /* @__PURE__ */ new Set();
|
|
130
|
+
const emit = (event) => {
|
|
131
|
+
const snapshot = [...listenersSet];
|
|
132
|
+
for (const listener of snapshot) listener(event);
|
|
133
|
+
};
|
|
134
|
+
const emitAccounts = (accounts) => {
|
|
135
|
+
const built = accounts.map((a) => buildPolkadotAccount(a.address, chain));
|
|
136
|
+
const first = built[0];
|
|
137
|
+
if (first !== void 0) emit({
|
|
138
|
+
account: first,
|
|
139
|
+
accounts: built,
|
|
140
|
+
type: "accountChanged"
|
|
141
|
+
});
|
|
142
|
+
};
|
|
143
|
+
const closeSession = () => {
|
|
144
|
+
session?.unsubscribe?.();
|
|
145
|
+
session = null;
|
|
146
|
+
};
|
|
147
|
+
const handleWalletAccounts = (accounts) => {
|
|
148
|
+
if (accounts.length === 0) {
|
|
149
|
+
closeSession();
|
|
150
|
+
emit({ type: "disconnected" });
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
emitAccounts(accounts);
|
|
154
|
+
};
|
|
155
|
+
const openSession = (injected) => {
|
|
156
|
+
closeSession();
|
|
157
|
+
const opened = {
|
|
158
|
+
injected,
|
|
159
|
+
unsubscribe: null
|
|
160
|
+
};
|
|
161
|
+
session = opened;
|
|
162
|
+
try {
|
|
163
|
+
const unsubscribe = injected.accounts.subscribe?.(handleWalletAccounts);
|
|
164
|
+
if (unsubscribe === void 0) return;
|
|
165
|
+
if (session === opened) opened.unsubscribe = unsubscribe;
|
|
166
|
+
else unsubscribe();
|
|
167
|
+
} catch (error) {
|
|
168
|
+
logWarn(`[butr/polkadot] ${displayName} accounts.subscribe threw:`, error);
|
|
169
|
+
}
|
|
170
|
+
};
|
|
141
171
|
const requireInjected = () => {
|
|
142
|
-
if (
|
|
143
|
-
return injected;
|
|
172
|
+
if (session === null) throw new Error(`Wallet ${displayName} is not connected`);
|
|
173
|
+
return session.injected;
|
|
144
174
|
};
|
|
145
175
|
const firstAddress = async () => {
|
|
146
|
-
if (
|
|
147
|
-
return (await injected.accounts.get())[0]?.address ?? null;
|
|
176
|
+
if (session === null) return null;
|
|
177
|
+
return (await session.injected.accounts.get())[0]?.address ?? null;
|
|
148
178
|
};
|
|
149
179
|
return {
|
|
150
180
|
capabilities,
|
|
151
181
|
chainPlatform: "polkadot",
|
|
152
182
|
async connect() {
|
|
153
|
-
injected = await provider.enable(DAPP_NAME);
|
|
183
|
+
const injected = await provider.enable(DAPP_NAME);
|
|
154
184
|
if ((await injected.accounts.get()).length === 0) throw new Error(`Wallet ${displayName} exposed no accounts`);
|
|
185
|
+
openSession(injected);
|
|
155
186
|
},
|
|
156
187
|
disconnect: () => {
|
|
157
|
-
|
|
188
|
+
closeSession();
|
|
158
189
|
return Promise.resolve();
|
|
159
190
|
},
|
|
160
191
|
async getAccount() {
|
|
@@ -162,8 +193,8 @@ const buildInjectedPolkadotAdapter = (extensionName, displayName, provider) => {
|
|
|
162
193
|
return address === null ? null : buildPolkadotAccount(address, chain);
|
|
163
194
|
},
|
|
164
195
|
async getAccounts() {
|
|
165
|
-
if (
|
|
166
|
-
return (await injected.accounts.get()).map((a) => buildPolkadotAccount(a.address, chain));
|
|
196
|
+
if (session === null) return [];
|
|
197
|
+
return (await session.injected.accounts.get()).map((a) => buildPolkadotAccount(a.address, chain));
|
|
167
198
|
},
|
|
168
199
|
getBalance: noRpcBalance,
|
|
169
200
|
async getSigner() {
|
|
@@ -200,29 +231,15 @@ const buildInjectedPolkadotAdapter = (extensionName, displayName, provider) => {
|
|
|
200
231
|
},
|
|
201
232
|
subscribe(listener) {
|
|
202
233
|
listenersSet.add(listener);
|
|
203
|
-
let unsubWallet = null;
|
|
204
|
-
if (injected?.accounts.subscribe) unsubWallet = injected.accounts.subscribe((accounts) => {
|
|
205
|
-
if (accounts.length === 0) {
|
|
206
|
-
listener({ type: "disconnected" });
|
|
207
|
-
return;
|
|
208
|
-
}
|
|
209
|
-
const built = accounts.map((a) => buildPolkadotAccount(a.address, chain));
|
|
210
|
-
const first = built[0];
|
|
211
|
-
if (first !== void 0) listener({
|
|
212
|
-
account: first,
|
|
213
|
-
accounts: built,
|
|
214
|
-
type: "accountChanged"
|
|
215
|
-
});
|
|
216
|
-
});
|
|
217
234
|
return () => {
|
|
218
235
|
listenersSet.delete(listener);
|
|
219
|
-
unsubWallet?.();
|
|
220
236
|
};
|
|
221
237
|
},
|
|
222
|
-
switchChain
|
|
223
|
-
if (target.namespace !== "polkadot")
|
|
224
|
-
chain = target;
|
|
225
|
-
|
|
238
|
+
async switchChain(target) {
|
|
239
|
+
if (target.namespace !== "polkadot") throw new Error(`Polkadot adapter received non-Polkadot chain "${target.id}". Pass a chain with namespace "polkadot".`);
|
|
240
|
+
chain = POLKADOT_CHAIN_BY_ID.get(target.id) ?? target;
|
|
241
|
+
if (session === null) return;
|
|
242
|
+
emitAccounts(await session.injected.accounts.get());
|
|
226
243
|
}
|
|
227
244
|
};
|
|
228
245
|
};
|
|
@@ -239,13 +256,9 @@ const KNOWN_NAMES = {
|
|
|
239
256
|
const displayNameFor = (key) => KNOWN_NAMES[key] ?? key.split(new RegExp("[\\-_]", "v")).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
|
|
240
257
|
const DEFAULT_POLLS = [250, 750];
|
|
241
258
|
/**
|
|
242
|
-
*
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
* lazily.
|
|
246
|
-
*
|
|
247
|
-
* Extensions inject at different times during page load, so we read
|
|
248
|
-
* immediately and re-check on a short poll schedule, deduping by key.
|
|
259
|
+
* Adapters are built without calling `enable()`, which would raise the
|
|
260
|
+
* extension's authorization prompt at discovery time. Extensions inject at
|
|
261
|
+
* different points during page load, hence the poll schedule.
|
|
249
262
|
*/
|
|
250
263
|
const discoverInjectedPolkadotAdapters = (onAdapter, options = {}) => {
|
|
251
264
|
const polls = options.pollMs ?? DEFAULT_POLLS;
|
|
@@ -277,13 +290,6 @@ const discoverInjectedPolkadotAdapters = (onAdapter, options = {}) => {
|
|
|
277
290
|
//#region src/wallet-standard-adapter.ts
|
|
278
291
|
const POLKADOT_PREFIX = "polkadot:";
|
|
279
292
|
const slugify$1 = (name) => slugify("polkadot", name);
|
|
280
|
-
/**
|
|
281
|
-
* Adapt a Wallet Standard wallet advertising `polkadot:*` features into a
|
|
282
|
-
* butr `WalletAdapter`. Returns `null` for wallets that don't advertise a
|
|
283
|
-
* polkadot chain or `standard:connect`. butr ships no RPC, so
|
|
284
|
-
* sendTx/getBalance/getTransactionReceipt are placeholders; transaction
|
|
285
|
-
* signing goes through `getSigner()` (returns the Wallet Standard wallet).
|
|
286
|
-
*/
|
|
287
293
|
const buildPolkadotWalletStandardAdapter = (wallet, registerDisconnector) => {
|
|
288
294
|
const core = createWalletStandardCore({
|
|
289
295
|
chainPrefix: POLKADOT_PREFIX,
|
|
@@ -291,7 +297,7 @@ const buildPolkadotWalletStandardAdapter = (wallet, registerDisconnector) => {
|
|
|
291
297
|
label: "Polkadot",
|
|
292
298
|
namespace: "polkadot",
|
|
293
299
|
platform: "Polkadot",
|
|
294
|
-
preferredChainIds:
|
|
300
|
+
preferredChainIds: POLKADOT_MAINNET_IDS,
|
|
295
301
|
registerDisconnector,
|
|
296
302
|
trackChainChanges: false,
|
|
297
303
|
wallet
|
|
@@ -326,25 +332,17 @@ const buildPolkadotWalletStandardAdapter = (wallet, registerDisconnector) => {
|
|
|
326
332
|
};
|
|
327
333
|
};
|
|
328
334
|
/**
|
|
329
|
-
*
|
|
330
|
-
*
|
|
331
|
-
* as the FALLBACK channel; see `polkadotDiscoverer`. Requires the
|
|
332
|
-
* optional `@wallet-standard/app` peer dep; absent → no-op.
|
|
335
|
+
* The fallback channel; see `polkadotDiscoverer`. Requires the optional
|
|
336
|
+
* `@wallet-standard/app` peer dep and no-ops without it.
|
|
333
337
|
*/
|
|
334
338
|
const discoverPolkadotWalletStandardAdapters = (onAdapter) => discoverWalletStandard(onAdapter, (wallet, registerDisconnector) => buildPolkadotWalletStandardAdapter(wallet, registerDisconnector));
|
|
335
339
|
|
|
336
340
|
//#endregion
|
|
337
341
|
//#region src/discoverer.ts
|
|
338
342
|
/**
|
|
339
|
-
*
|
|
340
|
-
*
|
|
341
|
-
*
|
|
342
|
-
* - FALLBACK is Wallet Standard `polkadot:*`. It defers when the primary
|
|
343
|
-
* channel already produced an adapter for the session
|
|
344
|
-
* (`hasAnyPrimaryAdapter`). Since Wallet Standard support is always
|
|
345
|
-
* additive on Polkadot today (Talisman/SubWallet expose both), the
|
|
346
|
-
* discovery-bus also dedups overlaps and the defer prevents
|
|
347
|
-
* double-listing.
|
|
343
|
+
* Primary is injectedWeb3; Wallet Standard `polkadot:*` is the fallback. Its
|
|
344
|
+
* defer is the only thing preventing double-listing: a wallet on both
|
|
345
|
+
* channels mints two unrelated ids the discovery bus cannot collapse.
|
|
348
346
|
*/
|
|
349
347
|
const polkadotDiscoverer = {
|
|
350
348
|
fallback: { subscribe: (onAdapter, opts) => {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["slugify","kitSlugify"],"sources":["../src/chains.ts","../src/capabilities.ts","../src/no-rpc.ts","../src/injected/icon.ts","../src/injected/injected-web3.ts","../src/injected/adapter.ts","../src/injected/index.ts","../src/wallet-standard-adapter.ts","../src/discoverer.ts"],"sourcesContent":["import type { ChainBase } from \"@usebutr/core\";\n\n// CAIP-2 for Polkadot is `polkadot:{first-32-hex-of-genesis-hash}`.\n// injectedWeb3 doesn't advertise chains (accounts are chain-agnostic\n// across Substrate), so this registry is butr-authored. Wallet Standard\n// polkadot wallets advertise these same CAIP-2 ids.\nconst POLKADOT_CHAINS = {\n kusama: {\n id: \"polkadot:b0a8d493285c2df73290dfb7e61f870f\",\n name: \"Kusama\",\n namespace: \"polkadot\",\n reference: \"b0a8d493285c2df73290dfb7e61f870f\",\n },\n paseo: {\n id: \"polkadot:77afd6190f1554ad45fd0d31aee62aac\",\n name: \"Paseo\",\n namespace: \"polkadot\",\n reference: \"77afd6190f1554ad45fd0d31aee62aac\",\n },\n polkadot: {\n id: \"polkadot:91b171bb158e2d3848fa23a9f1c25182\",\n name: \"Polkadot\",\n namespace: \"polkadot\",\n reference: \"91b171bb158e2d3848fa23a9f1c25182\",\n },\n westend: {\n id: \"polkadot:e143f23803ac50e8f6f8e62695d1ce9e\",\n name: \"Westend\",\n namespace: \"polkadot\",\n reference: \"e143f23803ac50e8f6f8e62695d1ce9e\",\n },\n} as const satisfies Record<string, ChainBase>;\n\nconst POLKADOT_CHAINS_LIST: ReadonlyArray<ChainBase> = Object.values(POLKADOT_CHAINS);\n\nexport { POLKADOT_CHAINS, POLKADOT_CHAINS_LIST };\n","import type { WalletCapabilities } from \"@usebutr/core\";\nimport { buildWalletCapabilities } from \"@usebutr/wallet-standard-shared\";\n\nimport { POLKADOT_CHAINS_LIST } from \"./chains\";\n\ntype WalletStandardPolkadotCapabilityInput = {\n chainCount: number;\n features: {\n events: boolean;\n signMessage: boolean;\n };\n};\n\n/**\n * injectedWeb3 capability profile. The injected `signer.signRaw` always\n * supports message signing and `accounts.subscribe` always supports events,\n * so both are unconditional. The chain count comes from butr's own registry\n * because injectedWeb3 wallets advertise no chains of their own.\n */\nconst resolveInjectedPolkadotCapabilities = (): WalletCapabilities =>\n buildWalletCapabilities({\n chainCount: POLKADOT_CHAINS_LIST.length,\n events: true,\n sendTransaction: false,\n signIn: false,\n signMessage: true,\n signTransaction: false,\n });\n\n/**\n * Wallet Standard `polkadot:*` feature → butr capability mapping. No\n * standalone `signTransaction`: building an extrinsic needs chain metadata\n * butr doesn't fetch, so transaction signing goes through `getSigner()`.\n */\nconst resolveWalletStandardPolkadotCapabilities = (\n input: WalletStandardPolkadotCapabilityInput,\n): WalletCapabilities =>\n buildWalletCapabilities({\n chainCount: input.chainCount,\n events: input.features.events,\n sendTransaction: false,\n signIn: false,\n signMessage: input.features.signMessage,\n signTransaction: false,\n });\n\nexport type { WalletStandardPolkadotCapabilityInput };\nexport { resolveInjectedPolkadotCapabilities, resolveWalletStandardPolkadotCapabilities };\n","import type { Balance } from \"@usebutr/core\";\n\n/**\n * butr ships no RPC on Polkadot: building/broadcasting an extrinsic and\n * reading on-chain state both need chain metadata. Balance and receipt\n * reads return neutral placeholders (gated behind\n * `capabilities.getBalance` / `getTransactionReceipt === false`);\n * transaction submission rejects with a hint to drive polkadot-api via\n * `getSigner()`. Both discovery channels (injectedWeb3 + Wallet Standard)\n * share these so the invariant lives in one place.\n */\nconst POLKADOT_SEND_TX_HINT =\n \"Polkadot sendTx is unsupported: use getSigner() with polkadot-api to build and submit extrinsics\";\nconst POLKADOT_SEND_TX_TO_CHAIN_HINT =\n \"Polkadot sendTxToChain is unsupported: use getSigner() with polkadot-api to build and submit extrinsics\";\n\nconst noRpcBalance = (): Promise<Balance> =>\n Promise.resolve({ decimals: 0, formatted: \"0\", symbol: \"\", value: 0n });\n\nconst noRpcTransactionReceipt = (): Promise<{ status: \"Success\" | \"Error\" | \"Pending\" }> =>\n Promise.resolve({ status: \"Pending\" });\n\nconst noRpcSendTx = (): Promise<string> => Promise.reject(new Error(POLKADOT_SEND_TX_HINT));\n\nconst noRpcSendTxToChain = (): Promise<string> =>\n Promise.reject(new Error(POLKADOT_SEND_TX_TO_CHAIN_HINT));\n\nexport { noRpcBalance, noRpcSendTx, noRpcSendTxToChain, noRpcTransactionReceipt };\n","const GENERIC_POLKADOT_ICON =\n \"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiI+PGNpcmNsZSBjeD0iMTYiIGN5PSIxNiIgcj0iMTYiIGZpbGw9IiNFNjAwN0EiLz48L3N2Zz4=\";\n\nexport { GENERIC_POLKADOT_ICON };\n","/**\n * Minimal local types for the `@polkadot/extension-dapp` injectedWeb3\n * standard. Declared here (rather than depending on\n * `@polkadot/extension-inject`) so the connector stays lean; same\n * posture as `@usebutr/bitcoin`'s `UnisatProvider`. These narrow the\n * spec to only the fields butr reads.\n */\n\n/** A single account the extension exposes. Addresses are SS58; accounts\n * are chain-agnostic across Substrate. */\ntype InjectedAccount = {\n address: string;\n genesisHash?: string | null;\n name?: string;\n type?: string;\n};\n\n/** The polkadot-js `Signer`: butr only uses `signRaw` for message\n * signing. `signPayload` is consumer territory (via polkadot-api). */\ntype InjectedSigner = {\n signRaw?: (raw: {\n address: string;\n data: string;\n type: \"bytes\" | \"payload\";\n }) => Promise<{ id: number; signature: string }>;\n};\n\n/** The object returned by `enable()`. */\ntype Injected = {\n accounts: {\n get: () => Promise<ReadonlyArray<InjectedAccount>>;\n subscribe?: (cb: (accounts: ReadonlyArray<InjectedAccount>) => void) => () => void;\n };\n signer: InjectedSigner;\n};\n\n/** What lives at `window.injectedWeb3[key]`. */\ntype InjectedWindowProvider = {\n enable: (origin: string) => Promise<Injected>;\n version?: string;\n};\n\ntype InjectedWindow = {\n injectedWeb3?: Record<string, InjectedWindowProvider>;\n};\n\nconst BYTES_PREFIX = new TextEncoder().encode(\"<Bytes>\");\nconst BYTES_SUFFIX = new TextEncoder().encode(\"</Bytes>\");\n\nconst wrapBytes = (message: Uint8Array): Uint8Array => {\n const out = new Uint8Array(BYTES_PREFIX.length + message.length + BYTES_SUFFIX.length);\n out.set(BYTES_PREFIX, 0);\n out.set(message, BYTES_PREFIX.length);\n out.set(BYTES_SUFFIX, BYTES_PREFIX.length + message.length);\n return out;\n};\n\nconst readInjectedWindow = (target?: InjectedWindow | null): InjectedWindow | null => {\n if (target !== undefined) {\n return target;\n }\n if (typeof window === \"undefined\") {\n return null;\n }\n // `window.injectedWeb3` is the untyped Polkadot extension registry; the\n // DOM lib doesn't declare it, so this boundary assertion is unavoidable.\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- untyped window.injectedWeb3 extension registry\n return window as unknown as InjectedWindow;\n};\n\nexport type { Injected, InjectedAccount, InjectedSigner, InjectedWindow, InjectedWindowProvider };\nexport { bytesToHexPrefixed as bytesToHex, hexToBytes } from \"@usebutr/core\";\nexport { readInjectedWindow, wrapBytes };\n","import type {\n Account,\n ChainBase,\n ConnectorEvent,\n PolkadotAdapter,\n WalletCapabilities,\n} from \"@usebutr/core\";\nimport { sanitizeIcon } from \"@usebutr/core\";\n\nimport { resolveInjectedPolkadotCapabilities } from \"../capabilities\";\nimport { POLKADOT_CHAINS } from \"../chains\";\nimport { noRpcBalance, noRpcSendTx, noRpcSendTxToChain, noRpcTransactionReceipt } from \"../no-rpc\";\n\nimport { GENERIC_POLKADOT_ICON } from \"./icon\";\nimport type { Injected, InjectedWindowProvider } from \"./injected-web3\";\nimport { bytesToHex, hexToBytes, wrapBytes } from \"./injected-web3\";\n\nconst DAPP_NAME = \"butr\";\n\n/** Handle returned by `getSigner()`. Carries the `window.injectedWeb3`\n * key (`extensionName`) so consumers can bridge to polkadot-api's\n * `connectInjectedExtension`, the active SS58 address, and the raw\n * `Injected` object for direct `signer` access. */\ntype PolkadotSignerHandle = {\n address: string;\n extension: Injected;\n extensionName: string;\n};\n\n/**\n * Convert a wallet display name into a stable kebab-case slug for the\n * injected adapter id. Strips anything that isn't a lowercase letter or\n * digit (turning \"Polkadot{.js}\" → \"polkadot-js\"), then prepends the\n * injected Polkadot channel prefix.\n *\n * This is intentionally NOT the wallet-standard-shared `slugify` helper;\n * that helper embeds the `wallet-standard:` scheme which is wrong for\n * the injected channel. The ID convention for injected adapters is\n * `injected:polkadot:<slug>`.\n */\nconst toKebab = (name: string): string =>\n name\n .trim()\n .toLowerCase()\n .replaceAll(/[^a-z0-9]+/gv, \"-\")\n .replaceAll(/^-|-$/gv, \"\");\n\nconst buildPolkadotAccount = (address: string, chain: ChainBase): Account => ({\n chain,\n id: `${chain.id}:${address}`,\n walletAddress: address,\n});\n\n/**\n * Wrap a `window.injectedWeb3[name]` provider into a butr\n * `PolkadotAdapter`. The provider is NOT enabled at construction;\n * `enable()` triggers the authorization prompt, so it runs lazily in\n * `connect()`. Before connect, `getAccount` returns null.\n *\n * `id` is `injected:polkadot:<slug>` so consumers can distinguish the\n * injected channel from the Wallet Standard one in their picker.\n */\nconst buildInjectedPolkadotAdapter = (\n extensionName: string,\n displayName: string,\n provider: InjectedWindowProvider,\n): PolkadotAdapter => {\n const capabilities: WalletCapabilities = resolveInjectedPolkadotCapabilities();\n let injected: Injected | null = null;\n let chain: ChainBase = POLKADOT_CHAINS.polkadot;\n const listenersSet = new Set<(event: ConnectorEvent) => void>();\n\n const requireInjected = (): Injected => {\n if (injected === null) {\n throw new Error(`Wallet ${displayName} is not connected`);\n }\n return injected;\n };\n\n const firstAddress = async (): Promise<string | null> => {\n if (injected === null) {\n return null;\n }\n const accounts = await injected.accounts.get();\n return accounts[0]?.address ?? null;\n };\n\n return {\n capabilities,\n chainPlatform: \"polkadot\",\n\n async connect() {\n injected = await provider.enable(DAPP_NAME);\n const accounts = await injected.accounts.get();\n if (accounts.length === 0) {\n throw new Error(`Wallet ${displayName} exposed no accounts`);\n }\n },\n\n disconnect: () => {\n injected = null;\n return Promise.resolve();\n },\n\n async getAccount() {\n const address = await firstAddress();\n return address === null ? null : buildPolkadotAccount(address, chain);\n },\n\n async getAccounts() {\n if (injected === null) {\n return [];\n }\n const accounts = await injected.accounts.get();\n return accounts.map((a) => buildPolkadotAccount(a.address, chain));\n },\n\n getBalance: noRpcBalance,\n\n async getSigner() {\n const ext = requireInjected();\n const address = await firstAddress();\n if (address === null) {\n throw new Error(\"No connected account\");\n }\n const handle: PolkadotSignerHandle = { address, extension: ext, extensionName };\n return handle;\n },\n\n getTransactionReceipt: noRpcTransactionReceipt,\n\n icon: sanitizeIcon(GENERIC_POLKADOT_ICON),\n id: `injected:polkadot:${toKebab(extensionName)}`,\n name: displayName,\n\n sendTx: noRpcSendTx,\n\n sendTxToChain: noRpcSendTxToChain,\n\n async signMessage(msg, account) {\n const ext = requireInjected();\n if (ext.signer.signRaw === undefined) {\n throw new Error(`Wallet ${displayName} does not expose signRaw`);\n }\n const address = account?.walletAddress ?? (await firstAddress());\n if (address === null || address === \"\") {\n throw new Error(\"No connected account\");\n }\n const wrapped = wrapBytes(msg);\n const result = await ext.signer.signRaw({\n address,\n data: bytesToHex(wrapped),\n type: \"bytes\",\n });\n return { signature: hexToBytes(result.signature), signedMessage: wrapped };\n },\n\n subscribe(listener) {\n listenersSet.add(listener);\n let unsubWallet: (() => void) | null = null;\n if (injected?.accounts.subscribe) {\n unsubWallet = injected.accounts.subscribe((accounts) => {\n if (accounts.length === 0) {\n listener({ type: \"disconnected\" });\n return;\n }\n const built = accounts.map((a) => buildPolkadotAccount(a.address, chain));\n const first = built[0];\n if (first !== undefined) {\n listener({ account: first, accounts: built, type: \"accountChanged\" });\n }\n });\n }\n return () => {\n listenersSet.delete(listener);\n unsubWallet?.();\n };\n },\n\n switchChain: (target) => {\n if (target.namespace !== \"polkadot\") {\n return Promise.reject(\n new Error(\n `Polkadot adapter received non-Polkadot chain \"${target.id}\". Pass a chain with namespace \"polkadot\".`,\n ),\n );\n }\n chain = target;\n return Promise.resolve();\n },\n };\n};\n\nexport type { PolkadotSignerHandle };\nexport { buildInjectedPolkadotAdapter };\n","import type { WalletAdapter } from \"@usebutr/core\";\n\nimport { buildInjectedPolkadotAdapter } from \"./adapter\";\nimport type { InjectedWindow } from \"./injected-web3\";\nimport { readInjectedWindow } from \"./injected-web3\";\n\nconst KNOWN_NAMES: Readonly<Record<string, string>> = {\n enkrypt: \"Enkrypt\",\n \"nova-wallet\": \"Nova Wallet\",\n \"polkadot-js\": \"Polkadot{.js}\",\n \"subwallet-js\": \"SubWallet\",\n talisman: \"Talisman\",\n};\n\nconst displayNameFor = (key: string): string =>\n KNOWN_NAMES[key] ??\n key\n .split(/[\\-_]/v)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(\" \");\n\ntype InjectedPolkadotDiscoveryOptions = {\n /** Poll schedule (ms offsets) for late-injecting extensions. Defaults\n * to a few short polls; pass `[]` in tests for a single sync read. */\n pollMs?: ReadonlyArray<number>;\n /** Override the global host (tests, iframes). */\n target?: InjectedWindow | null;\n};\n\nconst DEFAULT_POLLS: ReadonlyArray<number> = [250, 750];\n\n/**\n * Primary Polkadot discovery: enumerate `window.injectedWeb3` keys and\n * emit one `PolkadotAdapter` per extension. Adapters are built WITHOUT\n * calling `enable()` (no prompt at discovery time); `connect()` enables\n * lazily.\n *\n * Extensions inject at different times during page load, so we read\n * immediately and re-check on a short poll schedule, deduping by key.\n */\nconst discoverInjectedPolkadotAdapters = (\n onAdapter: (adapter: WalletAdapter) => void,\n options: InjectedPolkadotDiscoveryOptions = {},\n): (() => void) => {\n const polls = options.pollMs ?? DEFAULT_POLLS;\n const seen = new Set<string>();\n const timers: Array<ReturnType<typeof setTimeout>> = [];\n let cancelled = false;\n\n const scan = () => {\n if (cancelled) {\n return;\n }\n const host = readInjectedWindow(options.target);\n const registry = host?.injectedWeb3;\n if (!registry) {\n return;\n }\n for (const [key, provider] of Object.entries(registry)) {\n if (seen.has(key)) {\n continue;\n }\n seen.add(key);\n onAdapter(buildInjectedPolkadotAdapter(key, displayNameFor(key), provider));\n }\n };\n\n // Always do one synchronous read so tests (and fast extensions) don't\n // wait for a timer.\n scan();\n for (const offset of polls) {\n if (offset === 0) {\n continue;\n }\n timers.push(setTimeout(scan, offset));\n }\n\n return () => {\n cancelled = true;\n for (const timer of timers) {\n clearTimeout(timer);\n }\n };\n};\n\nexport type { InjectedPolkadotDiscoveryOptions };\nexport { discoverInjectedPolkadotAdapters };\n","import type { WalletAdapter } from \"@usebutr/core\";\nimport {\n createWalletStandardCore,\n discoverWalletStandard,\n getFeature,\n slugify as kitSlugify,\n} from \"@usebutr/wallet-standard-shared\";\nimport type { WalletStandardWallet } from \"@usebutr/wallet-standard-shared\";\n\nimport { resolveWalletStandardPolkadotCapabilities } from \"./capabilities\";\nimport { noRpcBalance, noRpcSendTx, noRpcSendTxToChain, noRpcTransactionReceipt } from \"./no-rpc\";\nimport type { PolkadotSignMessageFeature } from \"./wallet-standard-types\";\n\nconst POLKADOT_PREFIX = \"polkadot:\";\n\nconst slugify = (name: string): string => kitSlugify(\"polkadot\", name);\n\n/**\n * Adapt a Wallet Standard wallet advertising `polkadot:*` features into a\n * butr `WalletAdapter`. Returns `null` for wallets that don't advertise a\n * polkadot chain or `standard:connect`. butr ships no RPC, so\n * sendTx/getBalance/getTransactionReceipt are placeholders; transaction\n * signing goes through `getSigner()` (returns the Wallet Standard wallet).\n */\nconst buildPolkadotWalletStandardAdapter = (\n wallet: WalletStandardWallet,\n /** Optional. Called with a function that pushes a synthetic\n * `disconnected` event to all current subscribers. The discovery\n * layer invokes it on Wallet Standard `unregister`. */\n registerDisconnector?: (emit: () => void) => void,\n): WalletAdapter | null => {\n const core = createWalletStandardCore({\n chainPrefix: POLKADOT_PREFIX,\n id: slugify(wallet.name),\n label: \"Polkadot\",\n namespace: \"polkadot\",\n platform: \"Polkadot\",\n preferredChainIds: [],\n registerDisconnector,\n // Polkadot wallets advertise a single relay chain, so a wallet-side\n // `chains` change has no better chain to move to.\n trackChainChanges: false,\n wallet,\n });\n if (core === null) {\n return null;\n }\n\n const signMessage = getFeature<PolkadotSignMessageFeature>(wallet, \"polkadot:signMessage\");\n\n return {\n ...core,\n capabilities: resolveWalletStandardPolkadotCapabilities({\n chainCount: core.chainCount,\n features: { events: core.hasEvents, signMessage: Boolean(signMessage) },\n }),\n chainPlatform: \"polkadot\",\n\n getBalance: noRpcBalance,\n\n getTransactionReceipt: noRpcTransactionReceipt,\n\n sendTx: noRpcSendTx,\n\n sendTxToChain: noRpcSendTxToChain,\n\n async signMessage(msg, account) {\n if (signMessage === undefined) {\n throw new Error(`Wallet ${wallet.name} does not advertise polkadot:signMessage`);\n }\n const output = await signMessage.signMessage({\n account: core.resolveAccount(account),\n message: msg,\n });\n return { signature: output.signature, signedMessage: output.signedMessage ?? msg };\n },\n };\n};\n\n/**\n * Subscribe to Wallet Standard announcements and emit adapters for\n * wallets advertising `polkadot:*` features (Talisman, SubWallet). Used\n * as the FALLBACK channel; see `polkadotDiscoverer`. Requires the\n * optional `@wallet-standard/app` peer dep; absent → no-op.\n */\nconst discoverPolkadotWalletStandardAdapters = (\n onAdapter: (adapter: WalletAdapter) => void,\n): (() => void) =>\n discoverWalletStandard(onAdapter, (wallet, registerDisconnector) =>\n buildPolkadotWalletStandardAdapter(wallet, registerDisconnector),\n );\n\nexport { buildPolkadotWalletStandardAdapter, discoverPolkadotWalletStandardAdapters };\n","import type { PlatformDiscoverer } from \"@usebutr/core\";\n\nimport { discoverInjectedPolkadotAdapters } from \"./injected\";\nimport { discoverPolkadotWalletStandardAdapters } from \"./wallet-standard-adapter\";\n\n/**\n * Polkadot's `PlatformDiscoverer`. Inverts the Bitcoin layout:\n * - PRIMARY (`subscribe`) is injectedWeb3; the dominant, broadest\n * Polkadot standard (polkadot-js, Talisman, SubWallet, Nova, Enkrypt).\n * - FALLBACK is Wallet Standard `polkadot:*`. It defers when the primary\n * channel already produced an adapter for the session\n * (`hasAnyPrimaryAdapter`). Since Wallet Standard support is always\n * additive on Polkadot today (Talisman/SubWallet expose both), the\n * discovery-bus also dedups overlaps and the defer prevents\n * double-listing.\n */\nconst polkadotDiscoverer: PlatformDiscoverer = {\n fallback: {\n subscribe: (onAdapter, opts) => {\n // Defer entirely when injected discovery has already surfaced a\n // wallet; no Polkadot wallet is Wallet-Standard-only today.\n if (opts.hasAnyPrimaryAdapter()) {\n return () => undefined;\n }\n return discoverPolkadotWalletStandardAdapters(onAdapter);\n },\n },\n subscribe: discoverInjectedPolkadotAdapters,\n};\n\nexport { polkadotDiscoverer };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["slugify","kitSlugify"],"sources":["../src/chains.ts","../src/capabilities.ts","../src/no-rpc.ts","../src/injected/icon.ts","../src/injected/injected-web3.ts","../src/injected/adapter.ts","../src/injected/index.ts","../src/wallet-standard-adapter.ts","../src/discoverer.ts"],"sourcesContent":["import type { ChainBase } from \"@usebutr/core\";\n\nconst POLKADOT_CHAINS = {\n kusama: {\n id: \"polkadot:b0a8d493285c2df73290dfb7e61f870f\",\n name: \"Kusama\",\n namespace: \"polkadot\",\n reference: \"b0a8d493285c2df73290dfb7e61f870f\",\n },\n paseo: {\n id: \"polkadot:77afd6190f1554ad45fd0d31aee62aac\",\n name: \"Paseo\",\n namespace: \"polkadot\",\n reference: \"77afd6190f1554ad45fd0d31aee62aac\",\n },\n polkadot: {\n id: \"polkadot:91b171bb158e2d3848fa23a9f1c25182\",\n name: \"Polkadot\",\n namespace: \"polkadot\",\n reference: \"91b171bb158e2d3848fa23a9f1c25182\",\n },\n westend: {\n id: \"polkadot:e143f23803ac50e8f6f8e62695d1ce9e\",\n name: \"Westend\",\n namespace: \"polkadot\",\n reference: \"e143f23803ac50e8f6f8e62695d1ce9e\",\n },\n} as const satisfies Record<string, ChainBase>;\n\nconst POLKADOT_CHAINS_LIST: ReadonlyArray<ChainBase> = Object.values(POLKADOT_CHAINS);\n\nconst POLKADOT_CHAIN_BY_ID: ReadonlyMap<string, ChainBase> = new Map(\n POLKADOT_CHAINS_LIST.map((chain) => [chain.id, chain]),\n);\n\n/** Chains a wallet advertising several networks should resolve to first.\n * Kusama sits alongside Polkadot because it carries real value; Westend\n * and Paseo are faucet testnets and must never win the default. */\nconst POLKADOT_MAINNET_IDS: ReadonlyArray<string> = [\n POLKADOT_CHAINS.polkadot.id,\n POLKADOT_CHAINS.kusama.id,\n];\n\nexport { POLKADOT_CHAIN_BY_ID, POLKADOT_CHAINS, POLKADOT_CHAINS_LIST, POLKADOT_MAINNET_IDS };\n","import type { WalletCapabilities } from \"@usebutr/core\";\nimport { buildWalletCapabilities } from \"@usebutr/wallet-standard-shared\";\n\nimport { POLKADOT_CHAINS_LIST } from \"./chains\";\n\ntype WalletStandardPolkadotCapabilityInput = {\n chainCount: number;\n features: {\n events: boolean;\n signMessage: boolean;\n };\n};\n\n/**\n * injectedWeb3 always exposes `signer.signRaw` and `accounts.subscribe`, so\n * those flags are unconditional. The chain count comes from butr's own\n * registry because injectedWeb3 wallets advertise no chains.\n */\nconst resolveInjectedPolkadotCapabilities = (): WalletCapabilities =>\n buildWalletCapabilities({\n chainCount: POLKADOT_CHAINS_LIST.length,\n events: true,\n sendTransaction: false,\n signIn: false,\n signMessage: true,\n signTransaction: false,\n });\n\n/**\n * Wallet Standard `polkadot:*` feature → butr capability mapping. No\n * standalone `signTransaction`: building an extrinsic needs chain metadata\n * butr doesn't fetch, so transaction signing goes through `getSigner()`.\n */\nconst resolveWalletStandardPolkadotCapabilities = (\n input: WalletStandardPolkadotCapabilityInput,\n): WalletCapabilities =>\n buildWalletCapabilities({\n chainCount: input.chainCount,\n events: input.features.events,\n sendTransaction: false,\n signIn: false,\n signMessage: input.features.signMessage,\n signTransaction: false,\n });\n\nexport type { WalletStandardPolkadotCapabilityInput };\nexport { resolveInjectedPolkadotCapabilities, resolveWalletStandardPolkadotCapabilities };\n","import type { Balance } from \"@usebutr/core\";\n\n/**\n * Building an extrinsic or reading on-chain state both need chain metadata\n * butr doesn't fetch, so it ships no Polkadot RPC. The neutral balance and\n * receipt values are gated behind the matching `capabilities` flags.\n */\nconst POLKADOT_SEND_TX_HINT =\n \"Polkadot sendTx is unsupported: use getSigner() with polkadot-api to build and submit extrinsics\";\nconst POLKADOT_SEND_TX_TO_CHAIN_HINT =\n \"Polkadot sendTxToChain is unsupported: use getSigner() with polkadot-api to build and submit extrinsics\";\n\nconst noRpcBalance = (): Promise<Balance> =>\n Promise.resolve({ decimals: 0, formatted: \"0\", symbol: \"\", value: 0n });\n\nconst noRpcTransactionReceipt = (): Promise<{ status: \"Success\" | \"Error\" | \"Pending\" }> =>\n Promise.resolve({ status: \"Pending\" });\n\nconst noRpcSendTx = (): Promise<string> => Promise.reject(new Error(POLKADOT_SEND_TX_HINT));\n\nconst noRpcSendTxToChain = (): Promise<string> =>\n Promise.reject(new Error(POLKADOT_SEND_TX_TO_CHAIN_HINT));\n\nexport { noRpcBalance, noRpcSendTx, noRpcSendTxToChain, noRpcTransactionReceipt };\n","const GENERIC_POLKADOT_ICON =\n \"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiI+PGNpcmNsZSBjeD0iMTYiIGN5PSIxNiIgcj0iMTYiIGZpbGw9IiNFNjAwN0EiLz48L3N2Zz4=\";\n\nexport { GENERIC_POLKADOT_ICON };\n","/**\n * Local narrowing of the `@polkadot/extension-dapp` injectedWeb3 standard\n * to the fields butr reads, so the connector takes no dependency on\n * `@polkadot/extension-inject`.\n */\n\n/** A single account the extension exposes. Addresses are SS58; accounts\n * are chain-agnostic across Substrate. */\ntype InjectedAccount = {\n address: string;\n genesisHash?: string | null;\n name?: string;\n type?: string;\n};\n\n/** The polkadot-js `Signer`: butr only uses `signRaw` for message\n * signing. `signPayload` is consumer territory (via polkadot-api). */\ntype InjectedSigner = {\n signRaw?: (raw: {\n address: string;\n data: string;\n type: \"bytes\" | \"payload\";\n }) => Promise<{ id: number; signature: string }>;\n};\n\n/** The object returned by `enable()`. */\ntype Injected = {\n accounts: {\n get: () => Promise<ReadonlyArray<InjectedAccount>>;\n subscribe?: (cb: (accounts: ReadonlyArray<InjectedAccount>) => void) => () => void;\n };\n signer: InjectedSigner;\n};\n\n/** What lives at `window.injectedWeb3[key]`. */\ntype InjectedWindowProvider = {\n enable: (origin: string) => Promise<Injected>;\n version?: string;\n};\n\ntype InjectedWindow = {\n injectedWeb3?: Record<string, InjectedWindowProvider>;\n};\n\nconst BYTES_PREFIX = new TextEncoder().encode(\"<Bytes>\");\nconst BYTES_SUFFIX = new TextEncoder().encode(\"</Bytes>\");\n\nconst wrapBytes = (message: Uint8Array): Uint8Array => {\n const out = new Uint8Array(BYTES_PREFIX.length + message.length + BYTES_SUFFIX.length);\n out.set(BYTES_PREFIX, 0);\n out.set(message, BYTES_PREFIX.length);\n out.set(BYTES_SUFFIX, BYTES_PREFIX.length + message.length);\n return out;\n};\n\nconst readInjectedWindow = (target?: InjectedWindow | null): InjectedWindow | null => {\n if (target !== undefined) {\n return target;\n }\n if (typeof window === \"undefined\") {\n return null;\n }\n // `window.injectedWeb3` is the untyped Polkadot extension registry; the\n // DOM lib doesn't declare it, so this boundary assertion is unavoidable.\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion, anti-slop/no-chained-type-assertions -- untyped window.injectedWeb3 extension registry\n return window as unknown as InjectedWindow;\n};\n\nexport type { Injected, InjectedAccount, InjectedSigner, InjectedWindow, InjectedWindowProvider };\nexport { bytesToHexPrefixed as bytesToHex, hexToBytes } from \"@usebutr/core\";\nexport { readInjectedWindow, wrapBytes };\n","import type {\n Account,\n ChainBase,\n ConnectorEvent,\n PolkadotAdapter,\n WalletCapabilities,\n} from \"@usebutr/core\";\nimport { logWarn, sanitizeIcon } from \"@usebutr/core\";\n\nimport { resolveInjectedPolkadotCapabilities } from \"../capabilities\";\nimport { POLKADOT_CHAIN_BY_ID, POLKADOT_CHAINS } from \"../chains\";\nimport { noRpcBalance, noRpcSendTx, noRpcSendTxToChain, noRpcTransactionReceipt } from \"../no-rpc\";\n\nimport { GENERIC_POLKADOT_ICON } from \"./icon\";\nimport type { Injected, InjectedAccount, InjectedWindowProvider } from \"./injected-web3\";\nimport { bytesToHex, hexToBytes, wrapBytes } from \"./injected-web3\";\n\nconst DAPP_NAME = \"butr\";\n\n/** Handle returned by `getSigner()`. Carries the `window.injectedWeb3`\n * key (`extensionName`) so consumers can bridge to polkadot-api's\n * `connectInjectedExtension`, the active SS58 address, and the raw\n * `Injected` object for direct `signer` access. */\ntype PolkadotSignerHandle = {\n address: string;\n extension: Injected;\n extensionName: string;\n};\n\n/**\n * Deliberately not wallet-standard-shared's `slugify`: that helper embeds\n * the `wallet-standard:` scheme, while injected adapter ids follow the\n * `injected:polkadot:<slug>` convention.\n */\nconst toKebab = (name: string): string =>\n name\n .trim()\n .toLowerCase()\n .replaceAll(/[^a-z0-9]+/gv, \"-\")\n .replaceAll(/^-|-$/gv, \"\");\n\nconst buildPolkadotAccount = (address: string, chain: ChainBase): Account => ({\n chain,\n id: `${chain.id}:${address}`,\n walletAddress: address,\n});\n\n/** Everything that only exists between `connect()` and `disconnect()`: the\n * enabled provider and the wallet-side account subscription opened against\n * it. One value so the adapter can never be half-connected. */\ntype InjectedSession = {\n injected: Injected;\n unsubscribe: (() => void) | null;\n};\n\n/**\n * The provider is not enabled at construction: `enable()` raises the\n * extension's authorization prompt, so it runs lazily in `connect()`.\n */\nconst buildInjectedPolkadotAdapter = (\n extensionName: string,\n displayName: string,\n provider: InjectedWindowProvider,\n): PolkadotAdapter => {\n const capabilities: WalletCapabilities = resolveInjectedPolkadotCapabilities();\n let session: InjectedSession | null = null;\n let chain: ChainBase = POLKADOT_CHAINS.polkadot;\n const listenersSet = new Set<(event: ConnectorEvent) => void>();\n\n const emit = (event: ConnectorEvent): void => {\n // Snapshot: a listener is free to unsubscribe others from inside its\n // callback, and every listener registered at emit time still gets this\n // event.\n const snapshot = [...listenersSet];\n for (const listener of snapshot) {\n listener(event);\n }\n };\n\n const emitAccounts = (accounts: ReadonlyArray<InjectedAccount>): void => {\n const built = accounts.map((a) => buildPolkadotAccount(a.address, chain));\n const first = built[0];\n if (first !== undefined) {\n emit({ account: first, accounts: built, type: \"accountChanged\" });\n }\n };\n\n const closeSession = (): void => {\n session?.unsubscribe?.();\n session = null;\n };\n\n const handleWalletAccounts = (accounts: ReadonlyArray<InjectedAccount>): void => {\n if (accounts.length === 0) {\n closeSession();\n emit({ type: \"disconnected\" });\n return;\n }\n emitAccounts(accounts);\n };\n\n const openSession = (injected: Injected): void => {\n closeSession();\n const opened: InjectedSession = { injected, unsubscribe: null };\n session = opened;\n try {\n const unsubscribe = injected.accounts.subscribe?.(handleWalletAccounts);\n if (unsubscribe === undefined) {\n return;\n }\n // Wallets may fire the callback synchronously; an empty first payload\n // closes the session before this assignment, so never revive it.\n if (session === opened) {\n opened.unsubscribe = unsubscribe;\n } else {\n unsubscribe();\n }\n } catch (error) {\n logWarn(`[butr/polkadot] ${displayName} accounts.subscribe threw:`, error);\n }\n };\n\n const requireInjected = (): Injected => {\n if (session === null) {\n throw new Error(`Wallet ${displayName} is not connected`);\n }\n return session.injected;\n };\n\n const firstAddress = async (): Promise<string | null> => {\n if (session === null) {\n return null;\n }\n const accounts = await session.injected.accounts.get();\n return accounts[0]?.address ?? null;\n };\n\n return {\n capabilities,\n chainPlatform: \"polkadot\",\n\n async connect() {\n const injected = await provider.enable(DAPP_NAME);\n const accounts = await injected.accounts.get();\n if (accounts.length === 0) {\n throw new Error(`Wallet ${displayName} exposed no accounts`);\n }\n openSession(injected);\n },\n\n disconnect: () => {\n closeSession();\n return Promise.resolve();\n },\n\n async getAccount() {\n const address = await firstAddress();\n return address === null ? null : buildPolkadotAccount(address, chain);\n },\n\n async getAccounts() {\n if (session === null) {\n return [];\n }\n const accounts = await session.injected.accounts.get();\n return accounts.map((a) => buildPolkadotAccount(a.address, chain));\n },\n\n getBalance: noRpcBalance,\n\n async getSigner() {\n const ext = requireInjected();\n const address = await firstAddress();\n if (address === null) {\n throw new Error(\"No connected account\");\n }\n const handle: PolkadotSignerHandle = { address, extension: ext, extensionName };\n return handle;\n },\n\n getTransactionReceipt: noRpcTransactionReceipt,\n\n icon: sanitizeIcon(GENERIC_POLKADOT_ICON),\n id: `injected:polkadot:${toKebab(extensionName)}`,\n name: displayName,\n\n sendTx: noRpcSendTx,\n\n sendTxToChain: noRpcSendTxToChain,\n\n async signMessage(msg, account) {\n const ext = requireInjected();\n if (ext.signer.signRaw === undefined) {\n throw new Error(`Wallet ${displayName} does not expose signRaw`);\n }\n const address = account?.walletAddress ?? (await firstAddress());\n if (address === null || address === \"\") {\n throw new Error(\"No connected account\");\n }\n const wrapped = wrapBytes(msg);\n const result = await ext.signer.signRaw({\n address,\n data: bytesToHex(wrapped),\n type: \"bytes\",\n });\n return { signature: hexToBytes(result.signature), signedMessage: wrapped };\n },\n\n subscribe(listener) {\n listenersSet.add(listener);\n return () => {\n listenersSet.delete(listener);\n };\n },\n\n async switchChain(target) {\n if (target.namespace !== \"polkadot\") {\n throw new Error(\n `Polkadot adapter received non-Polkadot chain \"${target.id}\". Pass a chain with namespace \"polkadot\".`,\n );\n }\n chain = POLKADOT_CHAIN_BY_ID.get(target.id) ?? target;\n if (session === null) {\n return;\n }\n emitAccounts(await session.injected.accounts.get());\n },\n };\n};\n\nexport type { PolkadotSignerHandle };\nexport { buildInjectedPolkadotAdapter };\n","import type { WalletAdapter } from \"@usebutr/core\";\n\nimport { buildInjectedPolkadotAdapter } from \"./adapter\";\nimport type { InjectedWindow } from \"./injected-web3\";\nimport { readInjectedWindow } from \"./injected-web3\";\n\nconst KNOWN_NAMES: Readonly<Record<string, string>> = {\n enkrypt: \"Enkrypt\",\n \"nova-wallet\": \"Nova Wallet\",\n \"polkadot-js\": \"Polkadot{.js}\",\n \"subwallet-js\": \"SubWallet\",\n talisman: \"Talisman\",\n};\n\nconst displayNameFor = (key: string): string =>\n KNOWN_NAMES[key] ??\n key\n .split(/[\\-_]/v)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(\" \");\n\ntype InjectedPolkadotDiscoveryOptions = {\n /** Poll schedule (ms offsets) for late-injecting extensions. Defaults\n * to a few short polls; pass `[]` in tests for a single sync read. */\n pollMs?: ReadonlyArray<number>;\n /** Override the global host (tests, iframes). */\n target?: InjectedWindow | null;\n};\n\nconst DEFAULT_POLLS: ReadonlyArray<number> = [250, 750];\n\n/**\n * Adapters are built without calling `enable()`, which would raise the\n * extension's authorization prompt at discovery time. Extensions inject at\n * different points during page load, hence the poll schedule.\n */\nconst discoverInjectedPolkadotAdapters = (\n onAdapter: (adapter: WalletAdapter) => void,\n options: InjectedPolkadotDiscoveryOptions = {},\n): (() => void) => {\n const polls = options.pollMs ?? DEFAULT_POLLS;\n const seen = new Set<string>();\n const timers: Array<ReturnType<typeof setTimeout>> = [];\n let cancelled = false;\n\n const scan = () => {\n if (cancelled) {\n return;\n }\n const host = readInjectedWindow(options.target);\n const registry = host?.injectedWeb3;\n if (!registry) {\n return;\n }\n for (const [key, provider] of Object.entries(registry)) {\n if (seen.has(key)) {\n continue;\n }\n seen.add(key);\n onAdapter(buildInjectedPolkadotAdapter(key, displayNameFor(key), provider));\n }\n };\n\n scan();\n for (const offset of polls) {\n if (offset === 0) {\n continue;\n }\n timers.push(setTimeout(scan, offset));\n }\n\n return () => {\n cancelled = true;\n for (const timer of timers) {\n clearTimeout(timer);\n }\n };\n};\n\nexport type { InjectedPolkadotDiscoveryOptions };\nexport { discoverInjectedPolkadotAdapters };\n","import type { WalletAdapter } from \"@usebutr/core\";\nimport {\n createWalletStandardCore,\n discoverWalletStandard,\n getFeature,\n slugify as kitSlugify,\n} from \"@usebutr/wallet-standard-shared\";\nimport type { WalletStandardWallet } from \"@usebutr/wallet-standard-shared\";\n\nimport { resolveWalletStandardPolkadotCapabilities } from \"./capabilities\";\nimport { POLKADOT_MAINNET_IDS } from \"./chains\";\nimport { noRpcBalance, noRpcSendTx, noRpcSendTxToChain, noRpcTransactionReceipt } from \"./no-rpc\";\nimport type { PolkadotSignMessageFeature } from \"./wallet-standard-types\";\n\nconst POLKADOT_PREFIX = \"polkadot:\";\n\nconst slugify = (name: string): string => kitSlugify(\"polkadot\", name);\n\nconst buildPolkadotWalletStandardAdapter = (\n wallet: WalletStandardWallet,\n /** Optional. Called with a function that pushes a synthetic\n * `disconnected` event to all current subscribers. The discovery\n * layer invokes it on Wallet Standard `unregister`. */\n registerDisconnector?: (emit: () => void) => void,\n): WalletAdapter | null => {\n const core = createWalletStandardCore({\n chainPrefix: POLKADOT_PREFIX,\n id: slugify(wallet.name),\n label: \"Polkadot\",\n namespace: \"polkadot\",\n platform: \"Polkadot\",\n preferredChainIds: POLKADOT_MAINNET_IDS,\n registerDisconnector,\n trackChainChanges: false,\n wallet,\n });\n if (core === null) {\n return null;\n }\n\n const signMessage = getFeature<PolkadotSignMessageFeature>(wallet, \"polkadot:signMessage\");\n\n return {\n ...core,\n capabilities: resolveWalletStandardPolkadotCapabilities({\n chainCount: core.chainCount,\n features: { events: core.hasEvents, signMessage: Boolean(signMessage) },\n }),\n chainPlatform: \"polkadot\",\n\n getBalance: noRpcBalance,\n\n getTransactionReceipt: noRpcTransactionReceipt,\n\n sendTx: noRpcSendTx,\n\n sendTxToChain: noRpcSendTxToChain,\n\n async signMessage(msg, account) {\n if (signMessage === undefined) {\n throw new Error(`Wallet ${wallet.name} does not advertise polkadot:signMessage`);\n }\n const output = await signMessage.signMessage({\n account: core.resolveAccount(account),\n message: msg,\n });\n return { signature: output.signature, signedMessage: output.signedMessage ?? msg };\n },\n };\n};\n\n/**\n * The fallback channel; see `polkadotDiscoverer`. Requires the optional\n * `@wallet-standard/app` peer dep and no-ops without it.\n */\nconst discoverPolkadotWalletStandardAdapters = (\n onAdapter: (adapter: WalletAdapter) => void,\n): (() => void) =>\n discoverWalletStandard(onAdapter, (wallet, registerDisconnector) =>\n buildPolkadotWalletStandardAdapter(wallet, registerDisconnector),\n );\n\nexport { buildPolkadotWalletStandardAdapter, discoverPolkadotWalletStandardAdapters };\n","import type { PlatformDiscoverer } from \"@usebutr/core\";\n\nimport { discoverInjectedPolkadotAdapters } from \"./injected\";\nimport { discoverPolkadotWalletStandardAdapters } from \"./wallet-standard-adapter\";\n\n/**\n * Primary is injectedWeb3; Wallet Standard `polkadot:*` is the fallback. Its\n * defer is the only thing preventing double-listing: a wallet on both\n * channels mints two unrelated ids the discovery bus cannot collapse.\n */\nconst polkadotDiscoverer: PlatformDiscoverer = {\n fallback: {\n subscribe: (onAdapter, opts) => {\n if (opts.hasAnyPrimaryAdapter()) {\n return () => undefined;\n }\n return discoverPolkadotWalletStandardAdapters(onAdapter);\n },\n },\n subscribe: discoverInjectedPolkadotAdapters,\n};\n\nexport { polkadotDiscoverer };\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@usebutr/polkadot",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "injectedWeb3 + Wallet Standard adapter for butr (Polkadot/Substrate).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Pedro Filho <pedro@filho.me>",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"access": "public"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@usebutr/core": "
|
|
29
|
-
"@usebutr/wallet-standard-shared": "0.
|
|
28
|
+
"@usebutr/core": "2.0.0",
|
|
29
|
+
"@usebutr/wallet-standard-shared": "0.5.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@wallet-standard/app": "^1.1.1",
|
|
@@ -47,7 +47,6 @@
|
|
|
47
47
|
"build": "tsdown",
|
|
48
48
|
"clean": "rm -rf dist",
|
|
49
49
|
"dev": "tsdown --watch",
|
|
50
|
-
"lint": "oxlint src",
|
|
51
50
|
"test": "vitest run --passWithNoTests",
|
|
52
51
|
"test:coverage": "vitest run --coverage --passWithNoTests",
|
|
53
52
|
"typecheck": "tsc -p tsconfig.json --noEmit"
|