@usebutr/polkadot 0.1.0 → 0.1.2

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 CHANGED
@@ -146,7 +146,7 @@ type PolkadotSignMessageOutput = {
146
146
  signedMessage?: Uint8Array;
147
147
  };
148
148
  type PolkadotSignMessageFeature = {
149
- signMessage(input: PolkadotSignMessageInput): Promise<PolkadotSignMessageOutput>;
149
+ signMessage: (input: PolkadotSignMessageInput) => Promise<PolkadotSignMessageOutput>;
150
150
  };
151
151
  //#endregion
152
152
  //#region src/wallet-standard-adapter.d.ts
@@ -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/wallet-standard.ts","../src/discoverer.ts","../src/signer-augmentation.ts"],"mappings":";;;;cAMM,eAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;cA2BA,oBAAA,EAAsB,aAAa,CAAC,SAAA;;;KC/BrC,qCAAA;EACH,UAAA;EACA,QAAA;IACE,MAAA;IACA,WAAA;EAAA;AAAA;;;;;;;cAgBE,mCAAA,QAA0C,kBAW9C;;;;;;cAOI,yCAAA,GACJ,KAAA,EAAO,qCAAA,KACN,kBAWD;;;;;;;ADrD6C;;;;;KEU1C,eAAA;EACH,OAAA;EACA,WAAA;EACA,IAAA;EACA,IAAA;AAAA;;;KAKG,cAAA;EACH,OAAA,IAAW,GAAA;IACT,OAAA;IACA,IAAA;IACA,IAAA;EAAA,MACI,OAAO;IAAG,EAAA;IAAY,SAAA;EAAA;AAAA;;KAIzB,QAAA;EACH,QAAA;IACE,GAAA,QAAW,OAAA,CAAQ,aAAA,CAAc,eAAA;IACjC,SAAA,IAAa,EAAA,GAAK,QAAA,EAAU,aAAA,CAAc,eAAA;EAAA;EAE5C,MAAA,EAAQ,cAAA;AAAA;;KAIL,sBAAA;EACH,MAAA,GAAS,MAAA,aAAmB,OAAO,CAAC,QAAA;EACpC,OAAA;AAAA;AAAA,KAGG,cAAA;EACH,YAAA,GAAe,MAAM,SAAS,sBAAA;AAAA;;;;;AF3Ce;;KGuB1C,oBAAA;EACH,OAAA;EACA,SAAA,EAAW,QAAQ;EACnB,aAAA;AAAA;;;;;;;;;;cAoCI,4BAAA,GACJ,aAAA,UACA,WAAA,UACA,QAAA,EAAU,sBAAA,KACT,eA+HF;;;KC1KI,gCAAA;;AJvB0C;EI0B7C,MAAA,GAAS,aAAA;EAET,MAAA,GAAS,cAAc;AAAA;;;;;;;;;;cAcnB,gCAAA,GACJ,SAAA,GAAY,OAAA,EAAS,aAAA,WACrB,OAAA,GAAS,gCAAqC;;;KCrC3C,wBAAA;EACH,OAAA,EAAS,2BAAA;EACT,OAAA,EAAS,UAAU;AAAA;AAAA,KAGhB,yBAAA;EACH,SAAA,EAAW,UAAA;EACX,aAAA,GAAgB,UAAU;AAAA;AAAA,KAGvB,0BAAA;EACH,WAAA,CAAY,KAAA,EAAO,wBAAA,GAA2B,OAAA,CAAQ,yBAAA;AAAA;;;;;ALlBT;;;;;cM2CzC,kCAAA,GACJ,MAAA,EAAQ,oBAAA,EACR,oBAAA,IAAwB,IAAA,0BACvB,aAAa;;;;;;AN9C+B;;;cOWzC,sCAAA,GACJ,SAAA,GAAY,OAAA,EAAS,aAAa;;;;;;APZW;;;;;;;;cQgBzC,kBAAA,EAAoB,kBAazB;;;;;AR7B8C;;;;;;;;;YSgBnC,iBAAA;IACR,QAAA,EAAU,oBAAA,GAAuB,oBAAoB;EAAA;AAAA"}
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/wallet-standard.ts","../src/discoverer.ts","../src/signer-augmentation.ts"],"mappings":";;;;cAMM,eAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;cA2BA,oBAAA,EAAsB,aAAa,CAAC,SAAA;;;KC/BrC,qCAAA;EACH,UAAA;EACA,QAAA;IACE,MAAA;IACA,WAAA;EAAA;AAAA;;;;;;;cAgBE,mCAAA,QAA0C,kBAW9C;;;;;;cAOI,yCAAA,GACJ,KAAA,EAAO,qCAAA,KACN,kBAWD;;;;;;;ADrD6C;;;;;KEU1C,eAAA;EACH,OAAA;EACA,WAAA;EACA,IAAA;EACA,IAAA;AAAA;;;KAKG,cAAA;EACH,OAAA,IAAW,GAAA;IACT,OAAA;IACA,IAAA;IACA,IAAA;EAAA,MACI,OAAO;IAAG,EAAA;IAAY,SAAA;EAAA;AAAA;;KAIzB,QAAA;EACH,QAAA;IACE,GAAA,QAAW,OAAA,CAAQ,aAAA,CAAc,eAAA;IACjC,SAAA,IAAa,EAAA,GAAK,QAAA,EAAU,aAAA,CAAc,eAAA;EAAA;EAE5C,MAAA,EAAQ,cAAA;AAAA;;KAIL,sBAAA;EACH,MAAA,GAAS,MAAA,aAAmB,OAAO,CAAC,QAAA;EACpC,OAAA;AAAA;AAAA,KAGG,cAAA;EACH,YAAA,GAAe,MAAM,SAAS,sBAAA;AAAA;;;;;AF3Ce;;KGuB1C,oBAAA;EACH,OAAA;EACA,SAAA,EAAW,QAAQ;EACnB,aAAA;AAAA;;;;;;;;;;cAoCI,4BAAA,GACJ,aAAA,UACA,WAAA,UACA,QAAA,EAAU,sBAAA,KACT,eA+HF;;;KC1KI,gCAAA;;AJvB0C;EI0B7C,MAAA,GAAS,aAAA;EAET,MAAA,GAAS,cAAc;AAAA;;;;;;;;;;cAcnB,gCAAA,GACJ,SAAA,GAAY,OAAA,EAAS,aAAA,WACrB,OAAA,GAAS,gCAAqC;;;KCrC3C,wBAAA;EACH,OAAA,EAAS,2BAAA;EACT,OAAA,EAAS,UAAU;AAAA;AAAA,KAGhB,yBAAA;EACH,SAAA,EAAW,UAAA;EACX,aAAA,GAAgB,UAAU;AAAA;AAAA,KAGvB,0BAAA;EACH,WAAA,GAAc,KAAA,EAAO,wBAAA,KAA6B,OAAA,CAAQ,yBAAA;AAAA;;;;;ALlBb;;;;;cM2CzC,kCAAA,GACJ,MAAA,EAAQ,oBAAA,EACR,oBAAA,IAAwB,IAAA,0BACvB,aAAa;;;;;;AN9C+B;;;cOWzC,sCAAA,GACJ,SAAA,GAAY,OAAA,EAAS,aAAa;;;;;;APZW;;;;;;;;cQgBzC,kBAAA,EAAoB,kBAazB;;;;;AR7B8C;;;;;;;;;YSgBnC,iBAAA;IACR,QAAA,EAAU,oBAAA,GAAuB,oBAAoB;EAAA;AAAA"}
package/dist/index.js CHANGED
@@ -1,2 +1,448 @@
1
- import{logWarn as e,sanitizeIcon as t}from"@usebutr/core";import{buildAccount as n,discoverWalletStandard as r,getFeature as i,pickAccountByAddress as a,pickFirstAddress as o,slugify as s}from"@usebutr/wallet-standard-shared";const c={kusama:{id:`polkadot:b0a8d493285c2df73290dfb7e61f870f`,name:`Kusama`,namespace:`polkadot`,reference:`b0a8d493285c2df73290dfb7e61f870f`},paseo:{id:`polkadot:77afd6190f1554ad45fd0d31aee62aac`,name:`Paseo`,namespace:`polkadot`,reference:`77afd6190f1554ad45fd0d31aee62aac`},polkadot:{id:`polkadot:91b171bb158e2d3848fa23a9f1c25182`,name:`Polkadot`,namespace:`polkadot`,reference:`91b171bb158e2d3848fa23a9f1c25182`},westend:{id:`polkadot:e143f23803ac50e8f6f8e62695d1ce9e`,name:`Westend`,namespace:`polkadot`,reference:`e143f23803ac50e8f6f8e62695d1ce9e`}},l=Object.values(c),u=()=>({getBalance:!1,getTransactionReceipt:!1,requestAccounts:!1,sendTransaction:!1,signIn:!1,signMessage:!0,signTransaction:!1,subscribe:!0,switchAccount:!1,switchChain:!0}),d=e=>({getBalance:!1,getTransactionReceipt:!1,requestAccounts:!1,sendTransaction:!1,signIn:!1,signMessage:e.features.signMessage,signTransaction:!1,subscribe:e.features.events,switchAccount:!1,switchChain:e.chainCount>1}),f=()=>Promise.resolve({decimals:0,formatted:`0`,symbol:``,value:0n}),p=()=>Promise.resolve({status:`Pending`}),m=()=>Promise.reject(Error(`Polkadot sendTx is unsupported — use getSigner() with polkadot-api to build and submit extrinsics`)),h=()=>Promise.reject(Error(`Polkadot sendTxToChain is unsupported — use getSigner() with polkadot-api to build and submit extrinsics`)),g=new TextEncoder().encode(`<Bytes>`),_=new TextEncoder().encode(`</Bytes>`),v=e=>{let t=new Uint8Array(g.length+e.length+_.length);return t.set(g,0),t.set(e,g.length),t.set(_,g.length+e.length),t},y=e=>{let t=`0x`;for(let n of e)t+=n.toString(16).padStart(2,`0`);return t},b=e=>{let t=e.startsWith(`0x`)?e.slice(2):e,n=new Uint8Array(t.length/2);for(let e=0;e<n.length;e+=1)n[e]=Number.parseInt(t.slice(e*2,e*2+2),16);return n},x=e=>e===void 0?typeof window>`u`?null:window:e,S=e=>e.trim().toLowerCase().replaceAll(RegExp(`[^a-z0-9]+`,`gv`),`-`).replaceAll(RegExp(`^-|-$`,`gv`),``),C=(e,t)=>({chain:t,id:`${t.id}:${e}`,walletAddress:e}),w=(e,n,r)=>{let i=u(),a=null,o=c.polkadot,s=new Set,l=()=>{if(!a)throw Error(`Wallet ${n} is not connected`);return a},d=async()=>a?(await a.accounts.get())[0]?.address??null:null;return{capabilities:i,chainPlatform:`polkadot`,async connect(){if(a=await r.enable(`butr`),(await a.accounts.get()).length===0)throw Error(`Wallet ${n} exposed no accounts`)},disconnect(){return a=null,Promise.resolve()},async getAccount(){let e=await d();return e?C(e,o):null},async getAccounts(){return a?(await a.accounts.get()).map(e=>C(e.address,o)):[]},getBalance:f,async getSigner(){let t=l(),n=await d();if(!n)throw Error(`No connected account`);return{address:n,extension:t,extensionName:e}},getTransactionReceipt:p,icon:t(`data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiI+PGNpcmNsZSBjeD0iMTYiIGN5PSIxNiIgcj0iMTYiIGZpbGw9IiNFNjAwN0EiLz48L3N2Zz4=`),id:`injected:polkadot:${S(e)}`,name:n,sendTx:m,sendTxToChain:h,async signMessage(e,t){let r=l();if(!r.signer.signRaw)throw Error(`Wallet ${n} does not expose signRaw`);let i=t?.walletAddress??await d();if(!i)throw Error(`No connected account`);let a=v(e);return{signature:b((await r.signer.signRaw({address:i,data:y(a),type:`bytes`})).signature),signedMessage:a}},subscribe(e){s.add(e);let t=null;return a?.accounts.subscribe&&(t=a.accounts.subscribe(t=>{if(t.length===0){e({type:`disconnected`});return}let n=t.map(e=>C(e.address,o)),r=n[0];r&&e({account:r,accounts:n,type:`accountChanged`})})),()=>{s.delete(e),t?.()}},switchChain(e){return e.namespace===`polkadot`?(o=e,Promise.resolve()):Promise.reject(Error(`Polkadot adapter received non-Polkadot chain "${e.id}". Pass a chain with namespace "polkadot".`))}}},T={enkrypt:`Enkrypt`,"nova-wallet":`Nova Wallet`,"polkadot-js":`Polkadot{.js}`,"subwallet-js":`SubWallet`,talisman:`Talisman`},E=e=>T[e]??e.split(RegExp(`[\\-_]`,`v`)).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(` `),D=[250,750],O=(e,t={})=>{let n=t.pollMs??D,r=new Set,i=[],a=!1,o=()=>{if(a)return;let n=x(t.target)?.injectedWeb3;if(n)for(let[t,i]of Object.entries(n))r.has(t)||(r.add(t),e(w(t,E(t),i)))};o();for(let e of n)e!==0&&i.push(setTimeout(o,e));return()=>{a=!0;for(let e of i)clearTimeout(e)}},k=`polkadot:`,A=e=>s(`polkadot`,e),j=e=>e.chains.find(e=>e.startsWith(k))??null,M=(e,t)=>({id:e,name:t,namespace:`polkadot`,reference:e.slice(9)}),N=(e,t)=>n(e,t),P=(n,r)=>{let s=j(n);if(!s)return null;let c=i(n,`standard:connect`);if(!c)return null;let l=i(n,`standard:disconnect`),u=i(n,`standard:events`),g=i(n,`polkadot:signMessage`),_=s,v=()=>M(_,n.name),y=new Set,b=()=>{if(n.accounts.length===0)return;let e=v(),t=n.accounts.map(t=>N(t.address,e)),r=t[0];if(r)for(let e of y)e({account:r,accounts:t,type:`accountChanged`})};return r?.(()=>{for(let e of y)e({type:`disconnected`})}),{capabilities:d({chainCount:n.chains.filter(e=>e.startsWith(k)).length,features:{events:!!u,signMessage:!!g}}),chainPlatform:`polkadot`,async connect(e){await c.connect(e?.silent?{silent:!0}:void 0)},async disconnect(){if(l)try{await l.disconnect()}catch(t){e(`[butr] Polkadot Wallet Standard disconnect threw:`,t)}},getAccount(){let e=o(n.accounts);return Promise.resolve(e?N(e,v()):null)},getAccounts(){let e=v();return Promise.resolve(n.accounts.map(t=>N(t.address,e)))},getBalance:f,getSigner(){return Promise.resolve(n)},getTransactionReceipt:p,icon:t(n.icon),id:A(n.name),name:n.name,sendTx:m,sendTxToChain:h,async signMessage(e,t){if(!g)throw Error(`Wallet ${n.name} does not advertise polkadot:signMessage`);let r=t?a(n.accounts,t.walletAddress):n.accounts[0]??null;if(!r)throw Error(`No connected account`);let i=await g.signMessage({account:r,message:e});return{signature:i.signature,signedMessage:i.signedMessage??e}},subscribe(e){y.add(e);let t=null;if(u){let n=u.on(`change`,t=>{if(t.accounts){if(t.accounts.length===0){e({type:`disconnected`});return}let n=v(),r=t.accounts.map(e=>N(e.address,n)),i=r[0];i&&e({account:i,accounts:r,type:`accountChanged`})}});t=()=>n()}return()=>{y.delete(e),t?.()}},switchChain(e){if(e.namespace!==`polkadot`)throw Error(`Polkadot adapter received non-Polkadot chain "${e.id}". Pass a chain with namespace "polkadot".`);if(!n.chains.includes(e.id))throw Error(`Wallet ${n.name} does not advertise chain "${e.id}". Available: ${n.chains.join(`, `)}`);return _=e.id,b(),Promise.resolve()}}},F=e=>r(e,(e,t)=>P(e,t)),I={fallback:{subscribe:(e,t)=>t.hasAnyPrimaryAdapter()?()=>void 0:F(e)},platform:`polkadot`,subscribe:O};export{c as POLKADOT_CHAINS,l as POLKADOT_CHAINS_LIST,w as buildInjectedPolkadotAdapter,P as buildPolkadotWalletStandardAdapter,O as discoverInjectedPolkadotAdapters,F as discoverPolkadotWalletStandardAdapters,I as polkadotDiscoverer,u as resolveInjectedPolkadotCapabilities,d as resolveWalletStandardPolkadotCapabilities};
1
+ import { bytesToHexPrefixed as bytesToHex, hexToBytes, logWarn, sanitizeIcon } from "@usebutr/core";
2
+ import { buildAccount, discoverWalletStandard, getFeature, pickAccountByAddress, pickFirstAddress, slugify } from "@usebutr/wallet-standard-shared";
3
+
4
+ //#region src/chains.ts
5
+ const POLKADOT_CHAINS = {
6
+ kusama: {
7
+ id: "polkadot:b0a8d493285c2df73290dfb7e61f870f",
8
+ name: "Kusama",
9
+ namespace: "polkadot",
10
+ reference: "b0a8d493285c2df73290dfb7e61f870f"
11
+ },
12
+ paseo: {
13
+ id: "polkadot:77afd6190f1554ad45fd0d31aee62aac",
14
+ name: "Paseo",
15
+ namespace: "polkadot",
16
+ reference: "77afd6190f1554ad45fd0d31aee62aac"
17
+ },
18
+ polkadot: {
19
+ id: "polkadot:91b171bb158e2d3848fa23a9f1c25182",
20
+ name: "Polkadot",
21
+ namespace: "polkadot",
22
+ reference: "91b171bb158e2d3848fa23a9f1c25182"
23
+ },
24
+ westend: {
25
+ id: "polkadot:e143f23803ac50e8f6f8e62695d1ce9e",
26
+ name: "Westend",
27
+ namespace: "polkadot",
28
+ reference: "e143f23803ac50e8f6f8e62695d1ce9e"
29
+ }
30
+ };
31
+ const POLKADOT_CHAINS_LIST = Object.values(POLKADOT_CHAINS);
32
+
33
+ //#endregion
34
+ //#region src/capabilities.ts
35
+ /**
36
+ * injectedWeb3 capability profile. The injected `signer.signRaw` always
37
+ * supports message signing; `accounts.subscribe` always supports events;
38
+ * butr authors the chain list (4 chains) so local switchChain is always
39
+ * available.
40
+ */
41
+ const resolveInjectedPolkadotCapabilities = () => ({
42
+ getBalance: false,
43
+ getTransactionReceipt: false,
44
+ requestAccounts: false,
45
+ sendTransaction: false,
46
+ signIn: false,
47
+ signMessage: true,
48
+ signTransaction: false,
49
+ subscribe: true,
50
+ switchAccount: false,
51
+ switchChain: true
52
+ });
53
+ /**
54
+ * Wallet Standard `polkadot:*` capability mapping. Mirrors the Sui/SVM
55
+ * resolvers: features come from what the wallet advertises; switchChain
56
+ * follows chainCount (local re-routing among advertised chains).
57
+ */
58
+ const resolveWalletStandardPolkadotCapabilities = (input) => ({
59
+ getBalance: false,
60
+ getTransactionReceipt: false,
61
+ requestAccounts: false,
62
+ sendTransaction: false,
63
+ signIn: false,
64
+ signMessage: input.features.signMessage,
65
+ signTransaction: false,
66
+ subscribe: input.features.events,
67
+ switchAccount: false,
68
+ switchChain: input.chainCount > 1
69
+ });
70
+
71
+ //#endregion
72
+ //#region src/no-rpc.ts
73
+ /**
74
+ * butr ships no RPC on Polkadot: building/broadcasting an extrinsic and
75
+ * reading on-chain state both need chain metadata. Balance and receipt
76
+ * reads return neutral placeholders (gated behind
77
+ * `capabilities.getBalance` / `getTransactionReceipt === false`);
78
+ * transaction submission rejects with a hint to drive polkadot-api via
79
+ * `getSigner()`. Both discovery channels (injectedWeb3 + Wallet Standard)
80
+ * share these so the invariant lives in one place.
81
+ */
82
+ const POLKADOT_SEND_TX_HINT = "Polkadot sendTx is unsupported — use getSigner() with polkadot-api to build and submit extrinsics";
83
+ const POLKADOT_SEND_TX_TO_CHAIN_HINT = "Polkadot sendTxToChain is unsupported — use getSigner() with polkadot-api to build and submit extrinsics";
84
+ const noRpcBalance = () => Promise.resolve({
85
+ decimals: 0,
86
+ formatted: "0",
87
+ symbol: "",
88
+ value: 0n
89
+ });
90
+ const noRpcTransactionReceipt = () => Promise.resolve({ status: "Pending" });
91
+ const noRpcSendTx = () => Promise.reject(/* @__PURE__ */ new Error(POLKADOT_SEND_TX_HINT));
92
+ const noRpcSendTxToChain = () => Promise.reject(/* @__PURE__ */ new Error(POLKADOT_SEND_TX_TO_CHAIN_HINT));
93
+
94
+ //#endregion
95
+ //#region src/injected/icon.ts
96
+ const GENERIC_POLKADOT_ICON = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiI+PGNpcmNsZSBjeD0iMTYiIGN5PSIxNiIgcj0iMTYiIGZpbGw9IiNFNjAwN0EiLz48L3N2Zz4=";
97
+
98
+ //#endregion
99
+ //#region src/injected/injected-web3.ts
100
+ const BYTES_PREFIX = new TextEncoder().encode("<Bytes>");
101
+ const BYTES_SUFFIX = new TextEncoder().encode("</Bytes>");
102
+ const wrapBytes = (message) => {
103
+ const out = new Uint8Array(BYTES_PREFIX.length + message.length + BYTES_SUFFIX.length);
104
+ out.set(BYTES_PREFIX, 0);
105
+ out.set(message, BYTES_PREFIX.length);
106
+ out.set(BYTES_SUFFIX, BYTES_PREFIX.length + message.length);
107
+ return out;
108
+ };
109
+ const readInjectedWindow = (target) => {
110
+ if (target !== void 0) return target;
111
+ return typeof window === "undefined" ? null : window;
112
+ };
113
+
114
+ //#endregion
115
+ //#region src/injected/adapter.ts
116
+ const DAPP_NAME = "butr";
117
+ /**
118
+ * Convert a wallet display name into a stable kebab-case slug for the
119
+ * injected adapter id. Strips anything that isn't a lowercase letter or
120
+ * digit (turning "Polkadot{.js}" → "polkadot-js"), then prepends the
121
+ * injected Polkadot channel prefix.
122
+ *
123
+ * This is intentionally NOT the wallet-standard-shared `slugify` helper
124
+ * — that helper embeds the `wallet-standard:` scheme which is wrong for
125
+ * the injected channel. The ID convention for injected adapters is
126
+ * `injected:polkadot:<slug>`.
127
+ */
128
+ const toKebab = (name) => name.trim().toLowerCase().replaceAll(/* @__PURE__ */ new RegExp("[^a-z0-9]+", "gv"), "-").replaceAll(/* @__PURE__ */ new RegExp("^-|-$", "gv"), "");
129
+ const buildPolkadotAccount = (address, chain) => ({
130
+ chain,
131
+ id: `${chain.id}:${address}`,
132
+ walletAddress: address
133
+ });
134
+ /**
135
+ * Wrap a `window.injectedWeb3[name]` provider into a butr
136
+ * `PolkadotAdapter`. The provider is NOT enabled at construction —
137
+ * `enable()` triggers the authorization prompt, so it runs lazily in
138
+ * `connect()`. Before connect, `getAccount` returns null.
139
+ *
140
+ * `id` is `injected:polkadot:<slug>` so consumers can distinguish the
141
+ * injected channel from the Wallet Standard one in their picker.
142
+ */
143
+ const buildInjectedPolkadotAdapter = (extensionName, displayName, provider) => {
144
+ const capabilities = resolveInjectedPolkadotCapabilities();
145
+ let injected = null;
146
+ let chain = POLKADOT_CHAINS.polkadot;
147
+ const listenersSet = /* @__PURE__ */ new Set();
148
+ const requireInjected = () => {
149
+ if (!injected) throw new Error(`Wallet ${displayName} is not connected`);
150
+ return injected;
151
+ };
152
+ const firstAddress = async () => {
153
+ if (!injected) return null;
154
+ return (await injected.accounts.get())[0]?.address ?? null;
155
+ };
156
+ return {
157
+ capabilities,
158
+ chainPlatform: "polkadot",
159
+ async connect() {
160
+ injected = await provider.enable(DAPP_NAME);
161
+ if ((await injected.accounts.get()).length === 0) throw new Error(`Wallet ${displayName} exposed no accounts`);
162
+ },
163
+ disconnect() {
164
+ injected = null;
165
+ return Promise.resolve();
166
+ },
167
+ async getAccount() {
168
+ const address = await firstAddress();
169
+ return address ? buildPolkadotAccount(address, chain) : null;
170
+ },
171
+ async getAccounts() {
172
+ if (!injected) return [];
173
+ return (await injected.accounts.get()).map((a) => buildPolkadotAccount(a.address, chain));
174
+ },
175
+ getBalance: noRpcBalance,
176
+ async getSigner() {
177
+ const ext = requireInjected();
178
+ const address = await firstAddress();
179
+ if (!address) throw new Error("No connected account");
180
+ return {
181
+ address,
182
+ extension: ext,
183
+ extensionName
184
+ };
185
+ },
186
+ getTransactionReceipt: noRpcTransactionReceipt,
187
+ icon: sanitizeIcon(GENERIC_POLKADOT_ICON),
188
+ id: `injected:polkadot:${toKebab(extensionName)}`,
189
+ name: displayName,
190
+ sendTx: noRpcSendTx,
191
+ sendTxToChain: noRpcSendTxToChain,
192
+ async signMessage(msg, account) {
193
+ const ext = requireInjected();
194
+ if (!ext.signer.signRaw) throw new Error(`Wallet ${displayName} does not expose signRaw`);
195
+ const address = account?.walletAddress ?? await firstAddress();
196
+ if (!address) throw new Error("No connected account");
197
+ const wrapped = wrapBytes(msg);
198
+ return {
199
+ signature: hexToBytes((await ext.signer.signRaw({
200
+ address,
201
+ data: bytesToHex(wrapped),
202
+ type: "bytes"
203
+ })).signature),
204
+ signedMessage: wrapped
205
+ };
206
+ },
207
+ subscribe(listener) {
208
+ listenersSet.add(listener);
209
+ let unsubWallet = null;
210
+ if (injected?.accounts.subscribe) unsubWallet = injected.accounts.subscribe((accounts) => {
211
+ if (accounts.length === 0) {
212
+ listener({ type: "disconnected" });
213
+ return;
214
+ }
215
+ const built = accounts.map((a) => buildPolkadotAccount(a.address, chain));
216
+ const first = built[0];
217
+ if (first) listener({
218
+ account: first,
219
+ accounts: built,
220
+ type: "accountChanged"
221
+ });
222
+ });
223
+ return () => {
224
+ listenersSet.delete(listener);
225
+ unsubWallet?.();
226
+ };
227
+ },
228
+ switchChain(target) {
229
+ if (target.namespace !== "polkadot") return Promise.reject(/* @__PURE__ */ new Error(`Polkadot adapter received non-Polkadot chain "${target.id}". Pass a chain with namespace "polkadot".`));
230
+ chain = target;
231
+ return Promise.resolve();
232
+ }
233
+ };
234
+ };
235
+
236
+ //#endregion
237
+ //#region src/injected/index.ts
238
+ const KNOWN_NAMES = {
239
+ enkrypt: "Enkrypt",
240
+ "nova-wallet": "Nova Wallet",
241
+ "polkadot-js": "Polkadot{.js}",
242
+ "subwallet-js": "SubWallet",
243
+ talisman: "Talisman"
244
+ };
245
+ const displayNameFor = (key) => KNOWN_NAMES[key] ?? key.split(/* @__PURE__ */ new RegExp("[\\-_]", "v")).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
246
+ const DEFAULT_POLLS = [250, 750];
247
+ /**
248
+ * Primary Polkadot discovery: enumerate `window.injectedWeb3` keys and
249
+ * emit one `PolkadotAdapter` per extension. Adapters are built WITHOUT
250
+ * calling `enable()` (no prompt at discovery time); `connect()` enables
251
+ * lazily.
252
+ *
253
+ * Extensions inject at different times during page load, so we read
254
+ * immediately and re-check on a short poll schedule, deduping by key.
255
+ */
256
+ const discoverInjectedPolkadotAdapters = (onAdapter, options = {}) => {
257
+ const polls = options.pollMs ?? DEFAULT_POLLS;
258
+ const seen = /* @__PURE__ */ new Set();
259
+ const timers = [];
260
+ let cancelled = false;
261
+ const scan = () => {
262
+ if (cancelled) return;
263
+ const registry = readInjectedWindow(options.target)?.injectedWeb3;
264
+ if (!registry) return;
265
+ for (const [key, provider] of Object.entries(registry)) {
266
+ if (seen.has(key)) continue;
267
+ seen.add(key);
268
+ onAdapter(buildInjectedPolkadotAdapter(key, displayNameFor(key), provider));
269
+ }
270
+ };
271
+ scan();
272
+ for (const offset of polls) {
273
+ if (offset === 0) continue;
274
+ timers.push(setTimeout(scan, offset));
275
+ }
276
+ return () => {
277
+ cancelled = true;
278
+ for (const timer of timers) clearTimeout(timer);
279
+ };
280
+ };
281
+
282
+ //#endregion
283
+ //#region src/wallet-standard-adapter.ts
284
+ const POLKADOT_PREFIX = "polkadot:";
285
+ const slugify$1 = (name) => slugify("polkadot", name);
286
+ const pickPolkadotChain = (wallet) => wallet.chains.find((c) => c.startsWith(POLKADOT_PREFIX)) ?? null;
287
+ const buildChain = (chainId, walletName) => ({
288
+ id: chainId,
289
+ name: walletName,
290
+ namespace: "polkadot",
291
+ reference: chainId.slice(9)
292
+ });
293
+ const buildWsAccount = (address, chain) => buildAccount(address, chain);
294
+ /**
295
+ * Adapt a Wallet Standard wallet advertising `polkadot:*` features into a
296
+ * butr `WalletAdapter`. Returns `null` for wallets that don't advertise a
297
+ * polkadot chain or `standard:connect`. butr ships no RPC, so
298
+ * sendTx/getBalance/getTransactionReceipt are placeholders; transaction
299
+ * signing goes through `getSigner()` (returns the Wallet Standard wallet).
300
+ */
301
+ const buildPolkadotWalletStandardAdapter = (wallet, registerDisconnector) => {
302
+ const chainId = pickPolkadotChain(wallet);
303
+ if (!chainId) return null;
304
+ const connect = getFeature(wallet, "standard:connect");
305
+ if (!connect) return null;
306
+ const disconnect = getFeature(wallet, "standard:disconnect");
307
+ const events = getFeature(wallet, "standard:events");
308
+ const signMessage = getFeature(wallet, "polkadot:signMessage");
309
+ let currentChainId = chainId;
310
+ const currentChain = () => buildChain(currentChainId, wallet.name);
311
+ const listeners = /* @__PURE__ */ new Set();
312
+ const notifyAccountChanged = () => {
313
+ if (wallet.accounts.length === 0) return;
314
+ const chain = currentChain();
315
+ const built = wallet.accounts.map((a) => buildWsAccount(a.address, chain));
316
+ const first = built[0];
317
+ if (!first) return;
318
+ for (const listener of listeners) listener({
319
+ account: first,
320
+ accounts: built,
321
+ type: "accountChanged"
322
+ });
323
+ };
324
+ registerDisconnector?.(() => {
325
+ for (const listener of listeners) listener({ type: "disconnected" });
326
+ });
327
+ return {
328
+ capabilities: resolveWalletStandardPolkadotCapabilities({
329
+ chainCount: wallet.chains.filter((c) => c.startsWith(POLKADOT_PREFIX)).length,
330
+ features: {
331
+ events: Boolean(events),
332
+ signMessage: Boolean(signMessage)
333
+ }
334
+ }),
335
+ chainPlatform: "polkadot",
336
+ async connect(opts) {
337
+ await connect.connect(opts?.silent ? { silent: true } : void 0);
338
+ },
339
+ async disconnect() {
340
+ if (disconnect) try {
341
+ await disconnect.disconnect();
342
+ } catch (error) {
343
+ logWarn("[butr] Polkadot Wallet Standard disconnect threw:", error);
344
+ }
345
+ },
346
+ getAccount() {
347
+ const address = pickFirstAddress(wallet.accounts);
348
+ return Promise.resolve(address ? buildWsAccount(address, currentChain()) : null);
349
+ },
350
+ getAccounts() {
351
+ const chain = currentChain();
352
+ return Promise.resolve(wallet.accounts.map((a) => buildWsAccount(a.address, chain)));
353
+ },
354
+ getBalance: noRpcBalance,
355
+ getSigner() {
356
+ return Promise.resolve(wallet);
357
+ },
358
+ getTransactionReceipt: noRpcTransactionReceipt,
359
+ icon: sanitizeIcon(wallet.icon),
360
+ id: slugify$1(wallet.name),
361
+ name: wallet.name,
362
+ sendTx: noRpcSendTx,
363
+ sendTxToChain: noRpcSendTxToChain,
364
+ async signMessage(msg, account) {
365
+ if (!signMessage) throw new Error(`Wallet ${wallet.name} does not advertise polkadot:signMessage`);
366
+ const wsAccount = account ? pickAccountByAddress(wallet.accounts, account.walletAddress) : wallet.accounts[0] ?? null;
367
+ if (!wsAccount) throw new Error("No connected account");
368
+ const output = await signMessage.signMessage({
369
+ account: wsAccount,
370
+ message: msg
371
+ });
372
+ return {
373
+ signature: output.signature,
374
+ signedMessage: output.signedMessage ?? msg
375
+ };
376
+ },
377
+ subscribe(listener) {
378
+ listeners.add(listener);
379
+ let unsubWallet = null;
380
+ if (events) {
381
+ const unsub = events.on("change", (changes) => {
382
+ if (changes.accounts) {
383
+ if (changes.accounts.length === 0) {
384
+ listener({ type: "disconnected" });
385
+ return;
386
+ }
387
+ const chain = currentChain();
388
+ const built = changes.accounts.map((a) => buildWsAccount(a.address, chain));
389
+ const first = built[0];
390
+ if (first) listener({
391
+ account: first,
392
+ accounts: built,
393
+ type: "accountChanged"
394
+ });
395
+ }
396
+ });
397
+ unsubWallet = () => unsub();
398
+ }
399
+ return () => {
400
+ listeners.delete(listener);
401
+ unsubWallet?.();
402
+ };
403
+ },
404
+ switchChain(target) {
405
+ if (target.namespace !== "polkadot") throw new Error(`Polkadot adapter received non-Polkadot chain "${target.id}". Pass a chain with namespace "polkadot".`);
406
+ if (!wallet.chains.includes(target.id)) throw new Error(`Wallet ${wallet.name} does not advertise chain "${target.id}". Available: ${wallet.chains.join(", ")}`);
407
+ currentChainId = target.id;
408
+ notifyAccountChanged();
409
+ return Promise.resolve();
410
+ }
411
+ };
412
+ };
413
+
414
+ //#endregion
415
+ //#region src/wallet-standard.ts
416
+ /**
417
+ * Subscribe to Wallet Standard announcements and emit adapters for
418
+ * wallets advertising `polkadot:*` features (Talisman, SubWallet). Used
419
+ * as the FALLBACK channel — see `polkadotDiscoverer`. Requires the
420
+ * optional `@wallet-standard/app` peer dep; absent → no-op.
421
+ */
422
+ const discoverPolkadotWalletStandardAdapters = (onAdapter) => discoverWalletStandard(onAdapter, (wallet, registerDisconnector) => buildPolkadotWalletStandardAdapter(wallet, registerDisconnector));
423
+
424
+ //#endregion
425
+ //#region src/discoverer.ts
426
+ /**
427
+ * Polkadot's `PlatformDiscoverer`. Inverts the Bitcoin layout:
428
+ * - PRIMARY (`subscribe`) is injectedWeb3 — the dominant, broadest
429
+ * Polkadot standard (polkadot-js, Talisman, SubWallet, Nova, Enkrypt).
430
+ * - FALLBACK is Wallet Standard `polkadot:*`. It defers when the primary
431
+ * channel already produced an adapter for the session
432
+ * (`hasAnyPrimaryAdapter`). Since Wallet Standard support is always
433
+ * additive on Polkadot today (Talisman/SubWallet expose both), the
434
+ * discovery-bus also dedups overlaps and the defer prevents
435
+ * double-listing.
436
+ */
437
+ const polkadotDiscoverer = {
438
+ fallback: { subscribe: (onAdapter, opts) => {
439
+ if (opts.hasAnyPrimaryAdapter()) return () => void 0;
440
+ return discoverPolkadotWalletStandardAdapters(onAdapter);
441
+ } },
442
+ platform: "polkadot",
443
+ subscribe: discoverInjectedPolkadotAdapters
444
+ };
445
+
446
+ //#endregion
447
+ export { POLKADOT_CHAINS, POLKADOT_CHAINS_LIST, buildInjectedPolkadotAdapter, buildPolkadotWalletStandardAdapter, discoverInjectedPolkadotAdapters, discoverPolkadotWalletStandardAdapters, polkadotDiscoverer, resolveInjectedPolkadotCapabilities, resolveWalletStandardPolkadotCapabilities };
2
448
  //# sourceMappingURL=index.js.map
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/wallet-standard.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\";\n\ntype WalletStandardPolkadotCapabilityInput = {\n chainCount: number;\n features: {\n events: boolean;\n signMessage: boolean;\n };\n};\n\n// butr ships no RPC: getBalance / getTransactionReceipt / sendTransaction\n// are always false on Polkadot. signTransaction is false too — building a\n// Substrate extrinsic needs chain metadata, so transaction signing goes\n// through getSigner() (consumer drives polkadot-api). requestAccounts is\n// false: extensions manage account exposure in their own UI.\n\n/**\n * injectedWeb3 capability profile. The injected `signer.signRaw` always\n * supports message signing; `accounts.subscribe` always supports events;\n * butr authors the chain list (4 chains) so local switchChain is always\n * available.\n */\nconst resolveInjectedPolkadotCapabilities = (): WalletCapabilities => ({\n getBalance: false,\n getTransactionReceipt: false,\n requestAccounts: false,\n sendTransaction: false,\n signIn: false,\n signMessage: true,\n signTransaction: false,\n subscribe: true,\n switchAccount: false,\n switchChain: true,\n});\n\n/**\n * Wallet Standard `polkadot:*` capability mapping. Mirrors the Sui/SVM\n * resolvers: features come from what the wallet advertises; switchChain\n * follows chainCount (local re-routing among advertised chains).\n */\nconst resolveWalletStandardPolkadotCapabilities = (\n input: WalletStandardPolkadotCapabilityInput,\n): WalletCapabilities => ({\n getBalance: false,\n getTransactionReceipt: false,\n requestAccounts: false,\n sendTransaction: false,\n signIn: false,\n signMessage: input.features.signMessage,\n signTransaction: false,\n subscribe: input.features.events,\n switchAccount: false,\n switchChain: input.chainCount > 1,\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\n// Neutral, chain-agnostic placeholder. The registry spans DOT/KSM/WND/PAS\n// with different symbols and decimals, so a hardcoded \"DOT\"/10 would be\n// wrong for most of them. Consumers read real balances via polkadot-api.\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","// Generic Polkadot mark (pink dot), data-URI so the connector ships no\n// asset files. Mirrors @usebutr/bitcoin's GENERIC_BITCOIN_ICON approach.\nconst 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\n// `<Bytes>` / `</Bytes>` wrapper polkadot-js, Talisman, and SubWallet add\n// around raw messages before signing (prevents signed messages from being\n// replayed as transaction payloads). Verifiers must check signatures\n// against the wrapped bytes, which is why butr returns them as\n// `signedMessage`.\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 bytesToHex = (bytes: Uint8Array): string => {\n let hex = \"0x\";\n for (const byte of bytes) {\n hex += byte.toString(16).padStart(2, \"0\");\n }\n return hex;\n};\n\nconst hexToBytes = (hex: string): Uint8Array => {\n const clean = hex.startsWith(\"0x\") ? hex.slice(2) : hex;\n const out = new Uint8Array(clean.length / 2);\n for (let i = 0; i < out.length; i += 1) {\n out[i] = Number.parseInt(clean.slice(i * 2, i * 2 + 2), 16);\n }\n return out;\n};\n\nconst readInjectedWindow = (target?: InjectedWindow | null): InjectedWindow | null => {\n if (target !== undefined) {\n return target;\n }\n return typeof window === \"undefined\" ? null : (window as unknown as InjectedWindow);\n};\n\nexport type { Injected, InjectedAccount, InjectedSigner, InjectedWindow, InjectedWindowProvider };\nexport { bytesToHex, hexToBytes, 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) {\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) {\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 ? buildPolkadotAccount(address, chain) : null;\n },\n\n async getAccounts() {\n if (!injected) {\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) {\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) {\n throw new Error(`Wallet ${displayName} does not expose signRaw`);\n }\n const address = account?.walletAddress ?? (await firstAddress());\n if (!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) {\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 // Substrate accounts are chain-agnostic; switching is local state\n // that tells consumers which chain context to target.\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\n// Display-name overrides for known registry keys. Unknown keys fall back\n// to a title-cased version of the key.\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 { Account, ChainBase, ConnectorEvent, WalletAdapter } from \"@usebutr/core\";\nimport { logWarn, sanitizeIcon } from \"@usebutr/core\";\nimport {\n buildAccount,\n getFeature,\n pickAccountByAddress,\n pickFirstAddress,\n slugify as kitSlugify,\n} from \"@usebutr/wallet-standard-shared\";\nimport type {\n StandardConnectFeature,\n StandardDisconnectFeature,\n StandardEventsFeature,\n WalletStandardWallet,\n} 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\nconst pickPolkadotChain = (wallet: WalletStandardWallet): string | null =>\n wallet.chains.find((c) => c.startsWith(POLKADOT_PREFIX)) ?? null;\n\nconst buildChain = (chainId: string, walletName: string): ChainBase => ({\n id: chainId,\n name: walletName,\n namespace: \"polkadot\",\n reference: chainId.slice(POLKADOT_PREFIX.length),\n});\n\nconst buildWsAccount = (address: string, chain: ChainBase): Account => buildAccount(address, chain);\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 registerDisconnector?: (emit: () => void) => void,\n): WalletAdapter | null => {\n const chainId = pickPolkadotChain(wallet);\n if (!chainId) {\n return null;\n }\n const connect = getFeature<StandardConnectFeature>(wallet, \"standard:connect\");\n if (!connect) {\n return null;\n }\n\n const disconnect = getFeature<StandardDisconnectFeature>(wallet, \"standard:disconnect\");\n const events = getFeature<StandardEventsFeature>(wallet, \"standard:events\");\n const signMessage = getFeature<PolkadotSignMessageFeature>(wallet, \"polkadot:signMessage\");\n\n let currentChainId = chainId;\n const currentChain = (): ChainBase => buildChain(currentChainId, wallet.name);\n\n const listeners = new Set<(event: ConnectorEvent) => void>();\n const notifyAccountChanged = () => {\n if (wallet.accounts.length === 0) {\n return;\n }\n const chain = currentChain();\n const built = wallet.accounts.map((a) => buildWsAccount(a.address, chain));\n const first = built[0];\n if (!first) {\n return;\n }\n for (const listener of listeners) {\n listener({ account: first, accounts: built, type: \"accountChanged\" });\n }\n };\n\n registerDisconnector?.(() => {\n for (const listener of listeners) {\n listener({ type: \"disconnected\" });\n }\n });\n\n return {\n capabilities: resolveWalletStandardPolkadotCapabilities({\n chainCount: wallet.chains.filter((c) => c.startsWith(POLKADOT_PREFIX)).length,\n features: { events: Boolean(events), signMessage: Boolean(signMessage) },\n }),\n chainPlatform: \"polkadot\",\n\n async connect(opts) {\n await connect.connect(opts?.silent ? { silent: true } : undefined);\n },\n\n async disconnect() {\n if (disconnect) {\n try {\n await disconnect.disconnect();\n } catch (error) {\n logWarn(\"[butr] Polkadot Wallet Standard disconnect threw:\", error);\n }\n }\n },\n\n getAccount() {\n const address = pickFirstAddress(wallet.accounts);\n return Promise.resolve(address ? buildWsAccount(address, currentChain()) : null);\n },\n\n getAccounts() {\n const chain = currentChain();\n return Promise.resolve(wallet.accounts.map((a) => buildWsAccount(a.address, chain)));\n },\n\n getBalance: noRpcBalance,\n\n getSigner() {\n return Promise.resolve(wallet);\n },\n\n getTransactionReceipt: noRpcTransactionReceipt,\n\n icon: sanitizeIcon(wallet.icon),\n id: slugify(wallet.name),\n name: wallet.name,\n\n sendTx: noRpcSendTx,\n\n sendTxToChain: noRpcSendTxToChain,\n\n async signMessage(msg, account) {\n if (!signMessage) {\n throw new Error(`Wallet ${wallet.name} does not advertise polkadot:signMessage`);\n }\n const wsAccount = account\n ? pickAccountByAddress(wallet.accounts, account.walletAddress)\n : (wallet.accounts[0] ?? null);\n if (!wsAccount) {\n throw new Error(\"No connected account\");\n }\n const output = await signMessage.signMessage({ account: wsAccount, message: msg });\n return { signature: output.signature, signedMessage: output.signedMessage ?? msg };\n },\n\n subscribe(listener) {\n listeners.add(listener);\n let unsubWallet: (() => void) | null = null;\n if (events) {\n const unsub = events.on(\"change\", (changes) => {\n if (changes.accounts) {\n if (changes.accounts.length === 0) {\n listener({ type: \"disconnected\" });\n return;\n }\n const chain = currentChain();\n const built = changes.accounts.map((a) => buildWsAccount(a.address, chain));\n const first = built[0];\n if (first) {\n listener({ account: first, accounts: built, type: \"accountChanged\" });\n }\n }\n });\n unsubWallet = () => unsub();\n }\n return () => {\n listeners.delete(listener);\n unsubWallet?.();\n };\n },\n\n 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 if (!wallet.chains.includes(target.id)) {\n throw new Error(\n `Wallet ${wallet.name} does not advertise chain \"${target.id}\". Available: ${wallet.chains.join(\", \")}`,\n );\n }\n currentChainId = target.id;\n notifyAccountChanged();\n return Promise.resolve();\n },\n };\n};\n\nexport { buildPolkadotWalletStandardAdapter };\n","import type { WalletAdapter } from \"@usebutr/core\";\nimport { discoverWalletStandard } from \"@usebutr/wallet-standard-shared\";\n\nimport { buildPolkadotWalletStandardAdapter } from \"./wallet-standard-adapter\";\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 { discoverPolkadotWalletStandardAdapters };\n","import type { PlatformDiscoverer } from \"@usebutr/core\";\n\nimport { discoverInjectedPolkadotAdapters } from \"./injected\";\nimport { discoverPolkadotWalletStandardAdapters } from \"./wallet-standard\";\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 platform: \"polkadot\",\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/wallet-standard.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\";\n\ntype WalletStandardPolkadotCapabilityInput = {\n chainCount: number;\n features: {\n events: boolean;\n signMessage: boolean;\n };\n};\n\n// butr ships no RPC: getBalance / getTransactionReceipt / sendTransaction\n// are always false on Polkadot. signTransaction is false too — building a\n// Substrate extrinsic needs chain metadata, so transaction signing goes\n// through getSigner() (consumer drives polkadot-api). requestAccounts is\n// false: extensions manage account exposure in their own UI.\n\n/**\n * injectedWeb3 capability profile. The injected `signer.signRaw` always\n * supports message signing; `accounts.subscribe` always supports events;\n * butr authors the chain list (4 chains) so local switchChain is always\n * available.\n */\nconst resolveInjectedPolkadotCapabilities = (): WalletCapabilities => ({\n getBalance: false,\n getTransactionReceipt: false,\n requestAccounts: false,\n sendTransaction: false,\n signIn: false,\n signMessage: true,\n signTransaction: false,\n subscribe: true,\n switchAccount: false,\n switchChain: true,\n});\n\n/**\n * Wallet Standard `polkadot:*` capability mapping. Mirrors the Sui/SVM\n * resolvers: features come from what the wallet advertises; switchChain\n * follows chainCount (local re-routing among advertised chains).\n */\nconst resolveWalletStandardPolkadotCapabilities = (\n input: WalletStandardPolkadotCapabilityInput,\n): WalletCapabilities => ({\n getBalance: false,\n getTransactionReceipt: false,\n requestAccounts: false,\n sendTransaction: false,\n signIn: false,\n signMessage: input.features.signMessage,\n signTransaction: false,\n subscribe: input.features.events,\n switchAccount: false,\n switchChain: input.chainCount > 1,\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\n// Neutral, chain-agnostic placeholder. The registry spans DOT/KSM/WND/PAS\n// with different symbols and decimals, so a hardcoded \"DOT\"/10 would be\n// wrong for most of them. Consumers read real balances via polkadot-api.\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","// Generic Polkadot mark (pink dot), data-URI so the connector ships no\n// asset files. Mirrors @usebutr/bitcoin's GENERIC_BITCOIN_ICON approach.\nconst 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\n// `<Bytes>` / `</Bytes>` wrapper polkadot-js, Talisman, and SubWallet add\n// around raw messages before signing (prevents signed messages from being\n// replayed as transaction payloads). Verifiers must check signatures\n// against the wrapped bytes, which is why butr returns them as\n// `signedMessage`.\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 return typeof window === \"undefined\" ? null : (window as unknown as InjectedWindow);\n};\n\nexport type { Injected, InjectedAccount, InjectedSigner, InjectedWindow, InjectedWindowProvider };\n// Polkadot uses 0x-prefixed hex; alias the shared prefixed variant to the\n// existing local name so internal callers stay unchanged.\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) {\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) {\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 ? buildPolkadotAccount(address, chain) : null;\n },\n\n async getAccounts() {\n if (!injected) {\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) {\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) {\n throw new Error(`Wallet ${displayName} does not expose signRaw`);\n }\n const address = account?.walletAddress ?? (await firstAddress());\n if (!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) {\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 // Substrate accounts are chain-agnostic; switching is local state\n // that tells consumers which chain context to target.\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\n// Display-name overrides for known registry keys. Unknown keys fall back\n// to a title-cased version of the key.\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 { Account, ChainBase, ConnectorEvent, WalletAdapter } from \"@usebutr/core\";\nimport { logWarn, sanitizeIcon } from \"@usebutr/core\";\nimport {\n buildAccount,\n getFeature,\n pickAccountByAddress,\n pickFirstAddress,\n slugify as kitSlugify,\n} from \"@usebutr/wallet-standard-shared\";\nimport type {\n StandardConnectFeature,\n StandardDisconnectFeature,\n StandardEventsFeature,\n WalletStandardWallet,\n} 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\nconst pickPolkadotChain = (wallet: WalletStandardWallet): string | null =>\n wallet.chains.find((c) => c.startsWith(POLKADOT_PREFIX)) ?? null;\n\nconst buildChain = (chainId: string, walletName: string): ChainBase => ({\n id: chainId,\n name: walletName,\n namespace: \"polkadot\",\n reference: chainId.slice(POLKADOT_PREFIX.length),\n});\n\nconst buildWsAccount = (address: string, chain: ChainBase): Account => buildAccount(address, chain);\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 registerDisconnector?: (emit: () => void) => void,\n): WalletAdapter | null => {\n const chainId = pickPolkadotChain(wallet);\n if (!chainId) {\n return null;\n }\n const connect = getFeature<StandardConnectFeature>(wallet, \"standard:connect\");\n if (!connect) {\n return null;\n }\n\n const disconnect = getFeature<StandardDisconnectFeature>(wallet, \"standard:disconnect\");\n const events = getFeature<StandardEventsFeature>(wallet, \"standard:events\");\n const signMessage = getFeature<PolkadotSignMessageFeature>(wallet, \"polkadot:signMessage\");\n\n let currentChainId = chainId;\n const currentChain = (): ChainBase => buildChain(currentChainId, wallet.name);\n\n const listeners = new Set<(event: ConnectorEvent) => void>();\n const notifyAccountChanged = () => {\n if (wallet.accounts.length === 0) {\n return;\n }\n const chain = currentChain();\n const built = wallet.accounts.map((a) => buildWsAccount(a.address, chain));\n const first = built[0];\n if (!first) {\n return;\n }\n for (const listener of listeners) {\n listener({ account: first, accounts: built, type: \"accountChanged\" });\n }\n };\n\n registerDisconnector?.(() => {\n for (const listener of listeners) {\n listener({ type: \"disconnected\" });\n }\n });\n\n return {\n capabilities: resolveWalletStandardPolkadotCapabilities({\n chainCount: wallet.chains.filter((c) => c.startsWith(POLKADOT_PREFIX)).length,\n features: { events: Boolean(events), signMessage: Boolean(signMessage) },\n }),\n chainPlatform: \"polkadot\",\n\n async connect(opts) {\n await connect.connect(opts?.silent ? { silent: true } : undefined);\n },\n\n async disconnect() {\n if (disconnect) {\n try {\n await disconnect.disconnect();\n } catch (error) {\n logWarn(\"[butr] Polkadot Wallet Standard disconnect threw:\", error);\n }\n }\n },\n\n getAccount() {\n const address = pickFirstAddress(wallet.accounts);\n return Promise.resolve(address ? buildWsAccount(address, currentChain()) : null);\n },\n\n getAccounts() {\n const chain = currentChain();\n return Promise.resolve(wallet.accounts.map((a) => buildWsAccount(a.address, chain)));\n },\n\n getBalance: noRpcBalance,\n\n getSigner() {\n return Promise.resolve(wallet);\n },\n\n getTransactionReceipt: noRpcTransactionReceipt,\n\n icon: sanitizeIcon(wallet.icon),\n id: slugify(wallet.name),\n name: wallet.name,\n\n sendTx: noRpcSendTx,\n\n sendTxToChain: noRpcSendTxToChain,\n\n async signMessage(msg, account) {\n if (!signMessage) {\n throw new Error(`Wallet ${wallet.name} does not advertise polkadot:signMessage`);\n }\n const wsAccount = account\n ? pickAccountByAddress(wallet.accounts, account.walletAddress)\n : (wallet.accounts[0] ?? null);\n if (!wsAccount) {\n throw new Error(\"No connected account\");\n }\n const output = await signMessage.signMessage({ account: wsAccount, message: msg });\n return { signature: output.signature, signedMessage: output.signedMessage ?? msg };\n },\n\n subscribe(listener) {\n listeners.add(listener);\n let unsubWallet: (() => void) | null = null;\n if (events) {\n const unsub = events.on(\"change\", (changes) => {\n if (changes.accounts) {\n if (changes.accounts.length === 0) {\n listener({ type: \"disconnected\" });\n return;\n }\n const chain = currentChain();\n const built = changes.accounts.map((a) => buildWsAccount(a.address, chain));\n const first = built[0];\n if (first) {\n listener({ account: first, accounts: built, type: \"accountChanged\" });\n }\n }\n });\n unsubWallet = () => unsub();\n }\n return () => {\n listeners.delete(listener);\n unsubWallet?.();\n };\n },\n\n 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 if (!wallet.chains.includes(target.id)) {\n throw new Error(\n `Wallet ${wallet.name} does not advertise chain \"${target.id}\". Available: ${wallet.chains.join(\", \")}`,\n );\n }\n currentChainId = target.id;\n notifyAccountChanged();\n return Promise.resolve();\n },\n };\n};\n\nexport { buildPolkadotWalletStandardAdapter };\n","import type { WalletAdapter } from \"@usebutr/core\";\nimport { discoverWalletStandard } from \"@usebutr/wallet-standard-shared\";\n\nimport { buildPolkadotWalletStandardAdapter } from \"./wallet-standard-adapter\";\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 { discoverPolkadotWalletStandardAdapters };\n","import type { PlatformDiscoverer } from \"@usebutr/core\";\n\nimport { discoverInjectedPolkadotAdapters } from \"./injected\";\nimport { discoverPolkadotWalletStandardAdapters } from \"./wallet-standard\";\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 platform: \"polkadot\",\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": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "injectedWeb3 + Wallet Standard adapter for butr (Polkadot/Substrate).",
5
5
  "license": "MIT",
6
6
  "author": "Pedro Filho <pedro@filho.me>",
@@ -25,13 +25,13 @@
25
25
  "access": "public"
26
26
  },
27
27
  "dependencies": {
28
- "@usebutr/core": "0.3.0",
29
- "@usebutr/wallet-standard-shared": "0.2.3"
28
+ "@usebutr/wallet-standard-shared": "0.2.5",
29
+ "@usebutr/core": "0.4.1"
30
30
  },
31
31
  "devDependencies": {
32
- "@wallet-standard/app": "^1.1.0",
32
+ "@wallet-standard/app": "^1.1.1",
33
33
  "typescript": "^6.0.3",
34
- "vitest": "^4.1.8",
34
+ "vitest": "^4.1.9",
35
35
  "@repo/config-vitest": "0.0.0",
36
36
  "@repo/typescript-config": "0.0.0"
37
37
  },