@le-space/p2pass 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export const VERSION: "0.1.0";
1
+ export const VERSION: "0.3.1";
2
2
  export { MultiDeviceManager } from "./registry/manager.js";
3
3
  import StorachaIntegration from './ui/StorachaIntegration.svelte';
4
4
  import StorachaFab from './ui/StorachaFab.svelte';
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // @le-space/p2pass — public API
2
- export const VERSION = '0.1.0';
2
+ export const VERSION = '0.3.1';
3
3
 
4
4
  // Explicit default bindings (not `export { default as X } from`) — avoids star-export / default resolution errors in Vite.
5
5
  import StorachaIntegration from './ui/StorachaIntegration.svelte';
@@ -778,6 +778,15 @@
778
778
  const dbAddr = registryDb.address?.toString?.() || registryDb.address;
779
779
  if (dbAddr) await deviceManager.openExistingDb(dbAddr);
780
780
 
781
+ // Use the same KV instance as MultiDeviceManager (sync listeners + replication). A second
782
+ // `openDeviceRegistry(..., sameAddress)` in openExistingDb is a distinct replica; reading
783
+ // `registryDb` from initRegistryDb after reload could list fewer devices than the manager.
784
+ const managedDb = deviceManager.getRegistryDb();
785
+ if (managedDb) {
786
+ registryDb = managedDb;
787
+ await identityService.setRegistry(registryDb);
788
+ }
789
+
781
790
  devices = await deviceManager.listDevices();
782
791
  peerInfo = deviceManager.getPeerInfo();
783
792
  console.log('[ui] MultiDeviceManager initialized');
@@ -790,9 +799,13 @@
790
799
 
791
800
  async function handleTabSwitch(tab) {
792
801
  activeTab = tab;
793
- if (tab === 'passkeys' && registryDb) {
802
+ if (tab === 'passkeys') {
794
803
  try {
795
- devices = await listRegistryDevices(registryDb);
804
+ if (deviceManager) {
805
+ devices = await deviceManager.listDevices();
806
+ } else if (registryDb) {
807
+ devices = await listRegistryDevices(registryDb);
808
+ }
796
809
  } catch (err) {
797
810
  console.warn('[ui] Failed to load devices:', err.message);
798
811
  }
@@ -1227,6 +1240,91 @@
1227
1240
  {/if}
1228
1241
  {/snippet}
1229
1242
 
1243
+ {#snippet yourDidCard()}
1244
+ <div
1245
+ data-testid="storacha-your-did"
1246
+ style="border-radius: 0.375rem; border: 1px solid rgba(233, 19, 21, 0.3); background: linear-gradient(to right, #ffffff, #EFE3F3); padding: 0.625rem 0.75rem; box-shadow: 0 1px 2px 0 rgba(0,0,0,0.05);"
1247
+ >
1248
+ <div
1249
+ style="font-size: 0.625rem; font-weight: 600; color: #6b7280; font-family: 'DM Sans', sans-serif; margin-bottom: 0.25rem; text-transform: uppercase; letter-spacing: 0.05em;"
1250
+ >
1251
+ Your DID
1252
+ </div>
1253
+ <div style="display: flex; align-items: center; gap: 0.5rem;">
1254
+ <code
1255
+ style="flex: 1; font-size: 0.75rem; color: #374151; font-family: 'DM Mono', monospace; word-break: break-all; line-height: 1.4;"
1256
+ >
1257
+ {signingMode?.did
1258
+ ? signingMode.did.length > 40
1259
+ ? signingMode.did.slice(0, 20) + '...' + signingMode.did.slice(-16)
1260
+ : signingMode.did
1261
+ : 'N/A'}
1262
+ </code>
1263
+ <button
1264
+ class="storacha-btn-icon"
1265
+ onclick={() => {
1266
+ if (signingMode?.did) {
1267
+ navigator.clipboard.writeText(signingMode.did);
1268
+ showMessage('DID copied to clipboard!');
1269
+ }
1270
+ }}
1271
+ style="border-radius: 0.25rem; padding: 0.25rem; color: #0176CE; transition: all 150ms; border: none; background: transparent; cursor: pointer; flex-shrink: 0;"
1272
+ title="Copy full DID"
1273
+ aria-label="Copy DID to clipboard"
1274
+ >
1275
+ <svg
1276
+ style="height: 0.875rem; width: 0.875rem;"
1277
+ fill="none"
1278
+ viewBox="0 0 24 24"
1279
+ stroke="currentColor"
1280
+ >
1281
+ <path
1282
+ stroke-linecap="round"
1283
+ stroke-linejoin="round"
1284
+ stroke-width="2"
1285
+ d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"
1286
+ />
1287
+ </svg>
1288
+ </button>
1289
+ </div>
1290
+ </div>
1291
+ {/snippet}
1292
+
1293
+ {#snippet storachaConnectedBanner()}
1294
+ <div
1295
+ style="display: flex; align-items: center; justify-content: space-between; border-radius: 0.375rem; border: 1px solid #E91315; background: linear-gradient(to right, #BDE0FF, #FFE4AE); padding: 0.75rem; box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.1);"
1296
+ >
1297
+ <div style="display: flex; align-items: center; gap: 0.75rem;">
1298
+ <div
1299
+ style="display: flex; height: 2rem; width: 2rem; align-items: center; justify-content: center; border-radius: 9999px; background-color: #E91315; box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1); flex-shrink: 0;"
1300
+ >
1301
+ <CheckCircle style="height: 1rem; width: 1rem; color: #ffffff;" />
1302
+ </div>
1303
+ <div>
1304
+ <div
1305
+ style="font-size: 0.875rem; font-weight: 700; color: #E91315; font-family: 'Epilogue', sans-serif;"
1306
+ >
1307
+ Connected to Storacha
1308
+ </div>
1309
+ {#if currentSpace}
1310
+ <div style="font-size: 0.75rem; color: #0176CE; font-family: 'DM Mono', monospace;">
1311
+ Space: {formatSpaceName(currentSpace)}
1312
+ </div>
1313
+ {/if}
1314
+ </div>
1315
+ </div>
1316
+
1317
+ <button
1318
+ class="storacha-btn-icon"
1319
+ onclick={handleLogout}
1320
+ style="display: flex; align-items: center; gap: 0.25rem; padding: 0.25rem 0.75rem; font-size: 0.875rem; color: #E91315; transition: color 150ms, background-color 150ms; border: none; background: transparent; cursor: pointer; font-family: 'DM Sans', sans-serif;"
1321
+ >
1322
+ <LogOut style="height: 0.75rem; width: 0.75rem;" />
1323
+ <span>Logout</span>
1324
+ </button>
1325
+ </div>
1326
+ {/snippet}
1327
+
1230
1328
  {#snippet linkedDevicesPanel()}
1231
1329
  <div
1232
1330
  style="border-radius: 0.375rem; border: 1px solid #E91315; background: linear-gradient(to bottom right, #ffffff, #FFE4AE); padding: 0.75rem;"
@@ -1741,7 +1839,7 @@
1741
1839
  </button>
1742
1840
  </div>
1743
1841
  {:else}
1744
- <!-- Step 2: Authenticated — show DID info + delegation import -->
1842
+ <!-- Step 2: Authenticated — signing badge; DID + tab panels render below tabs -->
1745
1843
  <div
1746
1844
  data-testid="storacha-post-auth"
1747
1845
  style="display: flex; flex-direction: column; gap: 0.75rem;"
@@ -1807,118 +1905,48 @@
1807
1905
  </span>
1808
1906
  {/if}
1809
1907
  </div>
1908
+ </div>
1909
+ {/if}
1810
1910
 
1811
- <!-- DID Display -->
1812
- <div
1813
- style="border-radius: 0.375rem; border: 1px solid rgba(233, 19, 21, 0.3); background: linear-gradient(to right, #ffffff, #EFE3F3); padding: 0.625rem 0.75rem; box-shadow: 0 1px 2px 0 rgba(0,0,0,0.05);"
1911
+ {#if signingMode}
1912
+ <!-- Tab Navigation (visible after authentication) — P2P Passkeys first -->
1913
+ <div
1914
+ style="border-radius: 0.5rem; background: rgba(233, 19, 21, 0.06); padding: 0.25rem; display: flex; gap: 0.25rem;"
1915
+ >
1916
+ <button
1917
+ data-testid="storacha-tab-passkeys"
1918
+ onclick={() => handleTabSwitch('passkeys')}
1919
+ style="flex: 1; padding: 0.5rem 1rem; border-radius: 0.375rem; border: none; cursor: pointer; font-family: 'Epilogue', sans-serif; font-size: 0.8rem; font-weight: 600; transition: all 200ms; background: {activeTab ===
1920
+ 'passkeys'
1921
+ ? 'linear-gradient(135deg, #E91315, #FFC83F)'
1922
+ : 'transparent'}; color: {activeTab === 'passkeys'
1923
+ ? '#fff'
1924
+ : '#6B7280'}; box-shadow: {activeTab === 'passkeys'
1925
+ ? '0 2px 8px rgba(233, 19, 21, 0.3)'
1926
+ : 'none'};"
1814
1927
  >
1815
- <div
1816
- style="font-size: 0.625rem; font-weight: 600; color: #6b7280; font-family: 'DM Sans', sans-serif; margin-bottom: 0.25rem; text-transform: uppercase; letter-spacing: 0.05em;"
1817
- >
1818
- Your DID
1819
- </div>
1820
- <div style="display: flex; align-items: center; gap: 0.5rem;">
1821
- <code
1822
- style="flex: 1; font-size: 0.75rem; color: #374151; font-family: 'DM Mono', monospace; word-break: break-all; line-height: 1.4;"
1823
- >
1824
- {signingMode.did
1825
- ? signingMode.did.length > 40
1826
- ? signingMode.did.slice(0, 20) + '...' + signingMode.did.slice(-16)
1827
- : signingMode.did
1828
- : 'N/A'}
1829
- </code>
1830
- <button
1831
- class="storacha-btn-icon"
1832
- onclick={() => {
1833
- if (signingMode.did) {
1834
- navigator.clipboard.writeText(signingMode.did);
1835
- showMessage('DID copied to clipboard!');
1836
- }
1837
- }}
1838
- style="border-radius: 0.25rem; padding: 0.25rem; color: #0176CE; transition: all 150ms; border: none; background: transparent; cursor: pointer; flex-shrink: 0;"
1839
- title="Copy full DID"
1840
- aria-label="Copy DID to clipboard"
1841
- >
1842
- <svg
1843
- style="height: 0.875rem; width: 0.875rem;"
1844
- fill="none"
1845
- viewBox="0 0 24 24"
1846
- stroke="currentColor"
1847
- >
1848
- <path
1849
- stroke-linecap="round"
1850
- stroke-linejoin="round"
1851
- stroke-width="2"
1852
- d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"
1853
- />
1854
- </svg>
1855
- </button>
1856
- </div>
1857
- </div>
1928
+ P2P Passkeys
1929
+ </button>
1930
+ <button
1931
+ data-testid="storacha-tab-storacha"
1932
+ onclick={() => handleTabSwitch('storacha')}
1933
+ style="flex: 1; padding: 0.5rem 1rem; border-radius: 0.375rem; border: none; cursor: pointer; font-family: 'Epilogue', sans-serif; font-size: 0.8rem; font-weight: 600; transition: all 200ms; background: {activeTab ===
1934
+ 'storacha'
1935
+ ? 'linear-gradient(135deg, #E91315, #FFC83F)'
1936
+ : 'transparent'}; color: {activeTab === 'storacha'
1937
+ ? '#fff'
1938
+ : '#6B7280'}; box-shadow: {activeTab === 'storacha'
1939
+ ? '0 2px 8px rgba(233, 19, 21, 0.3)'
1940
+ : 'none'};"
1941
+ >
1942
+ Storacha
1943
+ </button>
1944
+ </div>
1858
1945
 
1859
- {#if activeTab !== 'passkeys'}
1860
- <!-- Delegation Import -->
1861
- <div
1862
- style="border-radius: 0.375rem; border: 1px solid #E91315; background: linear-gradient(to bottom right, #ffffff, #EFE3F3); padding: 1rem; box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.1);"
1863
- >
1864
- <h4
1865
- style="margin-bottom: 0.5rem; font-weight: 700; color: #E91315; font-family: 'Epilogue', sans-serif; font-size: 0.875rem;"
1866
- >
1867
- Import UCAN Delegation
1868
- </h4>
1869
- <p
1870
- style="margin-bottom: 0.75rem; font-size: 0.75rem; color: #6b7280; font-family: 'DM Sans', sans-serif; line-height: 1.4;"
1871
- >
1872
- Paste a <strong>Storacha UCAN delegation</strong> (from w3up, the CLI, or copied
1873
- from a browser that already has access) to reach your space. This is not for
1874
- linking devices over libp2p — use the <strong>P2P Passkeys</strong> tab and peer JSON
1875
- for that.
1876
- </p>
1877
- <div style="display: flex; flex-direction: column; gap: 0.75rem;">
1878
- <textarea
1879
- class="storacha-textarea"
1880
- data-testid="storacha-delegation-textarea"
1881
- bind:value={delegationText}
1882
- placeholder="Paste your UCAN delegation here (base64 encoded)..."
1883
- rows="4"
1884
- style="width: 100%; resize: none; border-radius: 0.375rem; border: 1px solid #E91315; background-color: #ffffff; padding: 0.5rem 0.75rem; font-size: 0.75rem; color: #111827; font-family: 'DM Mono', monospace; outline: none; box-sizing: border-box;"
1885
- ></textarea>
1886
- <button
1887
- class="storacha-btn-primary"
1888
- data-testid="storacha-delegation-import"
1889
- onclick={handleImportDelegation}
1890
- disabled={isLoading || !delegationText.trim()}
1891
- style="display: flex; width: 100%; align-items: center; justify-content: center; gap: 0.5rem; border-radius: 0.375rem; background-color: #E91315; padding: 0.5rem 1rem; color: #ffffff; box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1); transition: color 150ms, background-color 150ms; border: none; cursor: pointer; font-family: 'Epilogue', sans-serif; font-weight: 600; opacity: {isLoading ||
1892
- !delegationText.trim()
1893
- ? '0.5'
1894
- : '1'}; box-sizing: border-box;"
1895
- >
1896
- {#if isLoading}
1897
- <Loader2
1898
- style="height: 1rem; width: 1rem; animation: spin 1s linear infinite;"
1899
- />
1900
- <span>Connecting...</span>
1901
- {:else}
1902
- <svg
1903
- style="height: 1rem; width: 1rem;"
1904
- fill="none"
1905
- viewBox="0 0 24 24"
1906
- stroke="currentColor"
1907
- >
1908
- <path
1909
- stroke-linecap="round"
1910
- stroke-linejoin="round"
1911
- stroke-width="2"
1912
- d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"
1913
- />
1914
- </svg>
1915
- <span>Connect</span>
1916
- {/if}
1917
- </button>
1918
- </div>
1919
- </div>
1920
- {:else}
1921
- <!-- Link Device (peer id) -->
1946
+ {#if activeTab === 'passkeys'}
1947
+ <div style="display: flex; flex-direction: column; gap: 0.75rem;">
1948
+ {@render yourDidCard()}
1949
+ <!-- Link Device (peer id) pre–Storacha-login flow -->
1922
1950
  <div
1923
1951
  style="border-radius: 0.375rem; border: 1px solid #E91315; background: linear-gradient(to bottom right, #ffffff, #FFE4AE); padding: 1rem; box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.1);"
1924
1952
  >
@@ -2000,47 +2028,6 @@
2000
2028
  </button>
2001
2029
  </div>
2002
2030
  </div>
2003
- {/if}
2004
- </div>
2005
- {/if}
2006
-
2007
- {#if signingMode}
2008
- <!-- Tab Navigation (visible after authentication) — P2P Passkeys first -->
2009
- <div
2010
- style="border-radius: 0.5rem; background: rgba(233, 19, 21, 0.06); padding: 0.25rem; display: flex; gap: 0.25rem;"
2011
- >
2012
- <button
2013
- data-testid="storacha-tab-passkeys"
2014
- onclick={() => handleTabSwitch('passkeys')}
2015
- style="flex: 1; padding: 0.5rem 1rem; border-radius: 0.375rem; border: none; cursor: pointer; font-family: 'Epilogue', sans-serif; font-size: 0.8rem; font-weight: 600; transition: all 200ms; background: {activeTab ===
2016
- 'passkeys'
2017
- ? 'linear-gradient(135deg, #E91315, #FFC83F)'
2018
- : 'transparent'}; color: {activeTab === 'passkeys'
2019
- ? '#fff'
2020
- : '#6B7280'}; box-shadow: {activeTab === 'passkeys'
2021
- ? '0 2px 8px rgba(233, 19, 21, 0.3)'
2022
- : 'none'};"
2023
- >
2024
- P2P Passkeys
2025
- </button>
2026
- <button
2027
- data-testid="storacha-tab-storacha"
2028
- onclick={() => handleTabSwitch('storacha')}
2029
- style="flex: 1; padding: 0.5rem 1rem; border-radius: 0.375rem; border: none; cursor: pointer; font-family: 'Epilogue', sans-serif; font-size: 0.8rem; font-weight: 600; transition: all 200ms; background: {activeTab ===
2030
- 'storacha'
2031
- ? 'linear-gradient(135deg, #E91315, #FFC83F)'
2032
- : 'transparent'}; color: {activeTab === 'storacha'
2033
- ? '#fff'
2034
- : '#6B7280'}; box-shadow: {activeTab === 'storacha'
2035
- ? '0 2px 8px rgba(233, 19, 21, 0.3)'
2036
- : 'none'};"
2037
- >
2038
- Storacha
2039
- </button>
2040
- </div>
2041
-
2042
- {#if activeTab === 'passkeys'}
2043
- <div style="display: flex; flex-direction: column; gap: 0.75rem;">
2044
2031
  <!-- Connection Status + Copy -->
2045
2032
  <div
2046
2033
  style="border-radius: 0.375rem; border: 1px solid #E91315; background: linear-gradient(to right, #ffffff, #FFE4AE); padding: 0.625rem 0.75rem;"
@@ -2111,46 +2098,74 @@
2111
2098
 
2112
2099
  {@render linkedDevicesPanel()}
2113
2100
  </div>
2101
+ {:else if activeTab === 'storacha'}
2102
+ <div style="display: flex; flex-direction: column; gap: 0.75rem;">
2103
+ <div
2104
+ style="border-radius: 0.375rem; border: 1px solid #E91315; background: linear-gradient(to bottom right, #ffffff, #EFE3F3); padding: 1rem; box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.1);"
2105
+ >
2106
+ <h4
2107
+ style="margin-bottom: 0.5rem; font-weight: 700; color: #E91315; font-family: 'Epilogue', sans-serif; font-size: 0.875rem;"
2108
+ >
2109
+ Import UCAN Delegation
2110
+ </h4>
2111
+ <p
2112
+ style="margin-bottom: 0.75rem; font-size: 0.75rem; color: #6b7280; font-family: 'DM Sans', sans-serif; line-height: 1.4;"
2113
+ >
2114
+ Paste a <strong>Storacha UCAN delegation</strong> (from w3up, the CLI, or copied
2115
+ from a browser that already has access) to reach your space. This is not for
2116
+ linking devices over libp2p — use the <strong>P2P Passkeys</strong> tab and peer JSON
2117
+ for that.
2118
+ </p>
2119
+ <div style="display: flex; flex-direction: column; gap: 0.75rem;">
2120
+ <textarea
2121
+ class="storacha-textarea"
2122
+ data-testid="storacha-delegation-textarea"
2123
+ bind:value={delegationText}
2124
+ placeholder="Paste your UCAN delegation here (base64 encoded)..."
2125
+ rows="4"
2126
+ style="width: 100%; resize: none; border-radius: 0.375rem; border: 1px solid #E91315; background-color: #ffffff; padding: 0.5rem 0.75rem; font-size: 0.75rem; color: #111827; font-family: 'DM Mono', monospace; outline: none; box-sizing: border-box;"
2127
+ ></textarea>
2128
+ <button
2129
+ class="storacha-btn-primary"
2130
+ data-testid="storacha-delegation-import"
2131
+ onclick={handleImportDelegation}
2132
+ disabled={isLoading || !delegationText.trim()}
2133
+ style="display: flex; width: 100%; align-items: center; justify-content: center; gap: 0.5rem; border-radius: 0.375rem; background-color: #E91315; padding: 0.5rem 1rem; color: #ffffff; box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1); transition: color 150ms, background-color 150ms; border: none; cursor: pointer; font-family: 'Epilogue', sans-serif; font-weight: 600; opacity: {isLoading ||
2134
+ !delegationText.trim()
2135
+ ? '0.5'
2136
+ : '1'}; box-sizing: border-box;"
2137
+ >
2138
+ {#if isLoading}
2139
+ <Loader2
2140
+ style="height: 1rem; width: 1rem; animation: spin 1s linear infinite;"
2141
+ />
2142
+ <span>Connecting...</span>
2143
+ {:else}
2144
+ <svg
2145
+ style="height: 1rem; width: 1rem;"
2146
+ fill="none"
2147
+ viewBox="0 0 24 24"
2148
+ stroke="currentColor"
2149
+ >
2150
+ <path
2151
+ stroke-linecap="round"
2152
+ stroke-linejoin="round"
2153
+ stroke-width="2"
2154
+ d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"
2155
+ />
2156
+ </svg>
2157
+ <span>Connect</span>
2158
+ {/if}
2159
+ </button>
2160
+ </div>
2161
+ </div>
2162
+ </div>
2114
2163
  {/if}
2115
2164
  {/if}
2116
2165
  </div>
2117
2166
  {:else}
2118
2167
  <!-- Logged In Section -->
2119
2168
  <div style="display: flex; flex-direction: column; gap: 1rem;">
2120
- <!-- Account Info -->
2121
- <div
2122
- style="display: flex; align-items: center; justify-content: space-between; border-radius: 0.375rem; border: 1px solid #E91315; background: linear-gradient(to right, #BDE0FF, #FFE4AE); padding: 0.75rem; box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.1);"
2123
- >
2124
- <div style="display: flex; align-items: center; gap: 0.75rem;">
2125
- <div
2126
- style="display: flex; height: 2rem; width: 2rem; align-items: center; justify-content: center; border-radius: 9999px; background-color: #E91315; box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1); flex-shrink: 0;"
2127
- >
2128
- <CheckCircle style="height: 1rem; width: 1rem; color: #ffffff;" />
2129
- </div>
2130
- <div>
2131
- <div
2132
- style="font-size: 0.875rem; font-weight: 700; color: #E91315; font-family: 'Epilogue', sans-serif;"
2133
- >
2134
- Connected to Storacha
2135
- </div>
2136
- {#if currentSpace}
2137
- <div style="font-size: 0.75rem; color: #0176CE; font-family: 'DM Mono', monospace;">
2138
- Space: {formatSpaceName(currentSpace)}
2139
- </div>
2140
- {/if}
2141
- </div>
2142
- </div>
2143
-
2144
- <button
2145
- class="storacha-btn-icon"
2146
- onclick={handleLogout}
2147
- style="display: flex; align-items: center; gap: 0.25rem; padding: 0.25rem 0.75rem; font-size: 0.875rem; color: #E91315; transition: color 150ms, background-color 150ms; border: none; background: transparent; cursor: pointer; font-family: 'DM Sans', sans-serif;"
2148
- >
2149
- <LogOut style="height: 0.75rem; width: 0.75rem;" />
2150
- <span>Logout</span>
2151
- </button>
2152
- </div>
2153
-
2154
2169
  <!-- Tab Navigation — P2P Passkeys first -->
2155
2170
  <div
2156
2171
  style="border-radius: 0.5rem; background: rgba(233, 19, 21, 0.06); padding: 0.25rem; display: flex; gap: 0.25rem;"
@@ -2186,8 +2201,10 @@
2186
2201
  </div>
2187
2202
 
2188
2203
  {#if activeTab === 'storacha'}
2189
- <!-- Action Buttons -->
2190
2204
  <div style="display: flex; flex-direction: column; gap: 0.75rem;">
2205
+ {@render storachaConnectedBanner()}
2206
+ <!-- Action Buttons -->
2207
+ <div style="display: flex; flex-direction: column; gap: 0.75rem;">
2191
2208
  <button
2192
2209
  class="storacha-btn-backup"
2193
2210
  onclick={handleBackup}
@@ -2407,10 +2424,12 @@
2407
2424
  </div>
2408
2425
  {/if}
2409
2426
  </div>
2427
+ </div>
2410
2428
  {/if}
2411
2429
 
2412
2430
  {#if activeTab === 'passkeys'}
2413
2431
  <div style="display: flex; flex-direction: column; gap: 0.75rem;">
2432
+ {@render yourDidCard()}
2414
2433
  <!-- Connection Status + Copy -->
2415
2434
  <div
2416
2435
  style="border-radius: 0.375rem; border: 1px solid #E91315; background: linear-gradient(to right, #ffffff, #FFE4AE); padding: 0.625rem 0.75rem;"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@le-space/p2pass",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "type": "module",
5
5
  "description": "P2Pass — peer-to-peer passkeys, UCANs, OrbitDB registry sync, and Storacha backup (Svelte)",
6
6
  "license": "MIT",
@@ -23,8 +23,10 @@
23
23
  "test:e2e:ui": "playwright test --ui",
24
24
  "test": "vitest run",
25
25
  "test:watch": "vitest",
26
+ "prepackage": "node scripts/sync-version.mjs",
26
27
  "package": "svelte-package && publint",
27
28
  "prepublishOnly": "npm run package",
29
+ "version": "node scripts/sync-version.mjs && git add src/lib/index.js",
28
30
  "check": "svelte-check --tsconfig ./jsconfig.json",
29
31
  "format": "prettier --write .",
30
32
  "format:check": "prettier --check .",