►
From YouTube: Local-First, Multi-Device Applications With IPFS - Horacio Herrera, Alexander Burdiyan
Description
In this talk, we'd like to share the ideas and technical approaches we came up with while building Mintter on top of IPFS for the past 2.5 years. Some of the challenges we faced didn’t have easy, or plug-and-play solutions at the time, such as multi-device, decentralized identity, version control, etc.
Mintter is a hypertext system for knowledge management in open discussion groups. While working on the product, we were greatly inspired by the work of the founding fathers of hypertext: Doug Engelbart, Ted Nelson and others.
A
I'm
Mauricio
he's
Alex.
We
are
building
Minter,
which
is
a
local
first
and
Multi-Device
application
using
ipfs.
So.
A
A
I'm
sure
you
are
all
more
interested
in
the
actual
Tech,
not
the
not
the
product
side
of
things,
but
we
think
that
the
public
duration
processing
crisis
like
these
are
some
of
the
examples.
So
we
did
a
lot
of
research
and
we
found
that
I'm
sorry
and
we
found
that
hypertext
was
the
the
solution
and
we
found
that
50
years
ago
from
our
founding
file,
which
is
Ted,
Nelson
and
Doug,
Engelbert
I,
don't
know
if
no
one
knows
those
guys
good
awesome.
So
essentially
we
wanted
to
we.
A
We
were
betting,
that
the
centralized
knowledge
collaboration
powered
by
a
Knowledge
Graph,
can
spark
human
collaboration
and
can
solve
most
of
our
challenging
problems
as
Humanity
right.
So
we
built
this
application
and
we
actually
package
everything
or
we
try
to
explain
or
or
use
everything
via
our
Minter
open,
hypertext
document,
which
is
just
a
fancy
way
of
saying
that
it's
a
container
of
content
of
blocks
that
can
I
be
arranged
hierarchically
and
also
anyone
can
create
edit
move
them.
A
A
Fine
grain
links
between
Mentor
documents,
which
is
quite
powerful,
so
some
of
the
challenges
that
from
the
product
side
we
had
to
solve
technically
was
some
of
these
are
here,
so
we
needed
a
way
to
have
the
centralized
identity
to
power,
to
empower
like
human
collaboration,
and
we
need
some
sort
of
Version
Control
System.
We
also
wanted
the
product
to
work
Multi-Device
and
we
needed
the
rich
text
to
apply
Rich
sex
capabilities.
On
top
of
that,
so
people
can
express
better
the
ideas
using
hypertext.
A
So
here's
a
like
a
high
level
architecture
right
now
we
have
a
desktop
application.
That
looks
something
like
this.
You
have
like
the
list
view
of
documents
and
also
like
the
document
view
you
can
see
here
that
you,
you
can
see
some
parts
of
one
document
that
is
reusing
other
parts
of
other
documents
and
here's
also
another
view
that
you
can.
You
can
not
only
see
like
the
base
document,
but
also
the
extension,
the
discussions
or
the
activity
that
is
happening
around
happening
around
that
document.
A
A
Here's
also
that
also
works
multiple
windows,
so
it
doesn't,
you
don't
have
to
be
in
the
same
window
to
show
those
things
and
also
whenever
you
are
referring
to
a
document.
This
is
how
you
do
it.
You
copy
the
right
now,
a
block
ID,
and
then
you
paste
you're,
actually
pasting
a
reference,
you're,
not
pasting,
the
actual
content,
and
it's
all
working
as
it
is
now
and
also
you
can
do
like
some
cool
interactions
like
replying
to
a
document
which
is
you
just
take
a
link
to
that
document.
A
You
write
something
which
is
like
hello
from
ipfs
camp
and
when
you
publish
it,
the
original
document
knows
that
there
is
a
link,
there's
a
backlink
to
it,
so
people
can
start
collaborating
or
discussing
in
a
better
way.
We
have
also
a
link,
a
special
schema.
So
if
someone
sends
you
a
link
via
email,
you
can
paste
that
link
to
our
suite.
A
There
are
menu
in
the
application
and
we'll
look
for
that
document
in
the
local
database
that
we
have
in
in
place
or
or
maybe
in
the
network
like
if
we
don't
find
and
die,
we
just
go
to
the
network
and
and
look
for
it
and
and
render
it
so
local
first,
like
I,
said
it's
everything
we
are
following
this
paradigms
like
started
by
the
guy
from
Ink
and
switch,
which
is
pretty
good.
A
You
can
go
to
that
URL
if
you're
willing
to
learn
more
about
that,
and
we
believe
that
P2P
enables
local
first
and
we
are
betting
on
ipfs
and
lip
B2B
to
do
that.
So
here
is
also
a
very
Nar,
a
very
like
the
100
foot
view
of
the
architectural
application.
We
have
the
main
process
which
is
build
on
tari.
We
have
a
demon
which
is
build
on,
go
and
has
all
the
apfs
and
graph
and
graph
database
and
all
the
things
in
inside,
and
then
we
have
a
web
view.
A
B
So
we
really
believe
that
immutable
nature
of
ipfs
fits
very
really
well
with
our
goals
of
longevity
history,
preservation
and
content
reviews
and,
let's
dive
a
bit
deeper
into
how
we
actually
use
apfs
in
some
ways
it's
a
little
bit
unconventional
because,
for
example,
we
don't
use
Kubo
directly.
We
we
are
kind
of
assembling
our
own
ipfs
node,
using
the
same
lower
level.
B
Components
like
bit
swap
lip
P2P
and
DHD,
but
we
wouldn't
use
like
even
10
percent
of
the
functionality
of
Kubo,
so
we
we
just
don't
embed
it
inside
of
our
app
and
first
of
all,
we
want
to
talk
about
decentralized
identity,
because
if
we
talk
about
a
decentralized
app,
we
need
to
talk
about
identity
and
users,
identity
and
one
of
the
most
important
properties
we
wanted
to
achieve
with
our
identity
model
is
that
devices
don't
need
to
share
any
Keys
between
themselves
between
each
other.
So
we
don't
want
to
compromise
the
whole
user
identity.
B
If
we
just
lose
a
device
and
I,
don't
know
something
happens,
you
look,
you
lose
access.
We
don't
want
to
compromise
your
whole
identity
as
a
person
on
the
network,
so
the
way
it
works
right
now
is
that
the
identity
begins
with
a
cryptographic
seed,
similar
to
your
crypto
wallet
like
ethereum
wallet
or
Bitcoin
wallet.
We
encode
that
into
mnemonic
words,
and
that
is
the
only
part
that
you
need
to
really
keep
secret.
You
need
to
keep
it
handy.
B
B
The
public
part
of
that
key
pair
represents
you
as
a
user
as
an
interview
user,
and
it
becomes
your
user
ID
and
independently
from
that
devices
create
their
own
IDs
totally
at
random,
like
you
would
normally
do
that
when
you
create
your
ipfs
node
for
the
first
time,
you
just
generate
a
key,
and
then
we
essentially
sign
in
a
message
with
the
account
key
saying
that
we
want
to.
We
want
this
device
to
represent
this
account.
So
you
don't
need
to
store
that
key.
B
You
just
sign
a
message
and
then
you
keep
that
as
a
proof
that
you
have
this
cryptographic
verifiable
binding
between
these
two
keys
and
then
you
use
the
device
key
as
a
peer
ID
on
lipid2p,
and
you
do
all
of
your
actions
on
the
network
with
that
key.
But
you
can
always
show
that
proof
that
you
belong
to
that
account
and
you
can
create
multiple
devices
like
that
independently
and
they
are
the
important
thing.
Is
that
they're
disposable?
B
If
you
lose
the
device,
you
can
always
revoke
access,
but
just
signing
another
message
with
this
account
key.
So
you
you
can
just
introduce
the
mnemonic
words
again
another
device
and
you
can
revoke
some
other
device
and
you
just
say
like
don't:
pay
attention
to
this
device
anymore.
I'm.
Not
that's
not
doesn't
belong
to
me.
So
if
we
talk
about
application,
we
need
to
talk
about
mutable
content,
because
we
want
documents
we
want
to
change
them
and
what
we
need.
B
Mutable
content
on
an
immutable
Network
so
traditionally
and
conventionally
this
is
done
on
ipfs
by
having
a
mutable
pointer
like
an
ipns
name
right.
So
you
have
some
piece
of
data
you
want
to
create
a
new.
You
want
to
update
it.
You
create
a
new
piece
of
data
and
you
flip
the
pointer
to
the
new
CID,
and
this
is
a
bit
wasteful.
If
you
want
to
keep
all
of
the
history
forever
like
we
do,
because
you
keep,
you
have
to
keep
the
every
version
of
that
state
in
its
entirety
and
things
like
hemp.
B
Things
like
Unix,
FS
chunking
can
help
that
and
improve
the
situation
for
large
files
or
directories
or
videos,
but
for
small
pieces
of
data.
That's
still
kind
of
wasteful
because
you
wouldn't
make
smaller
blocks
because
sometimes
CID
can
get
larger
than
than
the
content
itself,
and
this
specific
example
is
from
the
ipfs
website,
and
this
is
a
little
bit
extreme,
because
you
have
blocks
that
are
super
small
and
like
having
mutable
pointer
for
these
blocks
and
having
to
keep
all
this
data
around
could
accumulate
and
you
would
have
more
cids
than
content.
B
Actually,
if
you
really
hash
them,
you
could
use,
of
course,
the
raw
CID
to
encode
them
to
embed
that,
but
still
the
more
important
thing
with
this
approach.
With
mutable
pointers,
where
we
think
that
it
falls
short
is,
is
that
it's
inherently
not
Multi-Device,
because
you
have
to
keep
you
have
to
have
the
key
for
ipns
record
to
update
it,
and
we
don't
want
to
share
any
Keys.
As
we
said,
and
when
you're
talking
about
trees
like
we
do
with
Mentor
documents,
they
are
hierarchical,
trees
and-
and
we
want
collaborate
on
them.
B
So
we
could
have
a
use
case.
Like
so
imagine
if
an
ALICE
publishes
a
hierarchical
document,
and
then
we
have
Bob
who
moves
a
Content
block
to
another
place
and
at
the
same
time
we
have
concurrently
Carol
moving
the
same
block
to
another
place.
Having
those
snapshots
of
those
documents
is
just
not
enough
for
making
like
sensible
outcome.
If
you
want
to
merge
those
together,
it's
really
hard.
B
If
we
don't
add
some
additional
information
and
it's
hard
for
having
this
mutable
pointers
that
you
need
to
sign
messages
to
keep
the
pointer
alive
and
to
updated,
so
we
don't
want
to
share
Keys
between
devices
and
we
don't
want
to
share
them
between
untrusted
peers
either.
So
this
is
where
we
think
that
ipns
falls
short
in
this
use
case
and,
interestingly
enough,
I
discovered
this
video
recently
browsing
ipfs
research
websites.
B
So
it
seems
like
there
are
folks
in
the
community
who
thinks
the
same,
that
mutable
pointers
are
not
enough
for
distributed
application
and
we
strongly
believe
that
CRTs
are
the
solution
to
achieve
what
we
want
and
before
there
was
a
panel
I.
Don't
know
how
many
of
you
were
present
here
on
the
panel.
B
They
were
discussing,
crdts
and
and
well
some
of
the
challenges
that
we
have
with
crdts
right
now,
but
we're
going
to
talk
a
little
bit
about
that,
because
we
think
that
they
can
be
made
a
lot
more
simpler
than
they're
currently
trying
to
be
made,
especially
if
we
don't
talk
about
real-time
use
case
like
real-time
collaboration.
B
So,
in
our
case,
we
talk
about
asynchronous
collaboration
and
what
essentially,
what
we
want
is
some
kind
of
a
Version
Control
System,
similar
like
to
get
what
that
we
all
know
I
guess
and
when
we
talk
about
Version,
Control
System.
We
need
to
think
about
whether
we
store
snapshots
of
objects
or
changes
to
objects
and
we've
seen
the
limitations
of
storing
snapshots
with
ipfs.
So
let's
talk
about
storing
changes,
because
this
is
what
we
ended
up
doing
at
Minter.
B
So
what
we
do
is
we
store
changes
to
the
data
instead
of
the
snapshots
and
the
way
we
do
it
is
that
we
create
a
mutable
object
by
declaring
what
we
call
a
permanent.
We
borrowed
this
name
actually
from
another
project
called
perkeep,
it's
unrelated
to
ipfs,
but
also
does
uses
content
addressability
for
many
many
things,
and
essentially
it's
an
it's.
B
A
ipld
object
that
declares
immutable
object
in
our
like
in
the
winter
world
what
it
is
when
it
was
created
who's
the
owner
of
that
object,
and
we
try
to
add
this
at
type
thing
to
all
of
our
ipld
objects
that
we
create,
because
we
think
IPL.
These
are
not
sufficiently
self-descriptive
degree.
We
wanted
to
add
some
additional
information
that
seeing
a
piece
of
data
you
know
without
context,
or
at
least
you
can
guess
what
it's
what
it
represents,
and
this
idea
is
also
like
similar
to
what
semantic
web
linked
data
initiative
is
doing.
B
Json,
LD
or
stuff
like
that,
if
you're
familiar
with
that,
so
the
CID
of
that
permanode
becomes
the
ID
of
the
object
and
then
you
apply
changes
to
to
that.
Perma,
node
and
change
says
what
changed
and
who
changed
it.
And
then
you
add
more
changes
that
point
to
previous
ones:
forming
a
hash
chain
of
events,
not
very
different
from
a
change
of
git
commits
or
even
a
blockchain.
B
It's
a
rather
damp
protocol
right
now,
but
there
are
ways
to
improve
it
and
well.
We
are
not
the
only
ones
who
are
taking
this
approach
for
mutable
data
on
ipfs
projects
like
textile
ceramic
orbiti,
query
rest
in
peace
and
others
took
a
similar
route
to
representing
immutable
data.
So
you
could
have
they
all
based
on
the
idea
of
an
append,
Only
log.
B
B
We
all
know
what
the
deck
is:
I'm,
not
gonna,
dig
into
that.
So
what's
inside
of
those
changes,
and
we
landed
on
this
rather
simplistic
data
model
for
our
crdt,
we
essentially
say
that
a
minor
object
is
kind
of
a
namespace,
a
scope
for
arbitrary
entities
that
are
have
identifiers
that
don't
have
to
be
large
identifiers.
They
only
need
to
be
unique
within
the
namespace
of
the
object,
so
we
just
use
64
bits
bit
random
numbers
in
there
and
those
identifiers.
B
Those
entities
identified
with
these
IDs
have
arbitrary,
attribute
value
Pairs
and
if
you've
ever
worked
with
a
triple
stored
graph
database
or
something
like
that
or
you're
familiar
with
rdf,
you
would
find
this
familiar
and
we
also
add
in
there
the
a
timestamp
we
use
hybrid
logical
clock
for
that
I'm
going
to
declare
it
sounds
a
lot
more
crazy
than
what
it
is
and
we
also
add
origin,
which
is
the
device
side,
the
shorten
it
device
ID
with
about
who
did
this
change?
Who
added
this
attribute?
B
So
that
simple
data
model
is
simple
to
reason
about.
You
can
decompose
pretty
much
any
piece
of
information,
any
piece
of
data
into
these
triple
centity
attribute
and
value.
You
can
even
express
links
between
those
entities.
So
essentially
it's
kind
of
a
little
graph
of
data
and
I
think
that
a
graph
is
like
an
ultimate
crdt,
especially
if
you
don't
remove
anything,
you
only
add
nodes.
B
You
only
add
edges,
so
you
don't
have
any
conflicts
when
you
insert
at
least
and
when
you
read
you
can
do
a
bunch
of
different
tricks
to
represent
a
lot
of
different
data
types
and
a
little
bit
about
hybrid
logical
clock
is
just
a
combined
wall
clock
plus
a
counter
which
you
increment.
If
your
wall
clock
ever
gets,
gets
back
in
time.
B
So
if
you
synchronize
with
ntp
or
anything
or
if
you
receive
an
event,
that's
from
future
time,
then
your
current
wall
clock,
you
get
incrementing
this
counter
and
you
always
produce
a
timestamp
that
it's
in
the
future.
From
all
the
other
events
that
you
that
happened
before
so
summarizing,
we
have
the
Perma
node.
We
have
the
changes.
There
are
those
triples
or
datums
inside
of
each
change.
B
There
are
ipld
links
between
those
changes
and
those
links,
Express
causality
of
events,
so
a
newer
change.
Changes
that
are
linked
in
the
new
change
are
always
happening.
We're
guaranteed
to
have
to
have
happened
before
that
new
change
so
having
this
causality
is
really
important
when
you
implement
the
crdt,
and
essentially
the
state
of
the
object
is
defined
by
a
set
of
those
changes.
B
So
you
get
all
the
changes
you
put
it
to
another
device
and
you
have
the
same
state
of
the
object,
but
we
we
need
some
something
to
identify
the
version
of
an
object
and
to
reference
different
versions
of
things,
because
we
we
want
to
be
able
to
address
things
in
older
versions
of
the
documents
and
stuff
like
that.
So
we
only
need
to
really
identify
the
leaf
nodes
in
this
DAC,
which
is
essentially
like
the
root
of
a
Merkel
deck.
B
But
we
treat
as
a
root
the
Perma
node
in
in
our
case,
and
you
can.
You
can
also
mix
those.
So,
in
this
case,
C3
the
change
teeth
C3
the
leaf
node
is
a
version,
but
C1
and
C2
are
also
versions,
and
the
combination
of
C1
and
C2
is
a
different
version
and
those
two
commute.
It
doesn't
matter
which
one
goes.
First,
the
state
essentially
is
going
to
be
the
same.
B
So
having
all
this
information,
the
causal
dag
of
changes,
Atomic
attributes
and
in
these
attribute
value
pairs,
logical
clocks,
we
can
Implement
different
data
types
and
we
don't
have
time
to
dig
into
the
details
of
each
of
this
of
these
data
types
and
we
are
using
well-known,
crdp
algorithms
adjusting
them
to
this
rather
simplistic
data
model.
So
we
use
RGA
or
causal
tree
algorithm
for
lists.
B
We
use
last
Rider
wind
semantics
for
simple
registers
when
you
need
only
the
last
web
values,
but
the
interesting
one
here
is
the
tree,
because
we
want
those,
we
want
those
trees.
We
want
to
be
able
to
move
a
block
to
a
different
place
and
even
sub
trees
of
those
blocks,
but
we
want
to
merge
those
together
and
generate
a
sensible
outcome
when
we
merge
different
perspective
and
gladly.
B
Unfortunately,
we
didn't
have
to
come
up
with
the
algorithms
ourselves,
so
huge
shout
out
to
Martin
clappen
and
his
team
buy
all
the
for
all
the
research
that
they're
doing
in
the
field
of
crdts,
and
this
particular
paper
describes
the
algorithm
that
allows
you
to
do
a
tree.
Manipulation,
resolving
conflicts,
moving
subtrees
and
what's
important
here
is
that
we
want.
We
want
to
preserve
the
position.
So
it's
a
combination
of
actually
the
last
Rider
when
crdt
plus
a
list
serity.
B
So
we
move
something
to
another
place,
but
we
want
that
node
to
be
at
a
specific
position
in
the
sublist,
so
we
can
combine
those
different
crdts
to
represent
these
manipulations
and
we
store
going
back
to
how
we
store
the
the
accounts
and
these
bindings
between
account
and
devices.
We
store
them
in
a
similar
in
a
similar
way.
We
have
a
separate
object.
That
represents
your
user
account.
B
You
store
there,
your
name,
your
Alias,
your
bio,
whatever
you
want
to
store
there,
and
also
you
store
there,
your
these
cryptographic
bindings
between
devices
and
accounts,
and
we
have
some
more
interesting
things
that
we
don't
have
time
to
talk
about
right.
Now
so
we
do
like
a
lot
of
stuff.
We
have
our
own
Block
store,
backed
by
crdt
by
sqlite.
We
have
a
special
draft
mode.
So
when
you
edited
the
document,
you
don't
need
to
constantly
updating
the
immutable
change.
You
can
write
a
document
in
multiple
settings.
B
You
can
get
back
to
it
later
before
you
publish
it
and
then,
when
you're
ready
to
publish
you
click
and
then
when
it's
create
when
change
is
created
and
it
gets
signed
at
this
time
we
index
ipld
links
between
changes
in
a
separate
index.
So
we
can
query
like
doing
recursive
SQL
queries.
We
can
query
the
ancestry
relationship
between
those
changes,
so
we
can
know
whether
one
change
is
ancestor
of
another
one.
B
We
have
index
for
backlinks.
So
the
thing
that
was
shown
on
the
video
where
you
link
something
and
then
you
can
see
in
the
other
document
that
it
was
linked
in
the
other
document,
we
have
named
versions
which
is
like
you,
give
it's
kind
of
like
a
brand
named
branch
and
Git
You.
You
give
a
name
to
some
version
of
something
and
then
you
you
can
keep
it
like.
Referring
that
to
it
by
name,
we
also
do
grpc
over
lipidop,
which
I
think
some
projects
out.
There
are
also
doing
it's
pretty
fun
and
well.
B
We
think
that
local,
first
crdt
and
peer-to-peer
are
things
that
really
Belong
Together
fit
very
well,
and
essentially
our
future
of
local
Computing.
I,
really
believe
that
you
don't
need
consensus
for
many
applications.
There
are
many
many
valid
use
cases
that
you
can
build
with
local
first
Paradigm
and
many
useful
applications
could
be
built
with
that.
So
you
might
ask
what
about
private
data,
and
the
answer
is
that
we
left
it
for
future
right
now,
focusing
on
open
use
cases,
open
deliberation,
and
the
main
reason
of
that.
B
Right
now
on,
ipfs
is
encrypting
things
in,
but
personally
I'm
not
feeling
comfortable
putting
my
sensitive
data
encrypting
it
on
a
public
lens,
leaving
it
on
a
public
network,
because
right
now
encryption
might
seem
bulletproof,
but
we
don't
know
what's
going
to
happen
in
future
and
as
of
three
days
ago,
we
made
the
repository
public
on
the
call
that
we
had,
so
you
can
visit
us
at
GitHub,
Mentor
team,
slash
mentor,
and
you
could
also
join
our
Discord
community
that
we
have
linked
here.
So
with
that,
thank
you
very
much.
Thank
you
for
having
us.