@unicitylabs/sphere-sdk 0.14.11 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -17
- package/dist/connect/index.cjs +17 -17
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.js +17 -17
- package/dist/connect/index.js.map +1 -1
- package/dist/core/index.cjs +69 -84
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +5 -14
- package/dist/core/index.d.ts +5 -14
- package/dist/core/index.js +69 -84
- package/dist/core/index.js.map +1 -1
- package/dist/impl/browser/connect/index.cjs +10 -3
- package/dist/impl/browser/connect/index.cjs.map +1 -1
- package/dist/impl/browser/connect/index.js +10 -3
- package/dist/impl/browser/connect/index.js.map +1 -1
- package/dist/impl/browser/index.cjs.map +1 -1
- package/dist/impl/browser/index.js.map +1 -1
- package/dist/impl/nodejs/connect/index.cjs +9 -2
- package/dist/impl/nodejs/connect/index.cjs.map +1 -1
- package/dist/impl/nodejs/connect/index.js +9 -2
- package/dist/impl/nodejs/connect/index.js.map +1 -1
- package/dist/impl/nodejs/index.cjs.map +1 -1
- package/dist/impl/nodejs/index.js.map +1 -1
- package/dist/impl/wallet-api-v2/index.cjs +92 -92
- package/dist/impl/wallet-api-v2/index.cjs.map +1 -1
- package/dist/impl/wallet-api-v2/index.js +92 -92
- package/dist/impl/wallet-api-v2/index.js.map +1 -1
- package/dist/index.cjs +69 -84
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -11
- package/dist/index.d.ts +6 -11
- package/dist/index.js +69 -84
- package/dist/index.js.map +1 -1
- package/dist/modules/payments-v2/index.cjs +116 -174
- package/dist/modules/payments-v2/index.cjs.map +1 -1
- package/dist/modules/payments-v2/index.d.cts +3 -5
- package/dist/modules/payments-v2/index.d.ts +3 -5
- package/dist/modules/payments-v2/index.js +114 -173
- package/dist/modules/payments-v2/index.js.map +1 -1
- package/dist/token-engine/index.cjs +43 -57
- package/dist/token-engine/index.cjs.map +1 -1
- package/dist/token-engine/index.d.cts +0 -4
- package/dist/token-engine/index.d.ts +0 -4
- package/dist/token-engine/index.js +43 -57
- package/dist/token-engine/index.js.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -110,7 +110,7 @@ A wallet is composed from **swappable ports**, layered in two steps:
|
|
|
110
110
|
- **The rail is wallet-api, not Nostr.** Transfers are certified on-chain by the token engine and the finished token is deposited into the recipient's **wallet-api mailbox**. Nostr carries messaging/nametags — **it does not move payments.**
|
|
111
111
|
- **Custody is server-side.** The wallet-api backend holds your token inventory; your keys never leave the client. (Own-storage custody was rescinded — there is no local token store.)
|
|
112
112
|
- **The money ports are contract-enforced.** `StoragePort`/`DeliveryPort` (`modules/payments-v2/ports.ts`) have wallet-api implementations; the `paymentsV2Transport` seam in the `walletApi` config lets tests/custom hosts inject a whole replacement bundle.
|
|
113
|
-
- **`network` placement.** Required on `createBrowserProviders`/`createNodeProviders
|
|
113
|
+
- **`network` placement.** Required on `createBrowserProviders`/`createNodeProviders`, in the `walletApi` config, AND on `Sphere.init` — the three must agree. `Sphere.init` resolves the payments composition and the token registry from its own `network`, so omitting it or letting it disagree with `walletApi.network` throws `INVALID_CONFIG` before any storage write.
|
|
114
114
|
|
|
115
115
|
For manual/advanced provider wiring, see [Custom Providers Configuration](#custom-providers-configuration). For the deeper integration guide, see [docs/INTEGRATION.md](docs/INTEGRATION.md).
|
|
116
116
|
|
|
@@ -148,6 +148,22 @@ try {
|
|
|
148
148
|
}
|
|
149
149
|
```
|
|
150
150
|
|
|
151
|
+
## Migrating off `sphere.paymentsV2`
|
|
152
|
+
|
|
153
|
+
The deprecated `sphere.paymentsV2` alias and the `paymentsV2: true` init flag are **removed** in
|
|
154
|
+
0.15.0. `sphere.payments` is the only accessor, and it is the same facade the alias returned.
|
|
155
|
+
|
|
156
|
+
One behavioural difference matters: while no vertical is running (init in flight, mid
|
|
157
|
+
address-switch, destroyed) the alias returned `null` and `sphere.payments` **throws**
|
|
158
|
+
`SphereError` with `code: 'NOT_INITIALIZED'`. Call sites that leaned on the nullish alias —
|
|
159
|
+
`sphere.paymentsV2?.tokens()`, `?? fallback`, `if (sphere.paymentsV2)` as a readiness probe —
|
|
160
|
+
silently degraded to "no payments" before and now throw, so catch `NOT_INITIALIZED` where you
|
|
161
|
+
used to check for null. Code that runs after `await Sphere.init(…)` and before `destroy()` —
|
|
162
|
+
everything else in this README — reads `sphere.payments` directly.
|
|
163
|
+
|
|
164
|
+
The `accounting:` / `swap:` options are **not** part of this cleanup: they still throw a typed
|
|
165
|
+
`INVALID_CONFIG`, deliberately, because 0.15.0 is the release where consumers re-integrate.
|
|
166
|
+
|
|
151
167
|
## Network Configuration
|
|
152
168
|
|
|
153
169
|
The SDK ships network presets that configure all services automatically. `network` is **required** — there is no default:
|
|
@@ -159,7 +175,9 @@ The SDK ships network presets that configure all services automatically. `networ
|
|
|
159
175
|
| `mainnet` | aggregator.unicity.network (v1-era) | relay.unicity.network (+ public relays) |
|
|
160
176
|
| `dev` | dev-aggregator.dyndns.org (v1-era) | nostr-relay.testnet.unicity.network |
|
|
161
177
|
|
|
162
|
-
> **v1 → v2 cutover:** `testnet` now points at **testnet2**, the v2 state-transition gateway network (network id 4, taken from the trust base; own testnet2 token registry). The old `goggregator-test` testnet spoke the removed v1 protocol and is gone. `mainnet` and `dev` still point at v1-era aggregators — wallet operations that move money (`send`, `mint`) **fail loudly** (`AGGREGATOR_ERROR`) on those networks until their gateways are cut over
|
|
178
|
+
> **v1 → v2 cutover:** `testnet` now points at **testnet2**, the v2 state-transition gateway network (network id 4, taken from the trust base; own testnet2 token registry). The old `goggregator-test` testnet spoke the removed v1 protocol and is gone. `mainnet` and `dev` still point at v1-era aggregators — wallet operations that move money (`send`, `mint`) **fail loudly** (`AGGREGATOR_ERROR`) on those networks until their gateways are cut over. The transfer wire payload is the finished token blob — the base SDK's own `Token.toCBOR()` bytes, with no sphere envelope around them — deposited into the recipient's wallet-api mailbox.
|
|
179
|
+
>
|
|
180
|
+
> The **network** name (testnet2) and the **base-SDK major** (3.x since 0.15.0) are separate axes: testnet2 is still testnet2 after the 3.0.1 bump. What the bump changes is the bytes on that network — a gateway serving the v3 protocol accepts nothing a 2.x client writes, and vice versa.
|
|
163
181
|
|
|
164
182
|
```typescript
|
|
165
183
|
// Use testnet for all services
|
|
@@ -168,7 +186,7 @@ const providers = createBrowserProviders({ network: 'testnet' });
|
|
|
168
186
|
// Override specific services while using network preset
|
|
169
187
|
const providers = createBrowserProviders({
|
|
170
188
|
network: 'testnet',
|
|
171
|
-
oracle: { url: 'https://custom-gateway.example.com' }, // custom
|
|
189
|
+
oracle: { url: 'https://custom-gateway.example.com' }, // custom testnet2 gateway
|
|
172
190
|
});
|
|
173
191
|
```
|
|
174
192
|
|
|
@@ -199,7 +217,7 @@ The `testnet` preset wires most of these automatically — you only pass `networ
|
|
|
199
217
|
| **Group-chat relay** (NIP-29) | `wss://sphere-relay.unicity.network` |
|
|
200
218
|
| **Token registry** | `https://raw.githubusercontent.com/unicitynetwork/unicity-ids/refs/heads/main/unicity-ids.testnet2.json` |
|
|
201
219
|
|
|
202
|
-
The aggregator key above is the **testnet2** key only and is safe in client code; a **mainnet** key is a real secret. `mainnet`/`dev` still point at v1-era aggregators and cannot serve the
|
|
220
|
+
The aggregator key above is the **testnet2** key only and is safe in client code; a **mainnet** key is a real secret. `mainnet`/`dev` still point at v1-era aggregators and cannot serve the engine (`AGGREGATOR_ERROR`).
|
|
203
221
|
|
|
204
222
|
## Price Provider (Optional)
|
|
205
223
|
|
|
@@ -243,7 +261,7 @@ sphere.setPriceProvider(createPriceProvider({
|
|
|
243
261
|
|
|
244
262
|
## Test Tokens on Testnet (Self-Mint)
|
|
245
263
|
|
|
246
|
-
There is no faucet. On testnet you top up your wallet by **self-minting** fungible tokens via the
|
|
264
|
+
There is no faucet. On testnet you top up your wallet by **self-minting** fungible tokens via the token engine — `mint(coinIdHex, amount)` mints a finished token directly to this wallet (journal-first: crash-safe, a replay converges idempotently):
|
|
247
265
|
|
|
248
266
|
```typescript
|
|
249
267
|
import { getCoinIdBySymbol } from '@unicitylabs/sphere-sdk';
|
|
@@ -259,7 +277,7 @@ if (result.success) {
|
|
|
259
277
|
}
|
|
260
278
|
```
|
|
261
279
|
|
|
262
|
-
> **Note:** Minting requires a working
|
|
280
|
+
> **Note:** Minting requires a working oracle config (trust base + gateway URL + API key) — it fails with an error result otherwise. See [API Key](#api-key) above.
|
|
263
281
|
|
|
264
282
|
## Multi-Address Support
|
|
265
283
|
|
|
@@ -596,7 +614,7 @@ const transport = createNostrTransportProvider({
|
|
|
596
614
|
relays: ['wss://nostr-relay.testnet.unicity.network'],
|
|
597
615
|
});
|
|
598
616
|
// `network` (or `trustBaseUrl`) is required — it selects the trust base the
|
|
599
|
-
//
|
|
617
|
+
// token engine is built from. The apiKey authenticates gateway requests.
|
|
600
618
|
const oracle = createUnicityAggregatorProvider({
|
|
601
619
|
url: 'https://gateway.testnet2.unicity.network',
|
|
602
620
|
apiKey: 'sk_...',
|
|
@@ -722,7 +740,16 @@ import {
|
|
|
722
740
|
|
|
723
741
|
## Token format & verification
|
|
724
742
|
|
|
725
|
-
Tokens are opaque
|
|
743
|
+
Tokens are opaque CBOR blobs — the base SDK's own `Token.toCBOR()` bytes, with no sphere-private
|
|
744
|
+
envelope wrapped around them (`Token.sdkData` carries the hex when a blob is loaded). That is the
|
|
745
|
+
same form on the wire, in the wallet-api mailbox and in server storage. Since 0.15.0 those bytes
|
|
746
|
+
are **state-transition-sdk 3.x** CBOR; a 2.x blob does not decode and is rejected on receipt (the
|
|
747
|
+
drain warns and acks it as invalid rather than silently dropping it).
|
|
748
|
+
|
|
749
|
+
Inventory lives in the wallet-api backend; the SDK downloads blobs on demand (lazy tokens carry
|
|
750
|
+
value metadata only until selected for a spend). Every incoming token is engine-verified (full
|
|
751
|
+
trust-base proof check) and ownership-checked **before it enters the balance** — there is no
|
|
752
|
+
separate validate step to run.
|
|
726
753
|
|
|
727
754
|
## Architecture
|
|
728
755
|
|
|
@@ -742,7 +769,7 @@ mnemonic → master key → BIP32 derivation → identity
|
|
|
742
769
|
↓ ↓ ↓
|
|
743
770
|
L3 (Unicity) Group Chat Nostr
|
|
744
771
|
sphere.payments sphere.groupChat sphere.communications
|
|
745
|
-
|
|
772
|
+
Tokens, engine NIP-29 messaging P2P messaging
|
|
746
773
|
```
|
|
747
774
|
|
|
748
775
|
```
|
|
@@ -761,14 +788,14 @@ Payments vertical (modules/payments-v2/ — docs/PAYMENTS-V2-DESIGN.md)
|
|
|
761
788
|
`walletApi` transport config (core/payments-v2-wiring.ts).
|
|
762
789
|
|
|
763
790
|
Token Engine (token-engine/)
|
|
764
|
-
└── The wallet's boundary to the
|
|
765
|
-
transfer / split / verify / spent-check operations go through
|
|
766
|
-
ITokenEngine port. Sphere builds the engine from the oracle's config
|
|
791
|
+
└── The wallet's boundary to the base state-transition SDK (pinned 3.0.1):
|
|
792
|
+
all mint / transfer / split / verify / spent-check operations go through
|
|
793
|
+
the ITokenEngine port. Sphere builds the engine from the oracle's config
|
|
767
794
|
(trust base JSON + gateway URL + API key); no state-transition SDK
|
|
768
795
|
objects cross this boundary.
|
|
769
796
|
|
|
770
797
|
Providers (injectable)
|
|
771
|
-
├── StorageProvider - Key-value persistence: keys/identity + the
|
|
798
|
+
├── StorageProvider - Key-value persistence: keys/identity + the pv2g2:* scoped KV
|
|
772
799
|
├── TransportProvider - Messaging (Nostr) — NOT the payment rail
|
|
773
800
|
├── OracleProvider - Token-engine config (trust base JSON + gateway URL + API key)
|
|
774
801
|
└── walletApi (config) - WalletApiTransportConfig — the wallet-api wire the
|
|
@@ -841,8 +868,19 @@ type NodeOracleConfig = BaseOracleConfig & NodeOracleExtensions;
|
|
|
841
868
|
|
|
842
869
|
## Documentation
|
|
843
870
|
|
|
844
|
-
-
|
|
845
|
-
|
|
871
|
+
Consumer-facing:
|
|
872
|
+
|
|
873
|
+
- [API Reference](./docs/API.md) — the full surface of `Sphere` and the payments facade
|
|
874
|
+
- [Integration Guide](./docs/INTEGRATION.md) — composition, custody, custom providers, events
|
|
875
|
+
- [Browser Quick Start](./docs/QUICKSTART-BROWSER.md) / [Node.js Quick Start](./docs/QUICKSTART-NODEJS.md)
|
|
876
|
+
- [Connect Protocol](./docs/CONNECT.md) — dApp ↔ wallet RPC (protocol version `2.1`)
|
|
877
|
+
- [Parallel token verification](./docs/VERIFICATION-WORKERS.md) — the opt-in worker pool
|
|
878
|
+
- [CHANGELOG](./CHANGELOG.md) — per-release notes (versioned sections start at `0.14.11`)
|
|
879
|
+
|
|
880
|
+
Design and migration references:
|
|
881
|
+
|
|
882
|
+
- [Payments vertical design](./docs/PAYMENTS-V2-DESIGN.md) — the authoritative money design
|
|
883
|
+
- [Payments migration guide](./docs/MIGRATION-PAYMENTS-V2.md) — what the P11 flip moved
|
|
846
884
|
|
|
847
885
|
## Browser Providers
|
|
848
886
|
|
|
@@ -852,7 +890,7 @@ The SDK includes browser-ready provider implementations:
|
|
|
852
890
|
|----------|-------------|
|
|
853
891
|
| `LocalStorageProvider` | Browser localStorage with SSR fallback |
|
|
854
892
|
| `NostrTransportProvider` | Nostr relay messaging with NIP-04 |
|
|
855
|
-
| `UnicityAggregatorProvider` | Network config for the
|
|
893
|
+
| `UnicityAggregatorProvider` | Network config for the token engine (trust base + gateway URL + API key) |
|
|
856
894
|
|
|
857
895
|
## Node.js Providers
|
|
858
896
|
|
|
@@ -1070,7 +1108,7 @@ Nametags provide human-readable addresses (e.g., `@alice`) for receiving payment
|
|
|
1070
1108
|
|
|
1071
1109
|
**How registration works:** registering a nametag publishes a **Nostr identity binding** (name ↔ chain pubkey). Uniqueness is first-seen-wins — a name is available iff no binding already resolves for it (`sphere.isNametagAvailable(name)`). Runtime name resolution is binding-only; payments always go to the recipient's key-based `DIRECT://` address (there are no PROXY addresses).
|
|
1072
1110
|
|
|
1073
|
-
|
|
1111
|
+
Registration is **Nostr-binding-only**. The self-issued `UnicityIdToken` on-chain claim was removed with the 2.0.0 state-transition-sdk bump (upstream deleted the unicity-id primitive) — nothing is minted at registration, and nothing on chain is consulted to resolve a name.
|
|
1074
1112
|
|
|
1075
1113
|
### Registering a Nametag
|
|
1076
1114
|
|
package/dist/connect/index.cjs
CHANGED
|
@@ -455,7 +455,7 @@ function checkCompatibility(input) {
|
|
|
455
455
|
}
|
|
456
456
|
|
|
457
457
|
// connect/version.ts
|
|
458
|
-
var SDK_VERSION = "0.
|
|
458
|
+
var SDK_VERSION = "0.15.0";
|
|
459
459
|
|
|
460
460
|
// connect/permissions.ts
|
|
461
461
|
var PERMISSION_SCOPES = {
|
|
@@ -540,8 +540,15 @@ var REALTIME_STATUS = {
|
|
|
540
540
|
function toLegacyRequest(view, status) {
|
|
541
541
|
return { ...view, symbol: view.symbol ?? "", status };
|
|
542
542
|
}
|
|
543
|
+
function paymentsOrNull(sphere) {
|
|
544
|
+
try {
|
|
545
|
+
return sphere.payments;
|
|
546
|
+
} catch {
|
|
547
|
+
return null;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
543
550
|
function legacyRequestPayload(sphere, update) {
|
|
544
|
-
const view = sphere
|
|
551
|
+
const view = paymentsOrNull(sphere)?.requests.list().find((request) => request.id === update.id);
|
|
545
552
|
if (!view) {
|
|
546
553
|
return {
|
|
547
554
|
id: update.id,
|
|
@@ -620,7 +627,7 @@ var COMPAT_ATTACHERS = /* @__PURE__ */ new Map([
|
|
|
620
627
|
forward({ providerId: "wallet-api", error: "wallet-api connection degraded" });
|
|
621
628
|
})],
|
|
622
629
|
["sync:completed", (sphere, forward) => sphere.on("inventory:updated", () => {
|
|
623
|
-
forward({ source: "payments", count: sphere
|
|
630
|
+
forward({ source: "payments", count: paymentsOrNull(sphere)?.tokens().length ?? 0 });
|
|
624
631
|
})],
|
|
625
632
|
["sync:remote-update", remoteUpdateAttacher]
|
|
626
633
|
]);
|
|
@@ -1372,32 +1379,25 @@ var ConnectHost = class {
|
|
|
1372
1379
|
return this.handleUnsubscribe(params.event);
|
|
1373
1380
|
}
|
|
1374
1381
|
const sphere = this.requireSphere();
|
|
1375
|
-
const v2 = sphere.paymentsV2 ?? null;
|
|
1376
1382
|
switch (method) {
|
|
1377
1383
|
case RPC_METHODS.GET_IDENTITY:
|
|
1378
1384
|
return this.getPublicIdentity();
|
|
1379
1385
|
case RPC_METHODS.GET_BALANCE:
|
|
1380
|
-
return v2 ? v2.assets(params.coinId) : sphere.payments.getBalance(params.coinId);
|
|
1381
1386
|
case RPC_METHODS.GET_ASSETS:
|
|
1382
|
-
return
|
|
1387
|
+
return sphere.payments.assets(params.coinId);
|
|
1383
1388
|
case RPC_METHODS.GET_FIAT_BALANCE:
|
|
1384
|
-
return {
|
|
1385
|
-
fiatBalance: v2 ? sumFiatUsd(await v2.assets()) : await sphere.payments.getFiatBalance()
|
|
1386
|
-
};
|
|
1389
|
+
return { fiatBalance: sumFiatUsd(await sphere.payments.assets()) };
|
|
1387
1390
|
case RPC_METHODS.GET_TOKENS:
|
|
1388
1391
|
return this.stripTokenSdkData(
|
|
1389
|
-
|
|
1390
|
-
params.coinId ? { coinId: params.coinId } : void 0
|
|
1391
|
-
)
|
|
1392
|
+
sphere.payments.tokens(params.coinId ? { coinId: params.coinId } : void 0)
|
|
1392
1393
|
);
|
|
1393
1394
|
case RPC_METHODS.GET_HISTORY: {
|
|
1394
|
-
if (!v2) return sphere.payments.getHistory();
|
|
1395
1395
|
const limit = typeof params.limit === "number" && Number.isFinite(params.limit) ? params.limit : void 0;
|
|
1396
|
-
if (limit !== void 0) return (await
|
|
1397
|
-
let page = await
|
|
1396
|
+
if (limit !== void 0) return (await sphere.payments.history({ limit })).entries;
|
|
1397
|
+
let page = await sphere.payments.history(void 0);
|
|
1398
1398
|
const entries = [...page.entries];
|
|
1399
1399
|
while (page.more && page.cursor !== null) {
|
|
1400
|
-
page = await
|
|
1400
|
+
page = await sphere.payments.history({ before: page.cursor });
|
|
1401
1401
|
entries.push(...page.entries);
|
|
1402
1402
|
}
|
|
1403
1403
|
return entries;
|
|
@@ -1508,7 +1508,7 @@ var ConnectHost = class {
|
|
|
1508
1508
|
return { subscribed: true, event: eventName };
|
|
1509
1509
|
}
|
|
1510
1510
|
const sphere = this.requireSphere();
|
|
1511
|
-
|
|
1511
|
+
{
|
|
1512
1512
|
const compatUnsub = attachCompatEvent(
|
|
1513
1513
|
sphere,
|
|
1514
1514
|
eventName,
|