|
| 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. |
0 commit comments