Skip to content

Commit 689305c

Browse files
committed
Squashed commit of the following:
commit d9317a2 Author: pablof7z <[email protected]> Date: Fri Nov 29 17:26:37 2024 +0000 modify ndk-mobile to remove NDKWalletService commit 16c07fb Author: pablof7z <[email protected]> Date: Fri Nov 29 17:11:47 2024 +0000 wip commit dd7442a Author: pablof7z <[email protected]> Date: Fri Nov 29 17:08:46 2024 +0000 wip commit 9799003 Author: pablof7z <[email protected]> Date: Thu Nov 28 20:50:59 2024 +0000 try giving all mint proofs to cashu-ts commit acf0a7b Author: pablof7z <[email protected]> Date: Thu Nov 28 15:43:15 2024 +0000 wip commit f239104 Author: pablof7z <[email protected]> Date: Thu Nov 28 13:45:13 2024 +0000 minor corrections commit 78200ee Author: pablof7z <[email protected]> Date: Thu Nov 28 12:48:16 2024 +0000 remove dexie from docs? commit 162ed25 Author: pablof7z <[email protected]> Date: Thu Nov 28 12:44:14 2024 +0000 update docs commit 4971db7 Author: pablof7z <[email protected]> Date: Thu Nov 28 12:22:55 2024 +0000 take ndk-mobile out from the default build commit 5bfd0b5 Author: pablof7z <[email protected]> Date: Thu Nov 28 12:21:03 2024 +0000 hopefully make github actions run commit eb48a7b Author: pablof7z <[email protected]> Date: Thu Nov 28 12:17:33 2024 +0000 workflow commit d9da2d5 Author: pablof7z <[email protected]> Date: Thu Nov 28 12:11:45 2024 +0000 update test commit c11da8d Author: pablof7z <[email protected]> Date: Thu Nov 28 12:10:58 2024 +0000 fix bug where both a and e tags were going in zap requests commit 35cdde8 Author: pablof7z <[email protected]> Date: Thu Nov 28 12:10:41 2024 +0000 deprecate user.zap() and ndk.zap() -- use new NDKZapper instead commit d70feb3 Author: pablof7z <[email protected]> Date: Wed Nov 27 13:19:53 2024 +0000 nwc support commit aee2abd Author: pablof7z <[email protected]> Date: Fri Nov 22 23:43:52 2024 +0000 wip commit ec7bb98 Author: pablof7z <[email protected]> Date: Thu Nov 14 00:09:55 2024 +0000 wip commit 74bf589 Author: pablof7z <[email protected]> Date: Wed Nov 13 22:07:56 2024 +0000 upgrade cashu-ts
1 parent 86c5d4f commit 689305c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+2313
-2130
lines changed

.changeset/eighty-toes-refuse.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@nostr-dev-kit/ndk": patch
3+
---
4+
5+
move NWC to ndk-wallet

.changeset/pretty-berries-talk.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@nostr-dev-kit/ndk-wallet": patch
3+
---
4+
5+
NWC support

.github/workflows/deploy.yml

+2-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ on:
66
# Runs on pushes targeting the `main` branch. Change this to `master` if you're
77
# using the `master` branch as the default branch.
88
push:
9-
branches: [master]
9+
branches:
10+
- '*'
1011

1112
# Allows you to run this workflow manually from the Actions tab
1213
workflow_dispatch:
@@ -36,14 +37,11 @@ jobs:
3637
- name: Setup Node
3738
uses: pnpm/action-setup@v3 # Uncomment this if you're using pnpm
3839
with:
39-
node-version: 21
4040
cache: pnpm # or pnpm / yarn
4141
- name: Setup Pages
4242
uses: actions/configure-pages@v4
4343
- name: Install dependencies
4444
run: pnpm install # or pnpm install / yarn install / bun install
45-
- name: Build dexie typedoc
46-
run: cd ndk-cache-dexie && pnpm typedoc && cat docs/interfaces/NDKCacheAdapterDexieOptions.md >> ../docs/cache/dexie.md
4745
- name: Build with VitePress
4846
run: pnpm docs:build # or pnpm docs:build / yarn docs:build / bun run docs:build
4947
- name: Build typedoc

docs/.vitepress/config.mts

+19-3
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,22 @@ export default withMermaid(defineConfig({
3131
{ text: 'Publishing', link: '/tutorial/publishing' },
3232
{ text: "Subscription Management", link: '/tutorial/subscription-management' },
3333
{ text: "Speed", link: '/tutorial/speed' },
34+
{ text: 'Zaps', link: '/tutorial/zaps' },
3435
]
3536
},
3637
{
37-
text: "Cache",
38+
text: "Cache Adapters",
3839
items: [
39-
{ text: 'Dexie Adapter', link: '/cache/dexie' },
40-
{ text: 'Nostr Relay Adapter', link: '/cache/nostr' },
40+
{ text: 'In-memory + dexie', link: '/cache/dexie' },
41+
{ text: 'Local Nostr Relay', link: '/cache/nostr' },
42+
]
43+
},
44+
{
45+
text: "Wallet",
46+
items: [
47+
{ text: 'Introduction', link: '/wallet/index' },
48+
{ text: 'Nutsack (NIP-60)', link: '/wallet/nutsack' },
49+
{ text: 'Nutzaps', link: '/wallet/nutzaps' },
4150
]
4251
},
4352
{
@@ -46,6 +55,13 @@ export default withMermaid(defineConfig({
4655
{ text: 'NDK Svelte', link: '/wrappers/svelte' },
4756
]
4857
},
58+
{
59+
text: "Mobile",
60+
items: [
61+
{ text: 'Introduction', link: '/mobile/index' },
62+
{ text: 'Session', link: '/mobile/session' },
63+
]
64+
},
4965
{
5066
text: "Internals",
5167
items: [

docs/mobile/index.md

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# NDK Mobile
2+
3+
A React Native/Expo implementation of [NDK (Nostr Development Kit)](https://github.com/nostr-dev-kit/ndk) that provides a complete toolkit for building Nostr applications on mobile platforms.
4+
5+
## Features
6+
7+
- 🔐 Multiple signer implementations (NIP-07, NIP-46, Private Key)
8+
- 💾 SQLite-based caching for offline support
9+
- 🔄 Subscription management with automatic reconnection
10+
- 📱 React Native and Expo compatibility
11+
- 🪝 React hooks for easy state management
12+
- 👛 Integrated wallet support
13+
14+
## Installation
15+
16+
```sh
17+
npm install @nostr-dev-kit/ndk-mobile
18+
```
19+
20+
## Usage
21+
22+
When using this library don't import `@nostr-dev-kit/ndk` directly, instead import `@nostr-dev-kit/ndk-mobile`. `ndk-mobile` exports the same classes as `ndk`, so you can just swap the import.
23+
24+
Once you have imported the library, you can use the `NDKProvider` to wrap your application. Pass as props all the typical arguments you would pass to an `new NDK()` call.
25+
26+
```tsx
27+
function App() {
28+
return <NDKProvider explicitRelayUrls={["wss://f7z.io"]}>{/* your app here */}</NDKProvider>;
29+
}
30+
```
31+
32+
## useNDK()
33+
34+
`useNDK()` provides access to the `ndk` instance and some other useful information.
35+
36+
```tsx
37+
function LoginScreen() {
38+
const { ndk, currentUser, login } = useNDK();
39+
40+
useEffect(() => {
41+
if (currentUser) alert("you are now logged in as ", +currentUser.pubkey);
42+
}, [currentUser]);
43+
44+
return <Button onPress={() => login(withPayload("nsec1..."))} title="Login" />;
45+
}
46+
```
47+
48+
## Example
49+
50+
There is a barebones repository showing how to use this library:
51+
[ndk-mobile-sample](https://github.com/pablof7z/ndk-mobile-sample).
52+
53+
For a real application using this look at [Olas](https://github.com/pablof7z/snapstr).
File renamed without changes.

docs/tutorial/mobile/session.md docs/mobile/session.md

+7-6
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,17 @@ const kinds = new Map([
2020
Now say you want to allow the user to bookmark something with the click of a button:
2121

2222
```tsx
23+
const { imageCurationSet } = useNDKSessionEventKind<NDKList>(NDKList, NDKKind.ImageCurationSet, {
24+
create: true,
25+
});
2326

27+
const bookmark = async () => {
28+
await imageCurationSet.addItem(event);
29+
};
2430
```
2531

26-
const { imageCurationSet } = useNDKSessionEventKind<NDKList>(NDKList, NDKKind.ImageCurationSet, { create: true });
27-
28-
const bookmark = async () => {
29-
await imageCurationSet.addItem(event);
30-
}
32+
Now, when your app calls the `bookmark` function, it will add the event to the user's image curation set, if none exists it will create one for you.
3133

3234
```
3335
34-
Now, when your app calls the `bookmark` function, it will add the event to the user's image curation set, if none exists it will create one for you.
3536
```

docs/mobile/subscriptions.md

Whitespace-only changes.

docs/tutorial/zaps/index.md

+7-29
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,13 @@ NDK comes with an interface to make zapping as simple as possible.
44

55
```ts
66
const user = await ndk.getUserFromNip05("[email protected]");
7-
const zapper = await ndk.zap(user, 1000)
7+
const lnPay = ({ pr: string }) => {
8+
console.log("please pay to complete the zap", pr);
9+
};
10+
const zapper = new NDKZapper(user, 1000, { lnPay });
11+
zapper.zap();
812
```
913

10-
## Connecting to WebLN
11-
Advanced users might have a webln extension available in their browsers. To attempt to use their WebLN to pay, you can connect webln with NDK.
14+
## NDK-Wallet
1215

13-
```ts
14-
import { requestProvider } from "webln";
15-
let weblnProvider;
16-
requestProvider().then(provider => weblnProvider = provider });
17-
18-
// whenever the user wants to pay for something, and using LN is an option for the payment
19-
// this function will be called
20-
ndk.walletConfig.onLnPay = async ({pr: string, amount: number, target?: NDKEvent | NDKUser}) => {
21-
if (weblnProvider) {
22-
if (confirm("Would you like to pay with your WebLN provider?")) {
23-
await weblnProvider.sendPayment(pr);
24-
}
25-
} else {
26-
// show a QR code to the user or handle in some way
27-
}
28-
});
29-
```
30-
31-
Now from anywhere in the app, you can:
32-
33-
```ts
34-
event.zap(1000); // zap an event 1 sat
35-
```
36-
37-
## Configuring a wallet
38-
NDK provides an `ndk-wallet` package that makes it very simple to use a NIP-60 wallet.
16+
Refer to the Wallet section of the tutorial to learn more about zapping. NDK-wallet provides many conveniences to integrate with zaps.

docs/wallet/index.md

+12-52
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,23 @@
11
# Wallet
22

3-
NDK provides the `@nostr-dev-kit/ndk-wallet` package, which provides common interfaces and functionalities to create a wallet that leverages nostr.
3+
NDK provides an optional `@nostr-dev-kit/ndk-wallet` package, which provides common interfaces and functionalities to interface with different wallet adapters.
44

5-
## Initialization
5+
Currently ndk-wallet supports:
66

7-
An `NDKWallet` can be provided to ndk in the constructor.
7+
- NIP-60 wallets (nutsacks)
8+
- NIP-47 connectors (NWC)
9+
- WebLN (when available)
810

9-
```ts
10-
// instantiate your NDK
11-
import NDK from "@nostr-dev-kit/ndk";
12-
import NDKWallet from "@nostr-dev-kit/ndk-wallet";
13-
14-
const ndk = new NDK({
15-
explicitRelayUrls: [ <some-relays> ],
16-
});
17-
ndk.connect();
18-
19-
// Establish the main user's signer
20-
ndk.signer = NDKPrivateKeySigner.generate();
21-
22-
// instantiate the wallet
23-
const ndkWallet = new NDKWallet(ndk);
24-
```
25-
26-
## Creating a Wallet
27-
Once we have an NDK instance ready we can create a wallet.
28-
29-
```ts
30-
const wallet = ndkWallet.createCashuWallet();
31-
wallet.name = "My Wallet";
32-
wallet.relays = [ "wss://relay1", "wss://relay2" ]
33-
wallet.publish();
34-
```
11+
## Connecting NDK with a wallet
3512

36-
This will publish a wallet `kind:37376` event, which contains the wallet information.
37-
38-
But wait, we have no mints!
39-
40-
## Discovering mints
41-
We need to find mints we want to use.
42-
43-
```ts
44-
import { getMintRecommendations } from "@nostr-dev-kit/ndk-wallet";
45-
const mintRecommendations = await getMintRecommendations(ndk);
46-
```
47-
48-
Now you can either use WoT to find the most trusted mints from the point of view of the user, or you can use any mechanism to let the user determine which mints to use.
49-
50-
```ts
51-
wallet.mints = choosenMints;
52-
// We want to publishReplaceable here since the wallet is a replaceable event
53-
wallet.publishReplaceable();
54-
```
13+
As a developer, the first thing you need to do to use a wallet in your app is to choose how you will connect to your wallet by using one of the wallet adapters.
5514

56-
## Receiving ecash
57-
To receive ecash just call the `receiveToken` method on the wallet.
15+
Once you instantiate the desired wallet, you simply pass it to ndk.
5816

5917
```ts
60-
const tokenEvent = await wallet.receiveToken(token);
18+
const wallet = new NDKNWCWallet(ndk);
19+
await wallet.initWithPairingCode("nostr+walletconnect:....");
20+
ndk.wallet = wallet;
6121
```
6222

63-
This will swap the tokens in the right mint and add them to the wallet. Note that if the mint of this token is not one of the ones in the wallet you will need to move them to the mint you want manually.
23+
Now whenever you want to pay something, the wallet will be called. Refer to the Nutsack adapter to see more details of the interface.

docs/wallet/nutsack.md

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# NIP-60 (Nutack) wallets
2+
3+
NIP-60 provides wallets that are available to any nostr application immediately; the goal of NIP-60 is to provide the same
4+
seamless experience nostr users expect from their apps with regards to the immediate aailability of their data, to their money.
5+
6+
## Creating a NIP-60 wallet
7+
8+
```ts
9+
import NDKWallet from "@nostr-dev-kit/ndk-wallet";
10+
import NDK from "@nostr-dev-kit/ndk";
11+
12+
// instantiate your NDK
13+
const ndk = new NDK({
14+
explicitRelayUrls: [ <some-relays> ],
15+
signer = NDKPrivateKeySigner.generate();
16+
});
17+
ndk.connect();
18+
19+
// create a new NIP-60 wallet
20+
const unit = "sat"; // unit of the wallet
21+
const mints = [ 'https://testnut.cashu.space' ] // mints the wallet will use
22+
const relays = [ 'wss://f7z.io', 'ws://localhost:4040' ]; // relays where proofs will be stored
23+
const wallet = NDKCashuWallet.create(ndk, unit, mints, relays);
24+
await wallet.publish();
25+
```
26+
27+
This will publish a wallet `kind:37376` event, which contains the wallet information.
28+
29+
We now have a NIP-60 wallet -- this wallet will be available from any nostr client that supports NIP-60.
30+
31+
## Deposit money
32+
33+
```ts
34+
const deposit = wallet.deposit(1000, mints[0]);
35+
const bolt11 = deposit.start(); // get a LN PR
36+
deposit.on("success", () => console.log("we have money!", wallet.balance()));
37+
```
38+
39+
## Configure NDK to use a wallet
40+
41+
You can configure NDK to use some wallet, this is equivalent for whatever wallet adapter you choose to use.
42+
43+
```ts
44+
ndk.wallet = wallet;
45+
```
46+
47+
## Send a zap
48+
49+
Now that we have a wallet, some funds, and we have ndk prepared to use that wallet, we'll send a zap. NDK provides a convenient `wallet` setter that allows
50+
51+
```ts
52+
const user = await NDKUser.fronNip05("[email protected]");
53+
const zapper = new NDKZapper(user, 1, "sat", {
54+
comment: "hello from my wallet!",
55+
});
56+
zapper.on("complete", () => console.log("pablo was zapped!"));
57+
zapper.zap();
58+
```
59+
60+
## Zapping without a wallet
61+
62+
If you don't connect a wallet to ndk and attempt to zap, you will receive the zapping information(s) so you can give your users the possibility of paying manually.
63+
64+
```ts
65+
// no wallet
66+
ndk.wallet = undefined;
67+
68+
// this function will be called when a bolt11 needs to be paid
69+
const lnPay = async (payment: NDKZapDetails<LnPaymentInfo>) => {
70+
console.log("please pay this invoice to complete the zap", payment.pr);
71+
};
72+
73+
const zapper = new NDKZapper(user, 1, "sat", { comment: "manual zapping", lnPay });
74+
const paymentInfo = await zapper.zap();
75+
```
76+
77+
You can also configure this at the application level, for example, to open a modal whenever a payment needs to be done
78+
79+
```ts
80+
const lnPay = async (payment: NDKZapDetails<LnPaymentInfo>) => {
81+
alert("please pay this invoice: " + payment.pr);
82+
};
83+
84+
ndk.wallet = { lnPay };
85+
```
86+
87+
## Receiving ecash
88+
89+
To receive ecash just call the `receiveToken` method on the wallet.
90+
91+
```ts
92+
const tokenEvent = await wallet.receiveToken(token);
93+
```
94+
95+
This will swap the tokens in the right mint and add them to the wallet. Note that if the mint of this token is not one of the ones in the wallet you will need to move them to the mint you want manually.

docs/wallet/nutzaps.md

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
1+
# Nutzaps
2+
3+
ndk-wallet provides a simple way to automatically redeem nutzaps. You can run this periodically or you can just start it as part of the boostrap of your application
4+
15
# Sweeping NIP-61 nutzaps
6+
27
When a user receives a nutzap, they should sweep the public tokens into their wallet, the `@nostr-dev-kit/ndk-wallet` package takes care of this for you when
38
the `NDKWalletService` is running by default.
49

5-
```typescript
10+
```ts
611
const walletService = new NDKWalletService(ndk);
712
walletService.start();
813
walletService.on("nutzap", (nutzap: NDKNutzap) => {
9-
console.log("Received a nutzap from " + nutzap.pubkey + " for " + nutzap.amount + " " + nutzap.unit + " on mint " + nutzap.mint);
10-
// -> Received a nutzap from fa98..... for 1 usd on mint https://...
14+
console.log("Received a nutzap", nutzap);
1115
});
1216
```
13-

0 commit comments

Comments
 (0)