Twitter maintains a list of ~35 accounts which it monitors and offers increased visibility including AOC, Joe Biden, Marc Andreessen, and Elon Musk
Nostr will Never do that
https://www.platformer.news/p/the-secret-list-of-twitter-vips-getting
Then why is there verification from valid sources here?? Not necessary right?😂
NIP-06
======
Basic key derivation from mnemonic seed phrase
----------------------------------------------
`draft` `optional` `author:fiatjaf`
[BIP39](https://bips.xyz/39) is used to generate mnemonic seed words and derive a binary seed from them.
[BIP32](https://bips.xyz/32) is used to derive the path `m/44'/1237'/0'/0/0` (according to the Nostr entry on [SLIP44](https://github.com/satoshilabs/slips/blob/master/slip-0044.md)).
This is the default for a basic, normal, single-key client.
Other types of clients can still get fancy and use other derivation paths for their own other purposes.
NIP-07
======
`window.nostr` capability for web browsers
------------------------------------------
`draft` `optional` `author:fiatjaf`
The `window.nostr` object may be made available by web browsers or extensions and websites or web-apps may make use of it after checking its availability.
That object must define the following methods:
```
async window.nostr.getPublicKey(): string // returns a public key as hex
async window.nostr.signEvent(event: Event): Event // takes an event object, adds `id`, `pubkey` and `sig` and returns it
```
Aside from these two basic above, the following functions can also be implemented optionally:
```
async window.nostr.getRelays(): { [url: string]: {read: boolean, write: boolean} } // returns a basic map of relay urls to relay policies
async window.nostr.nip04.encrypt(pubkey, plaintext): string // returns ciphertext and iv as specified in nip-04
async window.nostr.nip04.decrypt(pubkey, ciphertext): string // takes ciphertext and iv as specified in nip-04
```
### Implementation
- [nos2x](https://github.com/fiatjaf/nos2x) (Chrome and derivatives)
- [Alby](https://getalby.com) (Chrome and derivatives, Firefox, Safari)
- [Blockcore](https://www.blockcore.net/wallet) (Chrome and derivatives)
- [nos2x-fox](https://diegogurpegui.com/nos2x-fox/) (Firefox)
- [Flamingo](https://www.getflamingo.org/) (Chrome and derivatives)
NIP-05
======
Mapping Nostr keys to DNS-based internet identifiers
----------------------------------------------------
`final` `optional` `author:fiatjaf` `author:mikedilger`
On events of kind `0` (`set_metadata`) one can specify the key `"nip05"` with an [internet identifier](https://datatracker.ietf.org/doc/html/rfc5322#section-3.4.1) (an email-like address) as the value. Although there is a link to a very liberal "internet identifier" specification above, NIP-05 assumes the `
Upon seeing that, the client splits the identifier into `
The result should be a JSON document object with a key `"names"` that should then be a mapping of names to hex formatted public keys. If the public key for the given `
### Example
If a client sees an event like this:
```json
{
"pubkey": "b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9",
"kind": 0,
"content": "{\"name\": \"bob\", \"nip05\": \"bob@example.com\"}"
...
}
```
It will make a GET request to `https://example.com/.well-known/nostr.json?name=bob` and get back a response that will look like
```json
{
"names": {
"bob": "b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9"
}
}
````
or with the **optional** `"relays"` attribute:
```json
{
"names": {
"bob": "b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9"
},
"relays": {
"b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9": [ "wss://relay.example.com", "wss://relay2.example.com" ]
}
}
````
If the pubkey matches the one given in `"names"` (as in the example above) that means the association is right and the `"nip05"` identifier is valid and can be displayed.
The optional `"relays"` attribute may contain an object with public keys as properties and arrays of relay URLs as values. When present, that can be used to help clients learn in which relays that user may be found. Web servers which serve `/.well-known/nostr.json` files dynamically based on the query string SHOULD also serve the relays data for any name they serve in the same reply when that is available.
## Finding users from their NIP-05 identifier
A client may implement support for finding users' public keys from _internet identifiers_, the flow is the same as above, but reversed: first the client fetches the _well-known_ URL and from there it gets the public key of the user, then it tries to fetch the kind `0` event for that user and check if it has a matching `"nip05"`.
## Notes
### Clients must always follow public keys, not NIP-05 addresses
For example, if after finding that `bob@bob.com` has the public key `abc...def`, the user clicks a button to follow that profile, the client must keep a primary reference to `abc...def`, not `bob@bob.com`. If, for any reason, the address `https://bob.com/.well-known/nostr.json?name=bob` starts returning the public key `1d2...e3f` at any time in the future, the client must not replace `abc...def` in his list of followed profiles for the user (but it should stop displaying "bob@bob.com" for that user, as that will have become an invalid `"nip05"` property).
### Public keys must be in hex format
Keys must be returned in hex format. Keys in NIP-19 `npub` format are are only meant to be used for display in client UIs, not in this NIP.
### User Discovery implementation suggestion
A client can also use this to allow users to search other profiles. If a client has a search box or something like that, a user may be able to type "bob@example.com" there and the client would recognize that and do the proper queries to obtain a pubkey and suggest that to the user.
### Showing just the domain as an identifier
Clients may treat the identifier `_@domain` as the "root" identifier, and choose to display it as just the `
### Reasoning for the `/.well-known/nostr.json?name=
By adding the `
### Allowing access from JavaScript apps
JavaScript Nostr apps may be restricted by browser [CORS][] policies that prevent them from accessing `/.well-known/nostr.json` on the user's domain. When CORS prevents JS from loading a resource, the JS program sees it as a network failure identical to the resource not existing, so it is not possible for a pure-JS app to tell the user for certain that the failure was caused by a CORS issue. JS Nostr apps that see network failures requesting `/.well-known/nostr.json` files may want to recommend to users that they check the CORS policy of their servers, e.g.:
```bash
$ curl -sI https://example.com/.well-known/nostr.json?name=bob | grep -i ^Access-Control
Access-Control-Allow-Origin: *
```
Users should ensure that their `/.well-known/nostr.json` is served with the HTTP header `Access-Control-Allow-Origin: *` to ensure it can be validated by pure JS apps running in modern browsers.
[CORS]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
### Security Constraints
The `/.well-known/nostr.json` endpoint MUST NOT return any HTTP redirects.
Fetchers MUST ignore any HTTP redirects given by the `/.well-known/nostr.json` endpoint.
NIP-06
======
Basic key derivation from mnemonic seed phrase
----------------------------------------------
`draft` `optional` `author:fiatjaf`
[BIP39](https://bips.xyz/39) is used to generate mnemonic seed words and derive a binary seed from them.
[BIP32](https://bips.xyz/32) is used to derive the path `m/44'/1237'/0'/0/0` (according to the Nostr entry on [SLIP44](https://github.com/satoshilabs/slips/blob/master/slip-0044.md)).
This is the default for a basic, normal, single-key client.
Other types of clients can still get fancy and use other derivation paths for their own other purposes.
NIP-04
======
Encrypted Direct Message
------------------------
`final` `optional` `author:arcbtc`
A special event with kind `4`, meaning "encrypted direct message". It is supposed to have the following attributes:
**`content`** MUST be equal to the base64-encoded, aes-256-cbc encrypted string of anything a user wants to write, encrypted using a shared cipher generated by combining the recipient's public-key with the sender's private-key; this appended by the base64-encoded initialization vector as if it was a querystring parameter named "iv". The format is the following: `"content": "
**`tags`** MUST contain an entry identifying the receiver of the message (such that relays may naturally forward this event to them), in the form `["p", "
**`tags`** MAY contain an entry identifying the previous message in a conversation or a message we are explicitly replying to (such that contextual, more organized conversations may happen), in the form `["e", "
**Note**: By default in the [libsecp256k1](https://github.com/bitcoin-core/secp256k1) ECDH implementation, the secret is the SHA256 hash of the shared point (both X and Y coordinates). In Nostr, only the X coordinate of the shared point is used as the secret and it is NOT hashed. If using libsecp256k1, a custom function that copies the X coordinate must be passed as the `hashfp` argument in `secp256k1_ecdh`. See [here](https://github.com/bitcoin-core/secp256k1/blob/master/src/modules/ecdh/main_impl.h#L29).
Code sample for generating such an event in JavaScript:
```js
import crypto from 'crypto'
import * as secp from '@noble/secp256k1'
let sharedPoint = secp.getSharedSecret(ourPrivateKey, '02' + theirPublicKey)
let sharedX = sharedPoint.slice(1, 33)
let iv = crypto.randomFillSync(new Uint8Array(16))
var cipher = crypto.createCipheriv(
'aes-256-cbc',
Buffer.from(sharedX),
iv
)
let encryptedMessage = cipher.update(text, 'utf8', 'base64')
encryptedMessage += cipher.final('base64')
let ivBase64 = Buffer.from(iv.buffer).toString('base64')
let event = {
pubkey: ourPubKey,
created_at: Math.floor(Date.now() / 1000),
kind: 4,
tags: [['p', theirPublicKey]],
content: encryptedMessage + '?iv=' + ivBase64
}
```
## Security Warning
This standard does not go anywhere near what is considered the state-of-the-art in encrypted communication between peers, and it leaks metadata in the events, therefore it must not be used for anything you really need to keep secret, and only with relays that use `AUTH` to restrict who can fetch your `kind:4` events.
## Client Implementation Warning
Client's *should not* search and replace public key or note references from the `.content`. If processed like a regular text note (where `@npub...` is replaced with `#[0]` with a `["p", "..."]` tag) the tags are leaked and the mentioned user will receive the message in their inbox.
NIP-05
======
Mapping Nostr keys to DNS-based internet identifiers
----------------------------------------------------
`final` `optional` `author:fiatjaf` `author:mikedilger`
On events of kind `0` (`set_metadata`) one can specify the key `"nip05"` with an [internet identifier](https://datatracker.ietf.org/doc/html/rfc5322#section-3.4.1) (an email-like address) as the value. Although there is a link to a very liberal "internet identifier" specification above, NIP-05 assumes the `
Upon seeing that, the client splits the identifier into `
The result should be a JSON document object with a key `"names"` that should then be a mapping of names to hex formatted public keys. If the public key for the given `
### Example
If a client sees an event like this:
```json
{
"pubkey": "b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9",
"kind": 0,
"content": "{\"name\": \"bob\", \"nip05\": \"bob@example.com\"}"
...
}
```
It will make a GET request to `https://example.com/.well-known/nostr.json?name=bob` and get back a response that will look like
```json
{
"names": {
"bob": "b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9"
}
}
````
or with the **optional** `"relays"` attribute:
```json
{
"names": {
"bob": "b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9"
},
"relays": {
"b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9": [ "wss://relay.example.com", "wss://relay2.example.com" ]
}
}
````
If the pubkey matches the one given in `"names"` (as in the example above) that means the association is right and the `"nip05"` identifier is valid and can be displayed.
The optional `"relays"` attribute may contain an object with public keys as properties and arrays of relay URLs as values. When present, that can be used to help clients learn in which relays that user may be found. Web servers which serve `/.well-known/nostr.json` files dynamically based on the query string SHOULD also serve the relays data for any name they serve in the same reply when that is available.
## Finding users from their NIP-05 identifier
A client may implement support for finding users' public keys from _internet identifiers_, the flow is the same as above, but reversed: first the client fetches the _well-known_ URL and from there it gets the public key of the user, then it tries to fetch the kind `0` event for that user and check if it has a matching `"nip05"`.
## Notes
### Clients must always follow public keys, not NIP-05 addresses
For example, if after finding that `bob@bob.com` has the public key `abc...def`, the user clicks a button to follow that profile, the client must keep a primary reference to `abc...def`, not `bob@bob.com`. If, for any reason, the address `https://bob.com/.well-known/nostr.json?name=bob` starts returning the public key `1d2...e3f` at any time in the future, the client must not replace `abc...def` in his list of followed profiles for the user (but it should stop displaying "bob@bob.com" for that user, as that will have become an invalid `"nip05"` property).
### Public keys must be in hex format
Keys must be returned in hex format. Keys in NIP-19 `npub` format are are only meant to be used for display in client UIs, not in this NIP.
### User Discovery implementation suggestion
A client can also use this to allow users to search other profiles. If a client has a search box or something like that, a user may be able to type "bob@example.com" there and the client would recognize that and do the proper queries to obtain a pubkey and suggest that to the user.
### Showing just the domain as an identifier
Clients may treat the identifier `_@domain` as the "root" identifier, and choose to display it as just the `
### Reasoning for the `/.well-known/nostr.json?name=
By adding the `
### Allowing access from JavaScript apps
JavaScript Nostr apps may be restricted by browser [CORS][] policies that prevent them from accessing `/.well-known/nostr.json` on the user's domain. When CORS prevents JS from loading a resource, the JS program sees it as a network failure identical to the resource not existing, so it is not possible for a pure-JS app to tell the user for certain that the failure was caused by a CORS issue. JS Nostr apps that see network failures requesting `/.well-known/nostr.json` files may want to recommend to users that they check the CORS policy of their servers, e.g.:
```bash
$ curl -sI https://example.com/.well-known/nostr.json?name=bob | grep -i ^Access-Control
Access-Control-Allow-Origin: *
```
Users should ensure that their `/.well-known/nostr.json` is served with the HTTP header `Access-Control-Allow-Origin: *` to ensure it can be validated by pure JS apps running in modern browsers.
[CORS]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
### Security Constraints
The `/.well-known/nostr.json` endpoint MUST NOT return any HTTP redirects.
Fetchers MUST ignore any HTTP redirects given by the `/.well-known/nostr.json` endpoint.
NIP-04
======
Encrypted Direct Message
------------------------
`final` `optional` `author:arcbtc`
A special event with kind `4`, meaning "encrypted direct message". It is supposed to have the following attributes:
**`content`** MUST be equal to the base64-encoded, aes-256-cbc encrypted string of anything a user wants to write, encrypted using a shared cipher generated by combining the recipient's public-key with the sender's private-key; this appended by the base64-encoded initialization vector as if it was a querystring parameter named "iv". The format is the following: `"content": "
**`tags`** MUST contain an entry identifying the receiver of the message (such that relays may naturally forward this event to them), in the form `["p", "
**`tags`** MAY contain an entry identifying the previous message in a conversation or a message we are explicitly replying to (such that contextual, more organized conversations may happen), in the form `["e", "
**Note**: By default in the [libsecp256k1](https://github.com/bitcoin-core/secp256k1) ECDH implementation, the secret is the SHA256 hash of the shared point (both X and Y coordinates). In Nostr, only the X coordinate of the shared point is used as the secret and it is NOT hashed. If using libsecp256k1, a custom function that copies the X coordinate must be passed as the `hashfp` argument in `secp256k1_ecdh`. See [here](https://github.com/bitcoin-core/secp256k1/blob/master/src/modules/ecdh/main_impl.h#L29).
Code sample for generating such an event in JavaScript:
```js
import crypto from 'crypto'
import * as secp from '@noble/secp256k1'
let sharedPoint = secp.getSharedSecret(ourPrivateKey, '02' + theirPublicKey)
let sharedX = sharedPoint.slice(1, 33)
let iv = crypto.randomFillSync(new Uint8Array(16))
var cipher = crypto.createCipheriv(
'aes-256-cbc',
Buffer.from(sharedX),
iv
)
let encryptedMessage = cipher.update(text, 'utf8', 'base64')
encryptedMessage += cipher.final('base64')
let ivBase64 = Buffer.from(iv.buffer).toString('base64')
let event = {
pubkey: ourPubKey,
created_at: Math.floor(Date.now() / 1000),
kind: 4,
tags: [['p', theirPublicKey]],
content: encryptedMessage + '?iv=' + ivBase64
}
```
## Security Warning
This standard does not go anywhere near what is considered the state-of-the-art in encrypted communication between peers, and it leaks metadata in the events, therefore it must not be used for anything you really need to keep secret, and only with relays that use `AUTH` to restrict who can fetch your `kind:4` events.
## Client Implementation Warning
Client's *should not* search and replace public key or note references from the `.content`. If processed like a regular text note (where `@npub...` is replaced with `#[0]` with a `["p", "..."]` tag) the tags are leaked and the mentioned user will receive the message in their inbox.
NIP-03
======
OpenTimestamps Attestations for Events
--------------------------------------
`draft` `optional` `author:fiatjaf`
When there is an OTS available it MAY be included in the existing event body under the `ots` key:
```
{
"id": ...,
"kind": ...,
...,
...,
"ots":
}
```
The _event id_ MUST be used as the raw hash to be included in the OpenTimestamps merkle tree.
The attestation can be either provided by relays automatically (and the OTS binary contents just appended to the events it receives) or by clients themselves when they first upload the event to relays — and used by clients to show that an event is really "at least as old as [OTS date]".
NIP-02
======
Contact List and Petnames
-------------------------
`final` `optional` `author:fiatjaf` `author:arcbtc`
A special event with kind `3`, meaning "contact list" is defined as having a list of `p` tags, one for each of the followed/known profiles one is following.
Each tag entry should contain the key for the profile, a relay URL where events from that key can be found (can be set to an empty string if not needed), and a local name (or "petname") for that profile (can also be set to an empty string or not provided), i.e., `["p", <32-bytes hex key>,
For example:
```json
{
"kind": 3,
"tags": [
["p", "91cf9..4e5ca", "wss://alicerelay.com/", "alice"],
["p", "14aeb..8dad4", "wss://bobrelay.com/nostr", "bob"],
["p", "612ae..e610f", "ws://carolrelay.com/ws", "carol"]
],
"content": "",
...other fields
}
```
Every new contact list that gets published overwrites the past ones, so it should contain all entries. Relays and clients SHOULD delete past contact lists as soon as they receive a new one.
## Uses
### Contact list backup
If one believes a relay will store their events for sufficient time, they can use this kind-3 event to backup their following list and recover on a different device.
### Profile discovery and context augmentation
A client may rely on the kind-3 event to display a list of followed people by profiles one is browsing; make lists of suggestions on who to follow based on the contact lists of other people one might be following or browsing; or show the data in other contexts.
### Relay sharing
A client may publish a full list of contacts with good relays for each of their contacts so other clients may use these to update their internal relay lists if needed, increasing censorship-resistance.
### Petname scheme
The data from these contact lists can be used by clients to construct local ["petname"](http://www.skyhunter.com/marcs/petnames/IntroPetNames.html) tables derived from other people's contact lists. This alleviates the need for global human-readable names. For example:
A user has an internal contact list that says
```json
[
["p", "21df6d143fb96c2ec9d63726bf9edc71", "", "erin"]
]
```
And receives two contact lists, one from `21df6d143fb96c2ec9d63726bf9edc71` that says
```json
[
["p", "a8bb3d884d5d90b413d9891fe4c4e46d", "", "david"]
]
```
and another from `a8bb3d884d5d90b413d9891fe4c4e46d` that says
```json
[
["p", "f57f54057d2a7af0efecc8b0b66f5708", "", "frank"]
]
```
When the user sees `21df6d143fb96c2ec9d63726bf9edc71` the client can show _erin_ instead;
When the user sees `a8bb3d884d5d90b413d9891fe4c4e46d` the client can show _david.erin_ instead;
When the user sees `f57f54057d2a7af0efecc8b0b66f5708` the client can show _frank.david.erin_ instead.
NIP-01
Basic protocol flow description
draft mandatory author:fiatjaf author:distbit author:scsibug author:kukks author:jb55
This NIP defines the basic protocol that should be implemented by everybody. New NIPs may add new optional (or mandatory) fields and messages and features to the structures and flows described here.
Events and signatures
Each user has a keypair. Signatures, public key, and encodings are done according to the Schnorr signatures standard for the curve secp256k1.
The only object type that exists is the event, which has the following format on the wire:
{
"id": <32-bytes lowercase hex-encoded sha256 of the serialized event data>
"pubkey": <32-bytes lowercase hex-encoded public key of the event creator>,
"created_at":
"kind":
"tags": [
["e", <32-bytes hex of the id of another event>,
["p", <32-bytes hex of a pubkey>,
... // other kinds of tags may be included later
],
"content":
"sig": <64-bytes hex of the signature of the sha256 hash of the serialized event data, which is the same as the "id" field>
}
To obtain the event.id, we sha256 the serialized event. The serialization is done over the UTF-8 JSON-serialized string (with no white space or line breaks) of the following structure:
[
0,
]
Communication between clients and relays
Relays expose a websocket endpoint to which clients can connect.
From client to relay: sending events and creating subscriptions
Clients can send 3 types of messages, which must be JSON arrays, according to the following patterns:
["EVENT",
["REQ",
["CLOSE",
{
"ids": ,
"authors": ,
"kinds": ,
"#e": ,
"#p": ,
"since":
"until":
"limit":
}
Upon receiving a REQ message, the relay SHOULD query its internal database and return events that match the filter, then store that filter and send again all future events it receives to that same websocket until the websocket is closed. The CLOSE event is received with the same
Filter attributes containing lists (such as ids, kinds, or #e) are JSON arrays with one or more values. At least one of the array's values must match the relevant field in an event for the condition itself to be considered a match. For scalar event attributes such as kind, the attribute from the event must be contained in the filter list. For tag attributes such as #e, where an event may have multiple values, the event and filter condition values must have at least one item in common.
The ids and authors lists contain lowercase hexadecimal strings, which may either be an exact 64-character match, or a prefix of the event value. A prefix match is when the filter string is an exact string prefix of the event value. The use of prefixes allows for more compact filters where a large number of values are queried, and can provide some privacy for clients that may not want to disclose the exact authors or events they are searching for.
All conditions of a filter that are specified must match for an event for it to pass the filter, i.e., multiple conditions are interpreted as && conditions.
A REQ message may contain multiple filters. In this case, events that match any of the filters are to be returned, i.e., multiple filters are to be interpreted as || conditions.
The limit property of a filter is only valid for the initial query and can be ignored afterward. When limit: n is present it is assumed that the events returned in the initial query will be the latest n events. It is safe to return less events than limit specifies, but it is expected that relays do not return (much) more events than requested so clients don't get unnecessarily overwhelmed by data.
From relay to client: sending events and notices
Relays can send 2 types of messages, which must also be JSON arrays, according to the following patterns:
["EVENT",
["NOTICE",
This NIP defines no rules for how NOTICE messages should be sent or treated.
EVENT messages MUST be sent only with a subscription ID related to a subscription previously initiated by the client (using the REQ message above).
Basic Event Kinds
0: set_metadata: the content is set to a stringified JSON object {name:
1: text_note: the content is set to the plaintext content of a note (anything the user wants to say). Markdown links ([]() stuff) are not plaintext.
2: recommend_server: the content is set to the URL (e.g., wss://somerelay.com) of a relay the event creator wants to recommend to its followers.
A relay may choose to treat different message kinds differently, and it may or may not choose to have a default way to handle kinds it doesn't know about.
Other Notes:
Clients should not open more than one websocket to each relay. One channel can support an unlimited number of subscriptions, so clients should do that.
The tags array can store a tag identifier as the first element of each subarray, plus arbitrary information afterward (always as strings). This NIP defines "p" — meaning "pubkey", which points to a pubkey of someone that is referred to in the event —, and "e" — meaning "event", which points to the id of an event this event is quoting, replying to or referring to somehow.
The
- **IPFS** is **not decentralized**
- **Sia** is **not decentralized**
- **Storj** is **not decentralized**
- **Ethereum** is **not decentralized**
- **BSV** is **useless**
- **#bitcoin** is **working**
Check out this thread on why @APompliano is a scammer :
https://twitter.com/Andrew_J_Howard/status/1637526599846248449
The **relentless** #bitcoin scammer
**Please don't follow or listen to this piece of shit**
He is running a whole lot of scams, real shady piece of shit!!
#bitcoin supporters please be careful!!
Ofcourse **do your own research**
Fuck *Anthony Pompliano*
He is **Satoshi** #bitcoin #satoshi
**Reminder**
**#Bitcoin** is a p2p electronic cash system
I said this way back, but goes everything against what we stand for.
If we wants less bots/identify bots
a) use a BOT tag
b) just pay money to countries and asked them provide their central ID API service so that the user can be identified and approved as a human account.
Because he wants is fuckin 'X' app, he is suggesting removing the 'stack' without realizing that the 'stack' is for specifically 'twitter' that makes almost 80-90% of the revenue if i'm not wrong. Moreover lot advertisers left the comapny. What the fuck!. Sorry I just had to rant.
