Skip to content

Commit

Permalink
feat: reconnection in nip47 (#72)
Browse files Browse the repository at this point in the history
* feat: reconnection in nip47

* chore: spacing

* chore: persist request event state in db

* chore: use constants in json response

* chore: remove unnecessary nested for loop

* chore: add subscriptionToFilter function

* chore: separate nip47 with and without webhook

* chore: refactoring

* fix: close custom relay before reconnecting

* chore: further refactoring

* chore: improve EOS handling

* chore: refactor nip47 handlers

* chore: remove unused validation

* chore: check for deadline exceeded error

* chore: fix tags in nip47 subscriptions

* chore: use uuid to stop saving unnecessary subscriptions

* chore: don't save in svc.stopSusbcription
  • Loading branch information
im-adithya authored Jun 1, 2024
1 parent 909b11e commit 78a4d60
Show file tree
Hide file tree
Showing 5 changed files with 418 additions and 313 deletions.
64 changes: 53 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ This `GET` request returns a pubkey's NWC capabilities (if any)

### Publish NWC Request

Returns the response event directly or to the Webhook URL if provided.
Publishes the NWC request event and returns the response

#### Without webhook

<details>
<summary>
Expand All @@ -62,7 +64,6 @@ Returns the response event directly or to the Webhook URL if provided.
| name | type | data type | description |
|-----------|-----------|-------------------------|-----------------------------------------------------------------------|
| relayUrl | optional | string | If no relay is provided, it uses the default relay (wss://relay.getalby.com/v1) |
| webhookUrl | optional | string | Webhook URL to publish the response event, returns the event directly if not provided |
| walletPubkey | required | string | Pubkey of the NWC Wallet Provider |
| event | required | JSON object (see [example](#event-example)) | **Signed** request event |

Expand All @@ -87,15 +88,7 @@ Returns the response event directly or to the Webhook URL if provided.
// Source: https://pkg.go.dev/github.com/nbd-wtf/[email protected]#Event
```

#### Response (with webhook)

```json
{
"state": "WEBHOOK_RECEIVED"
}
```

#### Response (without webhook)
#### Response

```json
{
Expand All @@ -122,6 +115,55 @@ Returns the response event directly or to the Webhook URL if provided.
```
</details>

#### With webhook

<details>
<summary>
<code>POST</code> <code><b>/nip47/webhook</b></code>
</summary>

#### Request Body

| name | type | data type | description |
|-----------|-----------|-------------------------|-----------------------------------------------------------------------|
| relayUrl | optional | string | If no relay is provided, it uses the default relay (wss://relay.getalby.com/v1) |
| webhookUrl | required | string | Webhook URL to publish the response event |
| walletPubkey | required | string | Pubkey of the NWC Wallet Provider |
| event | required | JSON object (see [example](#event-example)) | **Signed** request event |


#### Response

```json
{
"state": "WEBHOOK_RECEIVED"
}
```

#### Response to webhook

```json
{
"id": "a16ycf4a01bcxx........xxxxx",
"pubkey": "a16y69effexxxx........xxxxx",
"created_at": 1709033612,
"kind": 23195,
"tags": [
[
"p",
"f490f5xxxxx........xxxxx"
],
[
"e",
"a41aefxxxxx........xxxxx"
]
],
"content": "<encrypted content>",
"sig": "<signature>",
}
```
</details>

------------------------------------------------------------------------------------------

### Publish Event
Expand Down
1 change: 1 addition & 0 deletions cmd/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func main() {

e.POST("/nip47/info", svc.InfoHandler)
e.POST("/nip47", svc.NIP47Handler)
e.POST("/nip47/webhook", svc.NIP47WebhookHandler)
e.POST("/nip47/notifications", svc.NIP47NotificationHandler)
e.POST("/publish", svc.PublishHandler)
e.POST("/subscriptions", svc.SubscriptionHandler)
Expand Down
83 changes: 51 additions & 32 deletions internal/nostr/models.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package nostr

import (
"context"
"encoding/json"
"time"

Expand All @@ -9,37 +10,45 @@ import (
)

const (
NIP_47_INFO_EVENT_KIND = 13194
NIP_47_REQUEST_KIND = 23194
NIP_47_RESPONSE_KIND = 23195

// state of request event
REQUEST_EVENT_PUBLISH_CONFIRMED = "confirmed"
REQUEST_EVENT_PUBLISH_FAILED = "failed"
NIP_47_INFO_EVENT_KIND = 13194
NIP_47_REQUEST_KIND = 23194
NIP_47_RESPONSE_KIND = 23195
NIP_47_NOTIFICATION_KIND = 23196

REQUEST_EVENT_PUBLISH_CONFIRMED = "CONFIRMED"
REQUEST_EVENT_PUBLISH_FAILED = "FAILED"
EVENT_PUBLISHED = "PUBLISHED"
EVENT_ALREADY_PROCESSED = "ALREADY_PROCESSED"
WEBHOOK_RECEIVED = "WEBHOOK_RECEIVED"
SUBSCRIPTION_CLOSED = "CLOSED"
SUBSCRIPTION_ALREADY_CLOSED = "ALREADY_CLOSED"
)

type Subscription struct {
ID uint
RelayUrl string `validate:"required"`
WebhookUrl string
Open bool
Ids *[]string `gorm:"-"`
Kinds *[]int `gorm:"-"`
Authors *[]string `gorm:"-"` // WalletPubkey is included in this
Tags *nostr.TagMap `gorm:"-"` // RequestEvent ID goes in the "e" tag
Since time.Time
Until time.Time
Limit int
Search string
CreatedAt time.Time
UpdatedAt time.Time
Uuid string `gorm:"type:uuid;default:gen_random_uuid()"`
ID uint
RelayUrl string
WebhookUrl string
Open bool
Ids *[]string `gorm:"-"`
Kinds *[]int `gorm:"-"`
Authors *[]string `gorm:"-"` // WalletPubkey is included in this
Tags *nostr.TagMap `gorm:"-"` // RequestEvent ID goes in the "e" tag
Since time.Time
Until time.Time
Limit int
Search string
CreatedAt time.Time
UpdatedAt time.Time
Uuid string `gorm:"type:uuid;default:gen_random_uuid()"`
EventChan chan *nostr.Event `gorm:"-"`
RequestEvent *nostr.Event `gorm:"-"`
RequestEventDB RequestEvent `gorm:"-"`

// TODO: fix an elegant solution to store datatypes
IdsString string
KindsString string
AuthorsString string
TagsString string
IdsString string
KindsString string
AuthorsString string
TagsString string
}

func (s *Subscription) BeforeSave(tx *gorm.DB) error {
Expand Down Expand Up @@ -116,9 +125,13 @@ func (s *Subscription) AfterFind(tx *gorm.DB) error {
return nil
}

type OnReceiveEOSFunc func(ctx context.Context, subscription *Subscription)

type HandleEventFunc func(event *nostr.Event, subscription *Subscription)

type RequestEvent struct {
ID uint
SubscriptionId uint `validate:"required"`
SubscriptionId *uint
NostrId string `validate:"required"`
Content string
State string
Expand All @@ -129,7 +142,7 @@ type RequestEvent struct {
type ResponseEvent struct {
ID uint
RequestId *uint
SubscriptionId uint `validate:"required"`
SubscriptionId *uint
NostrId string `validate:"required"`
Content string
RepliedAt time.Time
Expand All @@ -152,17 +165,23 @@ type InfoResponse struct {
}

type NIP47Request struct {
RelayUrl string `json:"relayUrl"`
WalletPubkey string `json:"walletPubkey"`
SignedEvent *nostr.Event `json:"event"`
}

type NIP47WebhookRequest struct {
RelayUrl string `json:"relayUrl"`
WalletPubkey string `json:"walletPubkey"`
WebhookUrl string `json:"webhookUrl"`
SignedEvent *nostr.Event `json:"event"`
}

type NIP47NotificationRequest struct {
RelayUrl string `json:"relayUrl"`
WebhookUrl string `json:"webhookUrl"`
WalletPubkey string `json:"walletPubkey"`
ConnPubkey string `json:"connectionPubkey"`
RelayUrl string `json:"relayUrl"`
WebhookUrl string `json:"webhookUrl"`
WalletPubkey string `json:"walletPubkey"`
ConnPubkey string `json:"connectionPubkey"`
}

type NIP47Response struct {
Expand Down
Loading

0 comments on commit 78a4d60

Please sign in to comment.