0.0.151
Private communication channel between two or more participants (Gun public keys). Can be used independently of other Iris stuff.
Used as a core element of iris-messenger.
channel.put(key, value)
and channel.on(key, callback)
.
Note that each participant has their own versions of each key-value — they don't overwrite each other. channel.on()
callback returns them all by default and has a parameter that indicates whose value you got.
While values are encrypted, encryption of keys is not implemented yet.
channel.send()
and channel.getMessages()
for timestamp-indexed chat-style messaging.
Message data is encrypted, but timestamps are public so that peers can return your messages in a sequential order.
You can open a channel with yourself for a private key-value space or a "note to self" type chat with yourself.
Note! As of April 2020 Gun.SEA hashing function is broken on Safari. Channels don't work on Safari unless you patch sea.js by adding this line.
Privacy disclaimer: Channel ids, data values and messages are encrypted, but message timestamps are unencrypted so that peers can return them to you in a sequential order. By looking at the unencrypted timestamps (or Gun subscriptions), it is possible to guess who are communicating with each other. This could be improved by indexing messages by day only, so making the guess would be more difficult, while you could still return them in a semi-sequential order.
(Object)
Name | Description |
---|---|
options.key string
|
your keypair |
options.gun Object
|
gun instance |
options.participants any
|
(optional) string or string array or permissions object ({'pub1':{read:true,write:true,admin:false},'pub2'...}) of participant public keys (your own key is included by default) |
options.chatLink string
|
(optional) chat link instead of participants list |
options.uuid string
|
(group channels only) unique channel identifier. Leave out for new channel. |
options.name string
|
(group channels only) channel name |
// Copy & paste this to console at https://iris.to or other page that has gun, sea and iris-lib
// Due to an unsolved bug, someoneElse's messages only start showing up after a reload
var gun1 = new Gun('https://gun-us.herokuapp.com/gun');
var gun2 = new Gun('https://gun-us.herokuapp.com/gun');
var myKey = await iris.Key.getDefault();
var someoneElse = localStorage.getItem('someoneElsesKey');
if (someoneElse) {
someoneElse = JSON.parse(someoneElse);
} else {
someoneElse = await iris.Key.generate();
localStorage.setItem('someoneElsesKey', JSON.stringify(someoneElse));
}
iris.Channel.initUser(gun1, myKey); // saves myKey.epub to gun.user().get('epub')
iris.Channel.initUser(gun2, someoneElse);
var ourChannel = new iris.Channel({key: myKey, gun: gun1, participants: someoneElse.pub});
var theirChannel = new iris.Channel({key: someoneElse, gun: gun2, participants: myKey.pub});
var myChannels = {}; // you can list them in a user interface
function printMessage(msg, info) {
console.log(`[${new Date(msg.time).toLocaleString()}] ${info.from.slice(0,8)}: ${msg.text}`)
}
iris.Channel.getChannels(gun1, myKey, channel => {
var pub = channel.getCurrentParticipants()[0];
gun1.user(pub).get('profile').get('name').on(name => channel.name = name);
myChannels[pub] = channel;
channel.getMessages(printMessage);
channel.on('mood', (mood, from) => console.log(from.slice(0,8) + ' is feeling ' + mood));
});
// you can play with these in the console:
ourChannel.send('message from myKey');
theirChannel.send('message from someoneElse');
ourChannel.put('mood', 'blessed');
theirChannel.put('mood', 'happy');
https://github.com/irislib/iris-lib/blob/master/__tests__/Channel.js
(any)
(any)
(any)
(any)
(any)
(any)
Calls back with Channels that you have initiated or written to.
Add a chat button to page
(any)
{label, channelOptions}
In order to receive messages from others, this method must be called for newly created users that have not started a channel with an existing user yet.
It saves the user's key.epub (public key for encryption) into their gun user space, so others can find it and write encrypted messages to them.
If you start a channel with an existing user, key.epub is saved automatically and you don't need to call this method.
(any)
(any)
Creates a channel link that can be used for two-way communication, i.e. only one link needs to be exchanged.
(any)
(any)
(any
= 'https://iris.to/'
)
(any)
(any)
(any
= 'https://iris.to/'
)
(any)
(any)
(any)
(any)
(any)
(any)
(any)
(any)
List participants of the channel (other than you)
Subscribe to the changing list of participants by channel admins
(any)
Returns either the uuid of a group channel or the public key of a direct channel.
Get messages from the channel
(any)
Get latest message in this channel. Useful for channel listing.
(any)
Useful for notifications
(integer)
last seen msg time (default: now)
Useful for notifications
(any)
For "seen" status indicator
(any)
Send a message to the channel
(any)
string or {time, text, ...} object
Save the channel to our channels list without sending a message
Subscribe to a key-value pair. Callback returns every participant's value unless you limit it with from param.
Set typing status
(any)
(any
= 5
)
Get typing status
(any)
(any
= 5
)
Get a simple link that points to the channel.
Direct channel: both users need to give their simple links. Use createChatLink() to get a two-way link that needs to be given by one user only.
Group channel: Works only if the link recipient has been already added onto the channel participants list.
(any
= 'https://iris.to/'
)
Get a channel box element that you can add to your page
Experimental. Unlike Channel, this is probably not the most useful class yet.
The essence of Iris: A database of Contacts and SignedMessages within your web of trust.
NOTE: these docs reflect the latest commit at https://github.com/irislib/iris-lib
To use someone else's index (read-only): set options.pubKey
To use your own index: set options.keypair or omit it to use Key.getDefaultKey().
Each added SignedMessage updates the SignedMessage and Contacts indexes and web of trust accordingly.
You can pass options.gun to use custom gun storages and networking settings.
Wait for index.ready promise to resolve before calling instance methods.
(Object)
see default options in example
SocialNetwork
:
index object
https://github.com/irislib/iris-lib/blob/master/__tests__/SocialNetwork.js
Default options:
{
keypair: undefined,
pubKey: undefined,
gun: undefined,
self: undefined,
indexSync: {
importOnAdd: {
enabled: true,
maxMsgCount: 500,
maxMsgDistance: 2
},
subscribe: {
enabled: true,
maxMsgDistance: 1
},
query: {
enabled: true
},
msgTypes: {
all: false,
rating: true,
verification: true,
unverification: true
},
debug: false
}
}
(any
= {}
)
Return existing chats and listen to new chats initiated by friends. Like Channel.getChannels(), but also listens to chats initiated by friends.
(any)
Add a message to messagesByTimestamp and other relevant indexes. Update identities in the web of trust according to message data.
(SignedMessage)
SignedMessage (or an array of messages) to add to the index
(any
= {}
)
An Iris Contact, such as person, organization or group. More abstractly speaking: an Identity.
Usually you don't create Contacts yourself, but get them from SocialNetwork methods such as get() and search().
(Object)
node where the Contact data lives
(any)
Appends an identity search widget to the given HTMLElement
(HTMLElement)
element where the search widget is added and event listener attached
(Index)
index root to use for search
Appends an identity search widget to the given HTMLElement
(HTMLElement)
element where the search widget is added and event listener attached
(Index)
index root to use for search
HTMLElement
:
profile card html element describing the identity
HTMLElement
:
profile card html element describing the identity
(Object
= {}
)
{width: 50, border: 4, showDistance: true, outerGlow: false}
HTMLElement
:
identicon element that can be appended to DOM
(Object
= {}
)
{width: 50, border: 4, showDistance: true, outerGlow: false}
HTMLElement
:
identicon element that can be appended to DOM
An Iris Contact, such as person, organization or group. More abstractly speaking: an Identity.
Usually you don't create Contacts yourself, but get them from SocialNetwork methods such as get() and search().
(Object)
node where the Contact data lives
(any)
Appends an identity search widget to the given HTMLElement
(HTMLElement)
element where the search widget is added and event listener attached
(Index)
index root to use for search
Appends an identity search widget to the given HTMLElement
(HTMLElement)
element where the search widget is added and event listener attached
(Index)
index root to use for search
HTMLElement
:
profile card html element describing the identity
HTMLElement
:
profile card html element describing the identity
(Object
= {}
)
{width: 50, border: 4, showDistance: true, outerGlow: false}
HTMLElement
:
identicon element that can be appended to DOM
(Object
= {}
)
{width: 50, border: 4, showDistance: true, outerGlow: false}
HTMLElement
:
identicon element that can be appended to DOM
Signed message object. Your friends can index and relay your messages, while others can still verify that they were signed by you.
Fields: signedData, signer (public key) and signature.
signedData has an author, signer, type, time and optionally other fields.
signature covers the utf8 string representation of signedData. Since messages are digitally signed, users only need to care about the message signer and not who relayed it or whose index it was found from.
signer is the entity that verified its origin. In other words: message author and signer can be different entities, and only the signer needs to use Iris.
For example, a crawler can import and sign other people's messages from Twitter. Only the users who trust the crawler will see the messages.
"Rating" type messages, when added to an SocialNetwork, can add or remove Identities from the web of trust. Verification/unverification messages can add or remove Attributes from an Contact. Other types of messages such as social media "post" are just indexed by their author, recipient and time.
Constructor: creates a message from the param obj.signedData that must contain at least the mandatory fields: author, recipient, type and time. You can use createRating() and createVerification() to automatically populate some of these fields and optionally sign the message.
(Object)
https://github.com/irislib/iris-lib/blob/master/__tests__/SignedMessage.js
Rating message:
{
signedData: {
author: {name:'Alice', key:'ABCD1234'},
recipient: {name:'Bob', email:'bob@example.com'},
type: 'rating',
rating: 1,
maxRating: 10,
minRating: -10,
text: 'Traded 1 BTC'
},
signer: 'ABCD1234',
signature: '1234ABCD'
}
Verification message:
{
signedData: {
author: {name:'Alice', key:'ABCD1234'},
recipient: {
name: 'Bob',
email: ['bob@example.com', 'bob.saget@example.com'],
bitcoin: '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa'
},
type: 'verification'
},
signer: 'ABCD1234',
signature: '1234ABCD'
}
Create an iris message. SignedMessage time is automatically set. If signingKey is specified and author omitted, signingKey will be used as author.
(Object)
message data object including author, recipient and other possible attributes
(Object)
optionally, you can set the key to sign the message with
Promise<SignedMessage>
:
message
(any)
Promise<SignedMessage>
:
Key management utils. Wraps GUN's Gun.SEA. https://gun.eco/docs/Gun.SEA
Load private key from datadir/iris.key on node.js or from local storage 'iris.myKey' in browser.
If the key does not exist, it is generated.
(string
= `.`
)
directory to find key from. In browser, localStorage is used instead.
(any
= `iris.key`
)
Promise<Object>
:
keypair object
Load private key from datadir/iris.key on node.js or from local storage 'iris.myKey' in browser.
If the key does not exist, it is generated.
(string
= `.`
)
directory to find key from. In browser, localStorage is used instead.
(any
= `iris.key`
)
Promise<Object>
:
keypair object
(any)
(any
= true
)
(any
= `.`
)
(any
= `iris.key`
)
(any)
(any
= true
)
(any
= `.`
)
(any
= `iris.key`
)
Key management utils. Wraps GUN's Gun.SEA. https://gun.eco/docs/Gun.SEA
Load private key from datadir/iris.key on node.js or from local storage 'iris.myKey' in browser.
If the key does not exist, it is generated.
(string
= `.`
)
directory to find key from. In browser, localStorage is used instead.
(any
= `iris.key`
)
Promise<Object>
:
keypair object
Load private key from datadir/iris.key on node.js or from local storage 'iris.myKey' in browser.
If the key does not exist, it is generated.
(string
= `.`
)
directory to find key from. In browser, localStorage is used instead.
(any
= `iris.key`
)
Promise<Object>
:
keypair object
(any)
(any
= true
)
(any
= `.`
)
(any
= `iris.key`
)
(any)
(any
= true
)
(any
= `.`
)
(any
= `iris.key`
)
A simple key-value pair with helper functions.
Constructor: new Attribute(value), new Attribute(type, value) or new Attribute({type, value})
Generate a visually recognizable representation of the attribute
(object
= {}
)
{width}
HTMLElement
:
identicon div element
Generate a visually recognizable representation of the attribute
(object
= {}
)
{width}
HTMLElement
:
identicon div element
A simple key-value pair with helper functions.
Constructor: new Attribute(value), new Attribute(type, value) or new Attribute({type, value})
Generate a visually recognizable representation of the attribute
(object
= {}
)
{width}
HTMLElement
:
identicon div element
Generate a visually recognizable representation of the attribute
(object
= {}
)
{width}
HTMLElement
:
identicon div element
Gun object collection that provides tools for indexing and search. Decentralize everything!
If opt.class is passed, object.serialize() and opt.class.deserialize() must be defined.
Supports search from multiple indexes. For example, retrieve message feed from your own index and your friends' indexes.
TODO: aggregation TODO: example TODO: scrollable and stretchable "search result window"
(Object
= {}
)
{gun, class, indexes = [], askPeers = true, name = class.name}
(any)
(any =
true
)