Skip to content

Commit

Permalink
Squashed commit of the following:
Browse files Browse the repository at this point in the history
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
  • Loading branch information
pablof7z committed Dec 2, 2024
1 parent 86c5d4f commit 689305c
Show file tree
Hide file tree
Showing 71 changed files with 2,313 additions and 2,130 deletions.
5 changes: 5 additions & 0 deletions .changeset/eighty-toes-refuse.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@nostr-dev-kit/ndk": patch
---

move NWC to ndk-wallet
5 changes: 5 additions & 0 deletions .changeset/pretty-berries-talk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@nostr-dev-kit/ndk-wallet": patch
---

NWC support
6 changes: 2 additions & 4 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ on:
# Runs on pushes targeting the `main` branch. Change this to `master` if you're
# using the `master` branch as the default branch.
push:
branches: [master]
branches:
- '*'

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
Expand Down Expand Up @@ -36,14 +37,11 @@ jobs:
- name: Setup Node
uses: pnpm/action-setup@v3 # Uncomment this if you're using pnpm
with:
node-version: 21
cache: pnpm # or pnpm / yarn
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Install dependencies
run: pnpm install # or pnpm install / yarn install / bun install
- name: Build dexie typedoc
run: cd ndk-cache-dexie && pnpm typedoc && cat docs/interfaces/NDKCacheAdapterDexieOptions.md >> ../docs/cache/dexie.md
- name: Build with VitePress
run: pnpm docs:build # or pnpm docs:build / yarn docs:build / bun run docs:build
- name: Build typedoc
Expand Down
22 changes: 19 additions & 3 deletions docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,22 @@ export default withMermaid(defineConfig({
{ text: 'Publishing', link: '/tutorial/publishing' },
{ text: "Subscription Management", link: '/tutorial/subscription-management' },
{ text: "Speed", link: '/tutorial/speed' },
{ text: 'Zaps', link: '/tutorial/zaps' },
]
},
{
text: "Cache",
text: "Cache Adapters",
items: [
{ text: 'Dexie Adapter', link: '/cache/dexie' },
{ text: 'Nostr Relay Adapter', link: '/cache/nostr' },
{ text: 'In-memory + dexie', link: '/cache/dexie' },
{ text: 'Local Nostr Relay', link: '/cache/nostr' },
]
},
{
text: "Wallet",
items: [
{ text: 'Introduction', link: '/wallet/index' },
{ text: 'Nutsack (NIP-60)', link: '/wallet/nutsack' },
{ text: 'Nutzaps', link: '/wallet/nutzaps' },
]
},
{
Expand All @@ -46,6 +55,13 @@ export default withMermaid(defineConfig({
{ text: 'NDK Svelte', link: '/wrappers/svelte' },
]
},
{
text: "Mobile",
items: [
{ text: 'Introduction', link: '/mobile/index' },
{ text: 'Session', link: '/mobile/session' },
]
},
{
text: "Internals",
items: [
Expand Down
53 changes: 53 additions & 0 deletions docs/mobile/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# NDK Mobile

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.

## Features

- 🔐 Multiple signer implementations (NIP-07, NIP-46, Private Key)
- 💾 SQLite-based caching for offline support
- 🔄 Subscription management with automatic reconnection
- 📱 React Native and Expo compatibility
- 🪝 React hooks for easy state management
- 👛 Integrated wallet support

## Installation

```sh
npm install @nostr-dev-kit/ndk-mobile
```

## Usage

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.

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.

```tsx
function App() {
return <NDKProvider explicitRelayUrls={["wss://f7z.io"]}>{/* your app here */}</NDKProvider>;
}
```

## useNDK()

`useNDK()` provides access to the `ndk` instance and some other useful information.

```tsx
function LoginScreen() {
const { ndk, currentUser, login } = useNDK();

useEffect(() => {
if (currentUser) alert("you are now logged in as ", +currentUser.pubkey);
}, [currentUser]);

return <Button onPress={() => login(withPayload("nsec1..."))} title="Login" />;
}
```

## Example

There is a barebones repository showing how to use this library:
[ndk-mobile-sample](https://github.com/pablof7z/ndk-mobile-sample).

For a real application using this look at [Olas](https://github.com/pablof7z/snapstr).
File renamed without changes.
13 changes: 7 additions & 6 deletions docs/tutorial/mobile/session.md → docs/mobile/session.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,17 @@ const kinds = new Map([
Now say you want to allow the user to bookmark something with the click of a button:

```tsx
const { imageCurationSet } = useNDKSessionEventKind<NDKList>(NDKList, NDKKind.ImageCurationSet, {
create: true,
});

const bookmark = async () => {
await imageCurationSet.addItem(event);
};
```

const { imageCurationSet } = useNDKSessionEventKind<NDKList>(NDKList, NDKKind.ImageCurationSet, { create: true });

const bookmark = async () => {
await imageCurationSet.addItem(event);
}
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.

```
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.
```
Empty file added docs/mobile/subscriptions.md
Empty file.
36 changes: 7 additions & 29 deletions docs/tutorial/zaps/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,13 @@ NDK comes with an interface to make zapping as simple as possible.

```ts
const user = await ndk.getUserFromNip05("[email protected]");
const zapper = await ndk.zap(user, 1000)
const lnPay = ({ pr: string }) => {
console.log("please pay to complete the zap", pr);
};
const zapper = new NDKZapper(user, 1000, { lnPay });
zapper.zap();
```

## Connecting to WebLN
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.
## NDK-Wallet

```ts
import { requestProvider } from "webln";
let weblnProvider;
requestProvider().then(provider => weblnProvider = provider });

// whenever the user wants to pay for something, and using LN is an option for the payment
// this function will be called
ndk.walletConfig.onLnPay = async ({pr: string, amount: number, target?: NDKEvent | NDKUser}) => {
if (weblnProvider) {
if (confirm("Would you like to pay with your WebLN provider?")) {
await weblnProvider.sendPayment(pr);
}
} else {
// show a QR code to the user or handle in some way
}
});
```

Now from anywhere in the app, you can:

```ts
event.zap(1000); // zap an event 1 sat
```

## Configuring a wallet
NDK provides an `ndk-wallet` package that makes it very simple to use a NIP-60 wallet.
Refer to the Wallet section of the tutorial to learn more about zapping. NDK-wallet provides many conveniences to integrate with zaps.
64 changes: 12 additions & 52 deletions docs/wallet/index.md
Original file line number Diff line number Diff line change
@@ -1,63 +1,23 @@
# Wallet

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

## Initialization
Currently ndk-wallet supports:

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

```ts
// instantiate your NDK
import NDK from "@nostr-dev-kit/ndk";
import NDKWallet from "@nostr-dev-kit/ndk-wallet";

const ndk = new NDK({
explicitRelayUrls: [ <some-relays> ],
});
ndk.connect();

// Establish the main user's signer
ndk.signer = NDKPrivateKeySigner.generate();

// instantiate the wallet
const ndkWallet = new NDKWallet(ndk);
```

## Creating a Wallet
Once we have an NDK instance ready we can create a wallet.

```ts
const wallet = ndkWallet.createCashuWallet();
wallet.name = "My Wallet";
wallet.relays = [ "wss://relay1", "wss://relay2" ]
wallet.publish();
```
## Connecting NDK with a wallet

This will publish a wallet `kind:37376` event, which contains the wallet information.

But wait, we have no mints!

## Discovering mints
We need to find mints we want to use.

```ts
import { getMintRecommendations } from "@nostr-dev-kit/ndk-wallet";
const mintRecommendations = await getMintRecommendations(ndk);
```

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.

```ts
wallet.mints = choosenMints;
// We want to publishReplaceable here since the wallet is a replaceable event
wallet.publishReplaceable();
```
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.

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

```ts
const tokenEvent = await wallet.receiveToken(token);
const wallet = new NDKNWCWallet(ndk);
await wallet.initWithPairingCode("nostr+walletconnect:....");
ndk.wallet = wallet;
```

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.
Now whenever you want to pay something, the wallet will be called. Refer to the Nutsack adapter to see more details of the interface.
95 changes: 95 additions & 0 deletions docs/wallet/nutsack.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# NIP-60 (Nutack) wallets

NIP-60 provides wallets that are available to any nostr application immediately; the goal of NIP-60 is to provide the same
seamless experience nostr users expect from their apps with regards to the immediate aailability of their data, to their money.

## Creating a NIP-60 wallet

```ts
import NDKWallet from "@nostr-dev-kit/ndk-wallet";
import NDK from "@nostr-dev-kit/ndk";

// instantiate your NDK
const ndk = new NDK({
explicitRelayUrls: [ <some-relays> ],
signer = NDKPrivateKeySigner.generate();
});
ndk.connect();

// create a new NIP-60 wallet
const unit = "sat"; // unit of the wallet
const mints = [ 'https://testnut.cashu.space' ] // mints the wallet will use
const relays = [ 'wss://f7z.io', 'ws://localhost:4040' ]; // relays where proofs will be stored
const wallet = NDKCashuWallet.create(ndk, unit, mints, relays);
await wallet.publish();
```

This will publish a wallet `kind:37376` event, which contains the wallet information.

We now have a NIP-60 wallet -- this wallet will be available from any nostr client that supports NIP-60.

## Deposit money

```ts
const deposit = wallet.deposit(1000, mints[0]);
const bolt11 = deposit.start(); // get a LN PR
deposit.on("success", () => console.log("we have money!", wallet.balance()));
```

## Configure NDK to use a wallet

You can configure NDK to use some wallet, this is equivalent for whatever wallet adapter you choose to use.

```ts
ndk.wallet = wallet;
```

## Send a zap

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

```ts
const user = await NDKUser.fronNip05("[email protected]");
const zapper = new NDKZapper(user, 1, "sat", {
comment: "hello from my wallet!",
});
zapper.on("complete", () => console.log("pablo was zapped!"));
zapper.zap();
```

## Zapping without a wallet

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.

```ts
// no wallet
ndk.wallet = undefined;

// this function will be called when a bolt11 needs to be paid
const lnPay = async (payment: NDKZapDetails<LnPaymentInfo>) => {
console.log("please pay this invoice to complete the zap", payment.pr);
};

const zapper = new NDKZapper(user, 1, "sat", { comment: "manual zapping", lnPay });
const paymentInfo = await zapper.zap();
```

You can also configure this at the application level, for example, to open a modal whenever a payment needs to be done

```ts
const lnPay = async (payment: NDKZapDetails<LnPaymentInfo>) => {
alert("please pay this invoice: " + payment.pr);
};

ndk.wallet = { lnPay };
```

## Receiving ecash

To receive ecash just call the `receiveToken` method on the wallet.

```ts
const tokenEvent = await wallet.receiveToken(token);
```

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.
11 changes: 7 additions & 4 deletions docs/wallet/nutzaps.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
# Nutzaps

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

# Sweeping NIP-61 nutzaps

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
the `NDKWalletService` is running by default.

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

Loading

0 comments on commit 689305c

Please sign in to comment.