{"id":30615812,"url":"https://github.com/shocknet/clinksdk","last_synced_at":"2026-05-18T09:34:02.264Z","repository":{"id":301920382,"uuid":"990851764","full_name":"shocknet/ClinkSDK","owner":"shocknet","description":"Client SDK for the CLINK Protocol","archived":false,"fork":false,"pushed_at":"2025-08-02T18:09:13.000Z","size":38,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-26T09:46:21.296Z","etag":null,"topics":["bitcoin","bolt11","lightning-network","nostr","nostr-client","nostr-protocol","wallet"],"latest_commit_sha":null,"homepage":"https://clinkme.dev","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shocknet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-26T18:32:11.000Z","updated_at":"2025-08-02T18:08:58.000Z","dependencies_parsed_at":"2025-08-01T19:18:33.125Z","dependency_job_id":null,"html_url":"https://github.com/shocknet/ClinkSDK","commit_stats":null,"previous_names":["shocknet/clinksdk"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/shocknet/ClinkSDK","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shocknet%2FClinkSDK","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shocknet%2FClinkSDK/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shocknet%2FClinkSDK/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shocknet%2FClinkSDK/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shocknet","download_url":"https://codeload.github.com/shocknet/ClinkSDK/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shocknet%2FClinkSDK/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272827393,"owners_count":24999806,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-30T02:00:09.474Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bitcoin","bolt11","lightning-network","nostr","nostr-client","nostr-protocol","wallet"],"created_at":"2025-08-30T08:40:48.414Z","updated_at":"2026-05-18T09:34:02.259Z","avatar_url":"https://github.com/shocknet.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @shocknet/clink-sdk\n\n**A TypeScript/JavaScript SDK for the CLINK protocol — Nostr-native static Lightning payment offers and debits.**\n\n---\n\n## Overview\n\n`@shocknet/clink-sdk` provides a simple, robust interface for working with [CLINK](https://github.com/shocknet/CLINK/) (`noffer1...` and `ndebit1...`) on Nostr. It enables applications and wallets to create, encode, decode, send, and receive CLINK payment requests and authorizations using Nostr relays, with full support for NIP-44 encryption and the CLINK protocol.\n\n- **No web server or Onion Messaging required:** Unlike LNURL and Bolt12, all communication is over Nostr relays.\n- **Compatible with [Lightning.Pub](https://github.com/shocknet/Lightning.Pub), [ShockWallet](https://shockwallet.app), and other CLINK-enabled apps.**\n- **Implements the official [CLINK protocol](https://github.com/shocknet/CLINK).**\n\n---\n\n## Features\n\n- Encode/decode CLINK Static Offers (`noffer1...`) and Debits (`ndebit1...`) per the spec.\n- Send and receive CLINK payment requests (kind 21001) and debit requests (kind 21002) over Nostr.\n- NIP-44 encrypted payloads for privacy and security.\n- TypeScript types for all protocol payloads and responses.\n- Simple, high-level API for wallet and service integration.\n\n---\n\n## Installation\n\n```bash\nnpm install @shocknet/clink-sdk\n# or\nyarn add @shocknet/clink-sdk\n```\n\n---\n\n## Usage\n\n### 1. Encoding/Decoding Offers and Debits\n\n```ts\nimport { nofferEncode, ndebitEncode, decodeBech32, OfferPriceType } from '@shocknet/clink-sdk';\n\n// Encode a CLINK Offer\nconst noffer = nofferEncode({\n  pubkey: '\u003creceiver_pubkey_hex\u003e',\n  relay: 'wss://relay.example.com',\n  offer: 'my_offer_id',\n  priceType: OfferPriceType.Fixed,\n  price: 1000 // sats\n});\n\n// Decode a CLINK Offer\nconst decoded = decodeBech32(noffer);\nconsole.log(decoded);\n// { type: 'noffer', data: { pubkey, relay, offer, priceType, price } }\n```\n\n### 2. Sending a CLINK Offer Request (Lightning Invoice)\n\n```ts\nimport { ClinkSDK, NofferData, generateSecretKey, decodeBech32 } from '@shocknet/clink-sdk';\n\n// First, decode the offer string to get the relay and pubkey\nconst nofferString = 'noffer1qvqsyqjqxuurvwpcxc6rvvrxxsurqep5vfjk2wf4v33nsenrxumnyvesxfnrswfkvycrwdp3x93xydf5xg6rzce4vv6xgdfh8quxgct9x5erxvspremhxue69uhhgetnwskhyetvv9ujumrfva58gmnfdenjuur4vgqzpccxc30wpf78wf2q78wg3vq008fd8ygtl4qy06gstpye3h5unc47xmee6z';\nconst decoded = decodeBech32(nofferString);\nif (decoded.type !== 'noffer') throw new Error('Invalid offer string');\n\n// Create SDK instance with the decoded relay and pubkey\nconst sdk = new ClinkSDK({\n  privateKey: generateSecretKey(), // Uint8Array\n  relays: [decoded.data.relay],\n  toPubKey: decoded.data.pubkey,\n});\n\nconst request: NofferData = {\n  offer: decoded.data.offer,\n  amount_sats: 1000, // sats (optional for variable/spontaneous offers)\n  description: 'coffee for bob', // optional, max 100 chars\n  expires_in_seconds: 3600, // optional\n  payer_data: { name: 'Alice' }, // optional\n};\n\n// Optional: Pass a receipt callback to be notified when the invoice is paid\nconst receiptCallback = (receipt) =\u003e {\n  console.log(\"got receipt\", receipt); // receipt will be { res: 'ok' }\n};\nsdk.Noffer(request, receiptCallback).then(response =\u003e {\n  if ('bolt11' in response) {\n    console.log('Invoice:', response.bolt11);\n  } else {\n    console.error('Error:', response.error);\n  }\n});\n```\n\n### 3. Sending a CLINK Debit Request\n\n```ts\nimport { ClinkSDK, NdebitData, generateSecretKey } from '@shocknet/clink-sdk';\n\nconst sdk = new ClinkSDK({\n  privateKey: generateSecretKey(),\n  relays: ['wss://relay.example.com'],\n  toPubKey: '\u003cwallet_service_pubkey_hex\u003e',\n});\n\n// Request the service to pay an invoice\nconst simplePaymentRequest = newNdebitPaymentRequest('\u003cBOLT11_invoice_string\u003e', 5000, 'my_pointer_id')\n\nsdk.Ndebit(simplePaymentRequest).then(response =\u003e {\n  if (response.res === 'ok') {\n    if ('preimage' in response) {\n      console.log('Payment preimage:', response.preimage);\n    } else {\n      console.log('Payment settled internally.');\n    }\n  } else if (response.res === 'GFY') {\n    console.error('Debit error:', response.error);\n  }\n});\n\n// Request whitelisting for future payment requests\nconst fullAccessRequest = newNdebitFullAccessRequest('my_pointer_id')\n\nsdk.Ndebit(fullAccessRequest).then(response =\u003e {\n  if (response.res === 'ok') {\n    console.log('Full access aproved:');\n  } else if (response.res === 'GFY') {\n    console.error('Full access request failed:', response.error);\n  }\n});\n\n// Request a budget\nconst budgetRequest = newNdebitBudgetRequest({ number: 1, unit: 'week' }, 1000, 'my_pointer_id')\n\nsdk.Ndebit(budgetRequest).then(response =\u003e {\n  if (response.res === 'ok') {\n    console.log('Budget aproved:');\n  } else if (response.res === 'GFY') {\n    console.error('Budget request failed:', response.error);\n  }\n});\n\n```\n\n---\n\n## API Reference\n\n### ClinkSDK\n\n```ts\nnew ClinkSDK(settings: ClinkSettings, pool?: AbstractSimplePool)\n```\n- `settings`: `{ privateKey: Uint8Array, relays: string[], toPubKey: string, defaultTimeoutSeconds?: number }`\n- `pool`: Optional, pass a custom Nostr pool (defaults to `SimplePool` from nostr-tools).\n\n#### Methods\n- `Noffer(data: NofferData, onReceipt?: (receipt: NofferReceipt) =\u003e void, timeoutSeconds?: number)`\n  - Sends a `kind: 21001` offer request.\n  - Returns a `Promise\u003cNofferResponse\u003e` that resolves with the invoice or an error.\n  - The optional `onReceipt` callback is triggered when the invoice is paid. **You must pass the callback as a parameter**—simply defining it is not enough.\n- `Ndebit(data: NdebitData, timeoutSeconds?: number)`\n  - Sends a `kind: 21002` debit request.\n  - Returns a `Promise\u003cNdebitResponse\u003e` that resolves with the payment/budget confirmation or an error.\n- `Nmanage(data: NmanageRequest, timeoutSeconds?: number)`\n  - Sends a `kind: 21003` management request.\n  - Returns a `Promise\u003cNmanageResponse\u003e` that resolves with the result of the management action.\n\n\n### Encoding/Decoding\n- `nofferEncode(offer: OfferPointer): string`\n- `ndebitEncode(debit: DebitPointer): string`\n- `decodeBech32(nip19: string): DecodeResult`\n\n### Types\n- **`NofferData`**: `{ offer: string, amount_sats?: number, description?: string, expires_in_seconds?: number, zap?: string, payer_data?: any }`\n- **`NofferResponse`**: `{ bolt11: string } | { code: number, error: string, range?: { min: number, max: number } }`\n- **`NofferReceipt`**: `{ res: 'ok' }` - The receipt object sent when an invoice is paid\n- **`NdebitData`**: `{ pointer?: string, amount_sats?: number, bolt11?: string, frequency?: BudgetFrequency }`\n- **`NdebitResponse`**: `{ res: 'ok', preimage?: string } | { res: 'GFY', error: string, code: number }`\n- **`OfferPointer`**: `{ pubkey: string, relay: string, offer: string, priceType: OfferPriceType, price?: number }`\n- **`DebitPointer`**: `{ pubkey: string, relay: string, pointer?: string }`\n- **`OfferPriceType`**: `enum { Fixed = 0, Variable = 1, Spontaneous = 2 }`\n- **`BudgetFrequency`**: `{ number: number, unit: 'day' | 'week' | 'month' }`\n\n---\n\n## Protocol\n\n- [CLINK Protocol Overview](https://github.com/shocknet/CLINK)\n\n---\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshocknet%2Fclinksdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshocknet%2Fclinksdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshocknet%2Fclinksdk/lists"}