@abraca/dabra 1.3.0 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,7 @@
1
1
  import * as Y from "yjs";
2
2
  import { retry } from "@lifeomic/attempt";
3
3
  import * as ed from "@noble/ed25519";
4
+ import { generateMnemonic as generateMnemonic$1, mnemonicToSeedSync, validateMnemonic as validateMnemonic$1 } from "@scure/bip39";
4
5
 
5
6
  //#region packages/provider/src/awarenessStatesToArray.ts
6
7
  const awarenessStatesToArray = (states) => {
@@ -3222,6 +3223,30 @@ var AbracadabraClient = class {
3222
3223
  auth: false
3223
3224
  });
3224
3225
  }
3226
+ /** Request a device session token after successful crypto auth. Requires valid JWT. */
3227
+ async requestDeviceSession(opts) {
3228
+ return this.request("POST", "/auth/device-session", { body: {
3229
+ publicKey: opts.publicKey,
3230
+ deviceName: opts.deviceName
3231
+ } });
3232
+ }
3233
+ /** Exchange a device session token for a fresh JWT. No biometric/passkey needed. */
3234
+ async refreshWithDeviceSession(sessionToken) {
3235
+ const res = await this.request("POST", "/auth/refresh", {
3236
+ body: { sessionToken },
3237
+ auth: false
3238
+ });
3239
+ this.token = res.token;
3240
+ return res.token;
3241
+ }
3242
+ /** List active device sessions for the authenticated user. */
3243
+ async listDeviceSessions() {
3244
+ return (await this.request("GET", "/auth/device-session")).sessions;
3245
+ }
3246
+ /** Revoke a device session by ID. */
3247
+ async revokeDeviceSession(sessionId) {
3248
+ await this.request("DELETE", `/auth/device-session/${encodeURIComponent(sessionId)}`);
3249
+ }
3225
3250
  /**
3226
3251
  * Fetch a short-lived anonymous pairing token for WebRTC signaling.
3227
3252
  * No authentication required. The token only grants access to `__pairing_*` rooms.
@@ -7066,23 +7091,2202 @@ const ristretto255_oprf = createORPF({
7066
7091
  hashToScalar: ristretto255_hasher.hashToScalar
7067
7092
  });
7068
7093
 
7094
+ //#endregion
7095
+ //#region node_modules/@scure/bip39/esm/wordlists/english.js
7096
+ const wordlist = `abandon
7097
+ ability
7098
+ able
7099
+ about
7100
+ above
7101
+ absent
7102
+ absorb
7103
+ abstract
7104
+ absurd
7105
+ abuse
7106
+ access
7107
+ accident
7108
+ account
7109
+ accuse
7110
+ achieve
7111
+ acid
7112
+ acoustic
7113
+ acquire
7114
+ across
7115
+ act
7116
+ action
7117
+ actor
7118
+ actress
7119
+ actual
7120
+ adapt
7121
+ add
7122
+ addict
7123
+ address
7124
+ adjust
7125
+ admit
7126
+ adult
7127
+ advance
7128
+ advice
7129
+ aerobic
7130
+ affair
7131
+ afford
7132
+ afraid
7133
+ again
7134
+ age
7135
+ agent
7136
+ agree
7137
+ ahead
7138
+ aim
7139
+ air
7140
+ airport
7141
+ aisle
7142
+ alarm
7143
+ album
7144
+ alcohol
7145
+ alert
7146
+ alien
7147
+ all
7148
+ alley
7149
+ allow
7150
+ almost
7151
+ alone
7152
+ alpha
7153
+ already
7154
+ also
7155
+ alter
7156
+ always
7157
+ amateur
7158
+ amazing
7159
+ among
7160
+ amount
7161
+ amused
7162
+ analyst
7163
+ anchor
7164
+ ancient
7165
+ anger
7166
+ angle
7167
+ angry
7168
+ animal
7169
+ ankle
7170
+ announce
7171
+ annual
7172
+ another
7173
+ answer
7174
+ antenna
7175
+ antique
7176
+ anxiety
7177
+ any
7178
+ apart
7179
+ apology
7180
+ appear
7181
+ apple
7182
+ approve
7183
+ april
7184
+ arch
7185
+ arctic
7186
+ area
7187
+ arena
7188
+ argue
7189
+ arm
7190
+ armed
7191
+ armor
7192
+ army
7193
+ around
7194
+ arrange
7195
+ arrest
7196
+ arrive
7197
+ arrow
7198
+ art
7199
+ artefact
7200
+ artist
7201
+ artwork
7202
+ ask
7203
+ aspect
7204
+ assault
7205
+ asset
7206
+ assist
7207
+ assume
7208
+ asthma
7209
+ athlete
7210
+ atom
7211
+ attack
7212
+ attend
7213
+ attitude
7214
+ attract
7215
+ auction
7216
+ audit
7217
+ august
7218
+ aunt
7219
+ author
7220
+ auto
7221
+ autumn
7222
+ average
7223
+ avocado
7224
+ avoid
7225
+ awake
7226
+ aware
7227
+ away
7228
+ awesome
7229
+ awful
7230
+ awkward
7231
+ axis
7232
+ baby
7233
+ bachelor
7234
+ bacon
7235
+ badge
7236
+ bag
7237
+ balance
7238
+ balcony
7239
+ ball
7240
+ bamboo
7241
+ banana
7242
+ banner
7243
+ bar
7244
+ barely
7245
+ bargain
7246
+ barrel
7247
+ base
7248
+ basic
7249
+ basket
7250
+ battle
7251
+ beach
7252
+ bean
7253
+ beauty
7254
+ because
7255
+ become
7256
+ beef
7257
+ before
7258
+ begin
7259
+ behave
7260
+ behind
7261
+ believe
7262
+ below
7263
+ belt
7264
+ bench
7265
+ benefit
7266
+ best
7267
+ betray
7268
+ better
7269
+ between
7270
+ beyond
7271
+ bicycle
7272
+ bid
7273
+ bike
7274
+ bind
7275
+ biology
7276
+ bird
7277
+ birth
7278
+ bitter
7279
+ black
7280
+ blade
7281
+ blame
7282
+ blanket
7283
+ blast
7284
+ bleak
7285
+ bless
7286
+ blind
7287
+ blood
7288
+ blossom
7289
+ blouse
7290
+ blue
7291
+ blur
7292
+ blush
7293
+ board
7294
+ boat
7295
+ body
7296
+ boil
7297
+ bomb
7298
+ bone
7299
+ bonus
7300
+ book
7301
+ boost
7302
+ border
7303
+ boring
7304
+ borrow
7305
+ boss
7306
+ bottom
7307
+ bounce
7308
+ box
7309
+ boy
7310
+ bracket
7311
+ brain
7312
+ brand
7313
+ brass
7314
+ brave
7315
+ bread
7316
+ breeze
7317
+ brick
7318
+ bridge
7319
+ brief
7320
+ bright
7321
+ bring
7322
+ brisk
7323
+ broccoli
7324
+ broken
7325
+ bronze
7326
+ broom
7327
+ brother
7328
+ brown
7329
+ brush
7330
+ bubble
7331
+ buddy
7332
+ budget
7333
+ buffalo
7334
+ build
7335
+ bulb
7336
+ bulk
7337
+ bullet
7338
+ bundle
7339
+ bunker
7340
+ burden
7341
+ burger
7342
+ burst
7343
+ bus
7344
+ business
7345
+ busy
7346
+ butter
7347
+ buyer
7348
+ buzz
7349
+ cabbage
7350
+ cabin
7351
+ cable
7352
+ cactus
7353
+ cage
7354
+ cake
7355
+ call
7356
+ calm
7357
+ camera
7358
+ camp
7359
+ can
7360
+ canal
7361
+ cancel
7362
+ candy
7363
+ cannon
7364
+ canoe
7365
+ canvas
7366
+ canyon
7367
+ capable
7368
+ capital
7369
+ captain
7370
+ car
7371
+ carbon
7372
+ card
7373
+ cargo
7374
+ carpet
7375
+ carry
7376
+ cart
7377
+ case
7378
+ cash
7379
+ casino
7380
+ castle
7381
+ casual
7382
+ cat
7383
+ catalog
7384
+ catch
7385
+ category
7386
+ cattle
7387
+ caught
7388
+ cause
7389
+ caution
7390
+ cave
7391
+ ceiling
7392
+ celery
7393
+ cement
7394
+ census
7395
+ century
7396
+ cereal
7397
+ certain
7398
+ chair
7399
+ chalk
7400
+ champion
7401
+ change
7402
+ chaos
7403
+ chapter
7404
+ charge
7405
+ chase
7406
+ chat
7407
+ cheap
7408
+ check
7409
+ cheese
7410
+ chef
7411
+ cherry
7412
+ chest
7413
+ chicken
7414
+ chief
7415
+ child
7416
+ chimney
7417
+ choice
7418
+ choose
7419
+ chronic
7420
+ chuckle
7421
+ chunk
7422
+ churn
7423
+ cigar
7424
+ cinnamon
7425
+ circle
7426
+ citizen
7427
+ city
7428
+ civil
7429
+ claim
7430
+ clap
7431
+ clarify
7432
+ claw
7433
+ clay
7434
+ clean
7435
+ clerk
7436
+ clever
7437
+ click
7438
+ client
7439
+ cliff
7440
+ climb
7441
+ clinic
7442
+ clip
7443
+ clock
7444
+ clog
7445
+ close
7446
+ cloth
7447
+ cloud
7448
+ clown
7449
+ club
7450
+ clump
7451
+ cluster
7452
+ clutch
7453
+ coach
7454
+ coast
7455
+ coconut
7456
+ code
7457
+ coffee
7458
+ coil
7459
+ coin
7460
+ collect
7461
+ color
7462
+ column
7463
+ combine
7464
+ come
7465
+ comfort
7466
+ comic
7467
+ common
7468
+ company
7469
+ concert
7470
+ conduct
7471
+ confirm
7472
+ congress
7473
+ connect
7474
+ consider
7475
+ control
7476
+ convince
7477
+ cook
7478
+ cool
7479
+ copper
7480
+ copy
7481
+ coral
7482
+ core
7483
+ corn
7484
+ correct
7485
+ cost
7486
+ cotton
7487
+ couch
7488
+ country
7489
+ couple
7490
+ course
7491
+ cousin
7492
+ cover
7493
+ coyote
7494
+ crack
7495
+ cradle
7496
+ craft
7497
+ cram
7498
+ crane
7499
+ crash
7500
+ crater
7501
+ crawl
7502
+ crazy
7503
+ cream
7504
+ credit
7505
+ creek
7506
+ crew
7507
+ cricket
7508
+ crime
7509
+ crisp
7510
+ critic
7511
+ crop
7512
+ cross
7513
+ crouch
7514
+ crowd
7515
+ crucial
7516
+ cruel
7517
+ cruise
7518
+ crumble
7519
+ crunch
7520
+ crush
7521
+ cry
7522
+ crystal
7523
+ cube
7524
+ culture
7525
+ cup
7526
+ cupboard
7527
+ curious
7528
+ current
7529
+ curtain
7530
+ curve
7531
+ cushion
7532
+ custom
7533
+ cute
7534
+ cycle
7535
+ dad
7536
+ damage
7537
+ damp
7538
+ dance
7539
+ danger
7540
+ daring
7541
+ dash
7542
+ daughter
7543
+ dawn
7544
+ day
7545
+ deal
7546
+ debate
7547
+ debris
7548
+ decade
7549
+ december
7550
+ decide
7551
+ decline
7552
+ decorate
7553
+ decrease
7554
+ deer
7555
+ defense
7556
+ define
7557
+ defy
7558
+ degree
7559
+ delay
7560
+ deliver
7561
+ demand
7562
+ demise
7563
+ denial
7564
+ dentist
7565
+ deny
7566
+ depart
7567
+ depend
7568
+ deposit
7569
+ depth
7570
+ deputy
7571
+ derive
7572
+ describe
7573
+ desert
7574
+ design
7575
+ desk
7576
+ despair
7577
+ destroy
7578
+ detail
7579
+ detect
7580
+ develop
7581
+ device
7582
+ devote
7583
+ diagram
7584
+ dial
7585
+ diamond
7586
+ diary
7587
+ dice
7588
+ diesel
7589
+ diet
7590
+ differ
7591
+ digital
7592
+ dignity
7593
+ dilemma
7594
+ dinner
7595
+ dinosaur
7596
+ direct
7597
+ dirt
7598
+ disagree
7599
+ discover
7600
+ disease
7601
+ dish
7602
+ dismiss
7603
+ disorder
7604
+ display
7605
+ distance
7606
+ divert
7607
+ divide
7608
+ divorce
7609
+ dizzy
7610
+ doctor
7611
+ document
7612
+ dog
7613
+ doll
7614
+ dolphin
7615
+ domain
7616
+ donate
7617
+ donkey
7618
+ donor
7619
+ door
7620
+ dose
7621
+ double
7622
+ dove
7623
+ draft
7624
+ dragon
7625
+ drama
7626
+ drastic
7627
+ draw
7628
+ dream
7629
+ dress
7630
+ drift
7631
+ drill
7632
+ drink
7633
+ drip
7634
+ drive
7635
+ drop
7636
+ drum
7637
+ dry
7638
+ duck
7639
+ dumb
7640
+ dune
7641
+ during
7642
+ dust
7643
+ dutch
7644
+ duty
7645
+ dwarf
7646
+ dynamic
7647
+ eager
7648
+ eagle
7649
+ early
7650
+ earn
7651
+ earth
7652
+ easily
7653
+ east
7654
+ easy
7655
+ echo
7656
+ ecology
7657
+ economy
7658
+ edge
7659
+ edit
7660
+ educate
7661
+ effort
7662
+ egg
7663
+ eight
7664
+ either
7665
+ elbow
7666
+ elder
7667
+ electric
7668
+ elegant
7669
+ element
7670
+ elephant
7671
+ elevator
7672
+ elite
7673
+ else
7674
+ embark
7675
+ embody
7676
+ embrace
7677
+ emerge
7678
+ emotion
7679
+ employ
7680
+ empower
7681
+ empty
7682
+ enable
7683
+ enact
7684
+ end
7685
+ endless
7686
+ endorse
7687
+ enemy
7688
+ energy
7689
+ enforce
7690
+ engage
7691
+ engine
7692
+ enhance
7693
+ enjoy
7694
+ enlist
7695
+ enough
7696
+ enrich
7697
+ enroll
7698
+ ensure
7699
+ enter
7700
+ entire
7701
+ entry
7702
+ envelope
7703
+ episode
7704
+ equal
7705
+ equip
7706
+ era
7707
+ erase
7708
+ erode
7709
+ erosion
7710
+ error
7711
+ erupt
7712
+ escape
7713
+ essay
7714
+ essence
7715
+ estate
7716
+ eternal
7717
+ ethics
7718
+ evidence
7719
+ evil
7720
+ evoke
7721
+ evolve
7722
+ exact
7723
+ example
7724
+ excess
7725
+ exchange
7726
+ excite
7727
+ exclude
7728
+ excuse
7729
+ execute
7730
+ exercise
7731
+ exhaust
7732
+ exhibit
7733
+ exile
7734
+ exist
7735
+ exit
7736
+ exotic
7737
+ expand
7738
+ expect
7739
+ expire
7740
+ explain
7741
+ expose
7742
+ express
7743
+ extend
7744
+ extra
7745
+ eye
7746
+ eyebrow
7747
+ fabric
7748
+ face
7749
+ faculty
7750
+ fade
7751
+ faint
7752
+ faith
7753
+ fall
7754
+ false
7755
+ fame
7756
+ family
7757
+ famous
7758
+ fan
7759
+ fancy
7760
+ fantasy
7761
+ farm
7762
+ fashion
7763
+ fat
7764
+ fatal
7765
+ father
7766
+ fatigue
7767
+ fault
7768
+ favorite
7769
+ feature
7770
+ february
7771
+ federal
7772
+ fee
7773
+ feed
7774
+ feel
7775
+ female
7776
+ fence
7777
+ festival
7778
+ fetch
7779
+ fever
7780
+ few
7781
+ fiber
7782
+ fiction
7783
+ field
7784
+ figure
7785
+ file
7786
+ film
7787
+ filter
7788
+ final
7789
+ find
7790
+ fine
7791
+ finger
7792
+ finish
7793
+ fire
7794
+ firm
7795
+ first
7796
+ fiscal
7797
+ fish
7798
+ fit
7799
+ fitness
7800
+ fix
7801
+ flag
7802
+ flame
7803
+ flash
7804
+ flat
7805
+ flavor
7806
+ flee
7807
+ flight
7808
+ flip
7809
+ float
7810
+ flock
7811
+ floor
7812
+ flower
7813
+ fluid
7814
+ flush
7815
+ fly
7816
+ foam
7817
+ focus
7818
+ fog
7819
+ foil
7820
+ fold
7821
+ follow
7822
+ food
7823
+ foot
7824
+ force
7825
+ forest
7826
+ forget
7827
+ fork
7828
+ fortune
7829
+ forum
7830
+ forward
7831
+ fossil
7832
+ foster
7833
+ found
7834
+ fox
7835
+ fragile
7836
+ frame
7837
+ frequent
7838
+ fresh
7839
+ friend
7840
+ fringe
7841
+ frog
7842
+ front
7843
+ frost
7844
+ frown
7845
+ frozen
7846
+ fruit
7847
+ fuel
7848
+ fun
7849
+ funny
7850
+ furnace
7851
+ fury
7852
+ future
7853
+ gadget
7854
+ gain
7855
+ galaxy
7856
+ gallery
7857
+ game
7858
+ gap
7859
+ garage
7860
+ garbage
7861
+ garden
7862
+ garlic
7863
+ garment
7864
+ gas
7865
+ gasp
7866
+ gate
7867
+ gather
7868
+ gauge
7869
+ gaze
7870
+ general
7871
+ genius
7872
+ genre
7873
+ gentle
7874
+ genuine
7875
+ gesture
7876
+ ghost
7877
+ giant
7878
+ gift
7879
+ giggle
7880
+ ginger
7881
+ giraffe
7882
+ girl
7883
+ give
7884
+ glad
7885
+ glance
7886
+ glare
7887
+ glass
7888
+ glide
7889
+ glimpse
7890
+ globe
7891
+ gloom
7892
+ glory
7893
+ glove
7894
+ glow
7895
+ glue
7896
+ goat
7897
+ goddess
7898
+ gold
7899
+ good
7900
+ goose
7901
+ gorilla
7902
+ gospel
7903
+ gossip
7904
+ govern
7905
+ gown
7906
+ grab
7907
+ grace
7908
+ grain
7909
+ grant
7910
+ grape
7911
+ grass
7912
+ gravity
7913
+ great
7914
+ green
7915
+ grid
7916
+ grief
7917
+ grit
7918
+ grocery
7919
+ group
7920
+ grow
7921
+ grunt
7922
+ guard
7923
+ guess
7924
+ guide
7925
+ guilt
7926
+ guitar
7927
+ gun
7928
+ gym
7929
+ habit
7930
+ hair
7931
+ half
7932
+ hammer
7933
+ hamster
7934
+ hand
7935
+ happy
7936
+ harbor
7937
+ hard
7938
+ harsh
7939
+ harvest
7940
+ hat
7941
+ have
7942
+ hawk
7943
+ hazard
7944
+ head
7945
+ health
7946
+ heart
7947
+ heavy
7948
+ hedgehog
7949
+ height
7950
+ hello
7951
+ helmet
7952
+ help
7953
+ hen
7954
+ hero
7955
+ hidden
7956
+ high
7957
+ hill
7958
+ hint
7959
+ hip
7960
+ hire
7961
+ history
7962
+ hobby
7963
+ hockey
7964
+ hold
7965
+ hole
7966
+ holiday
7967
+ hollow
7968
+ home
7969
+ honey
7970
+ hood
7971
+ hope
7972
+ horn
7973
+ horror
7974
+ horse
7975
+ hospital
7976
+ host
7977
+ hotel
7978
+ hour
7979
+ hover
7980
+ hub
7981
+ huge
7982
+ human
7983
+ humble
7984
+ humor
7985
+ hundred
7986
+ hungry
7987
+ hunt
7988
+ hurdle
7989
+ hurry
7990
+ hurt
7991
+ husband
7992
+ hybrid
7993
+ ice
7994
+ icon
7995
+ idea
7996
+ identify
7997
+ idle
7998
+ ignore
7999
+ ill
8000
+ illegal
8001
+ illness
8002
+ image
8003
+ imitate
8004
+ immense
8005
+ immune
8006
+ impact
8007
+ impose
8008
+ improve
8009
+ impulse
8010
+ inch
8011
+ include
8012
+ income
8013
+ increase
8014
+ index
8015
+ indicate
8016
+ indoor
8017
+ industry
8018
+ infant
8019
+ inflict
8020
+ inform
8021
+ inhale
8022
+ inherit
8023
+ initial
8024
+ inject
8025
+ injury
8026
+ inmate
8027
+ inner
8028
+ innocent
8029
+ input
8030
+ inquiry
8031
+ insane
8032
+ insect
8033
+ inside
8034
+ inspire
8035
+ install
8036
+ intact
8037
+ interest
8038
+ into
8039
+ invest
8040
+ invite
8041
+ involve
8042
+ iron
8043
+ island
8044
+ isolate
8045
+ issue
8046
+ item
8047
+ ivory
8048
+ jacket
8049
+ jaguar
8050
+ jar
8051
+ jazz
8052
+ jealous
8053
+ jeans
8054
+ jelly
8055
+ jewel
8056
+ job
8057
+ join
8058
+ joke
8059
+ journey
8060
+ joy
8061
+ judge
8062
+ juice
8063
+ jump
8064
+ jungle
8065
+ junior
8066
+ junk
8067
+ just
8068
+ kangaroo
8069
+ keen
8070
+ keep
8071
+ ketchup
8072
+ key
8073
+ kick
8074
+ kid
8075
+ kidney
8076
+ kind
8077
+ kingdom
8078
+ kiss
8079
+ kit
8080
+ kitchen
8081
+ kite
8082
+ kitten
8083
+ kiwi
8084
+ knee
8085
+ knife
8086
+ knock
8087
+ know
8088
+ lab
8089
+ label
8090
+ labor
8091
+ ladder
8092
+ lady
8093
+ lake
8094
+ lamp
8095
+ language
8096
+ laptop
8097
+ large
8098
+ later
8099
+ latin
8100
+ laugh
8101
+ laundry
8102
+ lava
8103
+ law
8104
+ lawn
8105
+ lawsuit
8106
+ layer
8107
+ lazy
8108
+ leader
8109
+ leaf
8110
+ learn
8111
+ leave
8112
+ lecture
8113
+ left
8114
+ leg
8115
+ legal
8116
+ legend
8117
+ leisure
8118
+ lemon
8119
+ lend
8120
+ length
8121
+ lens
8122
+ leopard
8123
+ lesson
8124
+ letter
8125
+ level
8126
+ liar
8127
+ liberty
8128
+ library
8129
+ license
8130
+ life
8131
+ lift
8132
+ light
8133
+ like
8134
+ limb
8135
+ limit
8136
+ link
8137
+ lion
8138
+ liquid
8139
+ list
8140
+ little
8141
+ live
8142
+ lizard
8143
+ load
8144
+ loan
8145
+ lobster
8146
+ local
8147
+ lock
8148
+ logic
8149
+ lonely
8150
+ long
8151
+ loop
8152
+ lottery
8153
+ loud
8154
+ lounge
8155
+ love
8156
+ loyal
8157
+ lucky
8158
+ luggage
8159
+ lumber
8160
+ lunar
8161
+ lunch
8162
+ luxury
8163
+ lyrics
8164
+ machine
8165
+ mad
8166
+ magic
8167
+ magnet
8168
+ maid
8169
+ mail
8170
+ main
8171
+ major
8172
+ make
8173
+ mammal
8174
+ man
8175
+ manage
8176
+ mandate
8177
+ mango
8178
+ mansion
8179
+ manual
8180
+ maple
8181
+ marble
8182
+ march
8183
+ margin
8184
+ marine
8185
+ market
8186
+ marriage
8187
+ mask
8188
+ mass
8189
+ master
8190
+ match
8191
+ material
8192
+ math
8193
+ matrix
8194
+ matter
8195
+ maximum
8196
+ maze
8197
+ meadow
8198
+ mean
8199
+ measure
8200
+ meat
8201
+ mechanic
8202
+ medal
8203
+ media
8204
+ melody
8205
+ melt
8206
+ member
8207
+ memory
8208
+ mention
8209
+ menu
8210
+ mercy
8211
+ merge
8212
+ merit
8213
+ merry
8214
+ mesh
8215
+ message
8216
+ metal
8217
+ method
8218
+ middle
8219
+ midnight
8220
+ milk
8221
+ million
8222
+ mimic
8223
+ mind
8224
+ minimum
8225
+ minor
8226
+ minute
8227
+ miracle
8228
+ mirror
8229
+ misery
8230
+ miss
8231
+ mistake
8232
+ mix
8233
+ mixed
8234
+ mixture
8235
+ mobile
8236
+ model
8237
+ modify
8238
+ mom
8239
+ moment
8240
+ monitor
8241
+ monkey
8242
+ monster
8243
+ month
8244
+ moon
8245
+ moral
8246
+ more
8247
+ morning
8248
+ mosquito
8249
+ mother
8250
+ motion
8251
+ motor
8252
+ mountain
8253
+ mouse
8254
+ move
8255
+ movie
8256
+ much
8257
+ muffin
8258
+ mule
8259
+ multiply
8260
+ muscle
8261
+ museum
8262
+ mushroom
8263
+ music
8264
+ must
8265
+ mutual
8266
+ myself
8267
+ mystery
8268
+ myth
8269
+ naive
8270
+ name
8271
+ napkin
8272
+ narrow
8273
+ nasty
8274
+ nation
8275
+ nature
8276
+ near
8277
+ neck
8278
+ need
8279
+ negative
8280
+ neglect
8281
+ neither
8282
+ nephew
8283
+ nerve
8284
+ nest
8285
+ net
8286
+ network
8287
+ neutral
8288
+ never
8289
+ news
8290
+ next
8291
+ nice
8292
+ night
8293
+ noble
8294
+ noise
8295
+ nominee
8296
+ noodle
8297
+ normal
8298
+ north
8299
+ nose
8300
+ notable
8301
+ note
8302
+ nothing
8303
+ notice
8304
+ novel
8305
+ now
8306
+ nuclear
8307
+ number
8308
+ nurse
8309
+ nut
8310
+ oak
8311
+ obey
8312
+ object
8313
+ oblige
8314
+ obscure
8315
+ observe
8316
+ obtain
8317
+ obvious
8318
+ occur
8319
+ ocean
8320
+ october
8321
+ odor
8322
+ off
8323
+ offer
8324
+ office
8325
+ often
8326
+ oil
8327
+ okay
8328
+ old
8329
+ olive
8330
+ olympic
8331
+ omit
8332
+ once
8333
+ one
8334
+ onion
8335
+ online
8336
+ only
8337
+ open
8338
+ opera
8339
+ opinion
8340
+ oppose
8341
+ option
8342
+ orange
8343
+ orbit
8344
+ orchard
8345
+ order
8346
+ ordinary
8347
+ organ
8348
+ orient
8349
+ original
8350
+ orphan
8351
+ ostrich
8352
+ other
8353
+ outdoor
8354
+ outer
8355
+ output
8356
+ outside
8357
+ oval
8358
+ oven
8359
+ over
8360
+ own
8361
+ owner
8362
+ oxygen
8363
+ oyster
8364
+ ozone
8365
+ pact
8366
+ paddle
8367
+ page
8368
+ pair
8369
+ palace
8370
+ palm
8371
+ panda
8372
+ panel
8373
+ panic
8374
+ panther
8375
+ paper
8376
+ parade
8377
+ parent
8378
+ park
8379
+ parrot
8380
+ party
8381
+ pass
8382
+ patch
8383
+ path
8384
+ patient
8385
+ patrol
8386
+ pattern
8387
+ pause
8388
+ pave
8389
+ payment
8390
+ peace
8391
+ peanut
8392
+ pear
8393
+ peasant
8394
+ pelican
8395
+ pen
8396
+ penalty
8397
+ pencil
8398
+ people
8399
+ pepper
8400
+ perfect
8401
+ permit
8402
+ person
8403
+ pet
8404
+ phone
8405
+ photo
8406
+ phrase
8407
+ physical
8408
+ piano
8409
+ picnic
8410
+ picture
8411
+ piece
8412
+ pig
8413
+ pigeon
8414
+ pill
8415
+ pilot
8416
+ pink
8417
+ pioneer
8418
+ pipe
8419
+ pistol
8420
+ pitch
8421
+ pizza
8422
+ place
8423
+ planet
8424
+ plastic
8425
+ plate
8426
+ play
8427
+ please
8428
+ pledge
8429
+ pluck
8430
+ plug
8431
+ plunge
8432
+ poem
8433
+ poet
8434
+ point
8435
+ polar
8436
+ pole
8437
+ police
8438
+ pond
8439
+ pony
8440
+ pool
8441
+ popular
8442
+ portion
8443
+ position
8444
+ possible
8445
+ post
8446
+ potato
8447
+ pottery
8448
+ poverty
8449
+ powder
8450
+ power
8451
+ practice
8452
+ praise
8453
+ predict
8454
+ prefer
8455
+ prepare
8456
+ present
8457
+ pretty
8458
+ prevent
8459
+ price
8460
+ pride
8461
+ primary
8462
+ print
8463
+ priority
8464
+ prison
8465
+ private
8466
+ prize
8467
+ problem
8468
+ process
8469
+ produce
8470
+ profit
8471
+ program
8472
+ project
8473
+ promote
8474
+ proof
8475
+ property
8476
+ prosper
8477
+ protect
8478
+ proud
8479
+ provide
8480
+ public
8481
+ pudding
8482
+ pull
8483
+ pulp
8484
+ pulse
8485
+ pumpkin
8486
+ punch
8487
+ pupil
8488
+ puppy
8489
+ purchase
8490
+ purity
8491
+ purpose
8492
+ purse
8493
+ push
8494
+ put
8495
+ puzzle
8496
+ pyramid
8497
+ quality
8498
+ quantum
8499
+ quarter
8500
+ question
8501
+ quick
8502
+ quit
8503
+ quiz
8504
+ quote
8505
+ rabbit
8506
+ raccoon
8507
+ race
8508
+ rack
8509
+ radar
8510
+ radio
8511
+ rail
8512
+ rain
8513
+ raise
8514
+ rally
8515
+ ramp
8516
+ ranch
8517
+ random
8518
+ range
8519
+ rapid
8520
+ rare
8521
+ rate
8522
+ rather
8523
+ raven
8524
+ raw
8525
+ razor
8526
+ ready
8527
+ real
8528
+ reason
8529
+ rebel
8530
+ rebuild
8531
+ recall
8532
+ receive
8533
+ recipe
8534
+ record
8535
+ recycle
8536
+ reduce
8537
+ reflect
8538
+ reform
8539
+ refuse
8540
+ region
8541
+ regret
8542
+ regular
8543
+ reject
8544
+ relax
8545
+ release
8546
+ relief
8547
+ rely
8548
+ remain
8549
+ remember
8550
+ remind
8551
+ remove
8552
+ render
8553
+ renew
8554
+ rent
8555
+ reopen
8556
+ repair
8557
+ repeat
8558
+ replace
8559
+ report
8560
+ require
8561
+ rescue
8562
+ resemble
8563
+ resist
8564
+ resource
8565
+ response
8566
+ result
8567
+ retire
8568
+ retreat
8569
+ return
8570
+ reunion
8571
+ reveal
8572
+ review
8573
+ reward
8574
+ rhythm
8575
+ rib
8576
+ ribbon
8577
+ rice
8578
+ rich
8579
+ ride
8580
+ ridge
8581
+ rifle
8582
+ right
8583
+ rigid
8584
+ ring
8585
+ riot
8586
+ ripple
8587
+ risk
8588
+ ritual
8589
+ rival
8590
+ river
8591
+ road
8592
+ roast
8593
+ robot
8594
+ robust
8595
+ rocket
8596
+ romance
8597
+ roof
8598
+ rookie
8599
+ room
8600
+ rose
8601
+ rotate
8602
+ rough
8603
+ round
8604
+ route
8605
+ royal
8606
+ rubber
8607
+ rude
8608
+ rug
8609
+ rule
8610
+ run
8611
+ runway
8612
+ rural
8613
+ sad
8614
+ saddle
8615
+ sadness
8616
+ safe
8617
+ sail
8618
+ salad
8619
+ salmon
8620
+ salon
8621
+ salt
8622
+ salute
8623
+ same
8624
+ sample
8625
+ sand
8626
+ satisfy
8627
+ satoshi
8628
+ sauce
8629
+ sausage
8630
+ save
8631
+ say
8632
+ scale
8633
+ scan
8634
+ scare
8635
+ scatter
8636
+ scene
8637
+ scheme
8638
+ school
8639
+ science
8640
+ scissors
8641
+ scorpion
8642
+ scout
8643
+ scrap
8644
+ screen
8645
+ script
8646
+ scrub
8647
+ sea
8648
+ search
8649
+ season
8650
+ seat
8651
+ second
8652
+ secret
8653
+ section
8654
+ security
8655
+ seed
8656
+ seek
8657
+ segment
8658
+ select
8659
+ sell
8660
+ seminar
8661
+ senior
8662
+ sense
8663
+ sentence
8664
+ series
8665
+ service
8666
+ session
8667
+ settle
8668
+ setup
8669
+ seven
8670
+ shadow
8671
+ shaft
8672
+ shallow
8673
+ share
8674
+ shed
8675
+ shell
8676
+ sheriff
8677
+ shield
8678
+ shift
8679
+ shine
8680
+ ship
8681
+ shiver
8682
+ shock
8683
+ shoe
8684
+ shoot
8685
+ shop
8686
+ short
8687
+ shoulder
8688
+ shove
8689
+ shrimp
8690
+ shrug
8691
+ shuffle
8692
+ shy
8693
+ sibling
8694
+ sick
8695
+ side
8696
+ siege
8697
+ sight
8698
+ sign
8699
+ silent
8700
+ silk
8701
+ silly
8702
+ silver
8703
+ similar
8704
+ simple
8705
+ since
8706
+ sing
8707
+ siren
8708
+ sister
8709
+ situate
8710
+ six
8711
+ size
8712
+ skate
8713
+ sketch
8714
+ ski
8715
+ skill
8716
+ skin
8717
+ skirt
8718
+ skull
8719
+ slab
8720
+ slam
8721
+ sleep
8722
+ slender
8723
+ slice
8724
+ slide
8725
+ slight
8726
+ slim
8727
+ slogan
8728
+ slot
8729
+ slow
8730
+ slush
8731
+ small
8732
+ smart
8733
+ smile
8734
+ smoke
8735
+ smooth
8736
+ snack
8737
+ snake
8738
+ snap
8739
+ sniff
8740
+ snow
8741
+ soap
8742
+ soccer
8743
+ social
8744
+ sock
8745
+ soda
8746
+ soft
8747
+ solar
8748
+ soldier
8749
+ solid
8750
+ solution
8751
+ solve
8752
+ someone
8753
+ song
8754
+ soon
8755
+ sorry
8756
+ sort
8757
+ soul
8758
+ sound
8759
+ soup
8760
+ source
8761
+ south
8762
+ space
8763
+ spare
8764
+ spatial
8765
+ spawn
8766
+ speak
8767
+ special
8768
+ speed
8769
+ spell
8770
+ spend
8771
+ sphere
8772
+ spice
8773
+ spider
8774
+ spike
8775
+ spin
8776
+ spirit
8777
+ split
8778
+ spoil
8779
+ sponsor
8780
+ spoon
8781
+ sport
8782
+ spot
8783
+ spray
8784
+ spread
8785
+ spring
8786
+ spy
8787
+ square
8788
+ squeeze
8789
+ squirrel
8790
+ stable
8791
+ stadium
8792
+ staff
8793
+ stage
8794
+ stairs
8795
+ stamp
8796
+ stand
8797
+ start
8798
+ state
8799
+ stay
8800
+ steak
8801
+ steel
8802
+ stem
8803
+ step
8804
+ stereo
8805
+ stick
8806
+ still
8807
+ sting
8808
+ stock
8809
+ stomach
8810
+ stone
8811
+ stool
8812
+ story
8813
+ stove
8814
+ strategy
8815
+ street
8816
+ strike
8817
+ strong
8818
+ struggle
8819
+ student
8820
+ stuff
8821
+ stumble
8822
+ style
8823
+ subject
8824
+ submit
8825
+ subway
8826
+ success
8827
+ such
8828
+ sudden
8829
+ suffer
8830
+ sugar
8831
+ suggest
8832
+ suit
8833
+ summer
8834
+ sun
8835
+ sunny
8836
+ sunset
8837
+ super
8838
+ supply
8839
+ supreme
8840
+ sure
8841
+ surface
8842
+ surge
8843
+ surprise
8844
+ surround
8845
+ survey
8846
+ suspect
8847
+ sustain
8848
+ swallow
8849
+ swamp
8850
+ swap
8851
+ swarm
8852
+ swear
8853
+ sweet
8854
+ swift
8855
+ swim
8856
+ swing
8857
+ switch
8858
+ sword
8859
+ symbol
8860
+ symptom
8861
+ syrup
8862
+ system
8863
+ table
8864
+ tackle
8865
+ tag
8866
+ tail
8867
+ talent
8868
+ talk
8869
+ tank
8870
+ tape
8871
+ target
8872
+ task
8873
+ taste
8874
+ tattoo
8875
+ taxi
8876
+ teach
8877
+ team
8878
+ tell
8879
+ ten
8880
+ tenant
8881
+ tennis
8882
+ tent
8883
+ term
8884
+ test
8885
+ text
8886
+ thank
8887
+ that
8888
+ theme
8889
+ then
8890
+ theory
8891
+ there
8892
+ they
8893
+ thing
8894
+ this
8895
+ thought
8896
+ three
8897
+ thrive
8898
+ throw
8899
+ thumb
8900
+ thunder
8901
+ ticket
8902
+ tide
8903
+ tiger
8904
+ tilt
8905
+ timber
8906
+ time
8907
+ tiny
8908
+ tip
8909
+ tired
8910
+ tissue
8911
+ title
8912
+ toast
8913
+ tobacco
8914
+ today
8915
+ toddler
8916
+ toe
8917
+ together
8918
+ toilet
8919
+ token
8920
+ tomato
8921
+ tomorrow
8922
+ tone
8923
+ tongue
8924
+ tonight
8925
+ tool
8926
+ tooth
8927
+ top
8928
+ topic
8929
+ topple
8930
+ torch
8931
+ tornado
8932
+ tortoise
8933
+ toss
8934
+ total
8935
+ tourist
8936
+ toward
8937
+ tower
8938
+ town
8939
+ toy
8940
+ track
8941
+ trade
8942
+ traffic
8943
+ tragic
8944
+ train
8945
+ transfer
8946
+ trap
8947
+ trash
8948
+ travel
8949
+ tray
8950
+ treat
8951
+ tree
8952
+ trend
8953
+ trial
8954
+ tribe
8955
+ trick
8956
+ trigger
8957
+ trim
8958
+ trip
8959
+ trophy
8960
+ trouble
8961
+ truck
8962
+ true
8963
+ truly
8964
+ trumpet
8965
+ trust
8966
+ truth
8967
+ try
8968
+ tube
8969
+ tuition
8970
+ tumble
8971
+ tuna
8972
+ tunnel
8973
+ turkey
8974
+ turn
8975
+ turtle
8976
+ twelve
8977
+ twenty
8978
+ twice
8979
+ twin
8980
+ twist
8981
+ two
8982
+ type
8983
+ typical
8984
+ ugly
8985
+ umbrella
8986
+ unable
8987
+ unaware
8988
+ uncle
8989
+ uncover
8990
+ under
8991
+ undo
8992
+ unfair
8993
+ unfold
8994
+ unhappy
8995
+ uniform
8996
+ unique
8997
+ unit
8998
+ universe
8999
+ unknown
9000
+ unlock
9001
+ until
9002
+ unusual
9003
+ unveil
9004
+ update
9005
+ upgrade
9006
+ uphold
9007
+ upon
9008
+ upper
9009
+ upset
9010
+ urban
9011
+ urge
9012
+ usage
9013
+ use
9014
+ used
9015
+ useful
9016
+ useless
9017
+ usual
9018
+ utility
9019
+ vacant
9020
+ vacuum
9021
+ vague
9022
+ valid
9023
+ valley
9024
+ valve
9025
+ van
9026
+ vanish
9027
+ vapor
9028
+ various
9029
+ vast
9030
+ vault
9031
+ vehicle
9032
+ velvet
9033
+ vendor
9034
+ venture
9035
+ venue
9036
+ verb
9037
+ verify
9038
+ version
9039
+ very
9040
+ vessel
9041
+ veteran
9042
+ viable
9043
+ vibrant
9044
+ vicious
9045
+ victory
9046
+ video
9047
+ view
9048
+ village
9049
+ vintage
9050
+ violin
9051
+ virtual
9052
+ virus
9053
+ visa
9054
+ visit
9055
+ visual
9056
+ vital
9057
+ vivid
9058
+ vocal
9059
+ voice
9060
+ void
9061
+ volcano
9062
+ volume
9063
+ vote
9064
+ voyage
9065
+ wage
9066
+ wagon
9067
+ wait
9068
+ walk
9069
+ wall
9070
+ walnut
9071
+ want
9072
+ warfare
9073
+ warm
9074
+ warrior
9075
+ wash
9076
+ wasp
9077
+ waste
9078
+ water
9079
+ wave
9080
+ way
9081
+ wealth
9082
+ weapon
9083
+ wear
9084
+ weasel
9085
+ weather
9086
+ web
9087
+ wedding
9088
+ weekend
9089
+ weird
9090
+ welcome
9091
+ west
9092
+ wet
9093
+ whale
9094
+ what
9095
+ wheat
9096
+ wheel
9097
+ when
9098
+ where
9099
+ whip
9100
+ whisper
9101
+ wide
9102
+ width
9103
+ wife
9104
+ wild
9105
+ will
9106
+ win
9107
+ window
9108
+ wine
9109
+ wing
9110
+ wink
9111
+ winner
9112
+ winter
9113
+ wire
9114
+ wisdom
9115
+ wise
9116
+ wish
9117
+ witness
9118
+ wolf
9119
+ woman
9120
+ wonder
9121
+ wood
9122
+ wool
9123
+ word
9124
+ work
9125
+ world
9126
+ worry
9127
+ worth
9128
+ wrap
9129
+ wreck
9130
+ wrestle
9131
+ wrist
9132
+ write
9133
+ wrong
9134
+ yard
9135
+ year
9136
+ yellow
9137
+ you
9138
+ young
9139
+ youth
9140
+ zebra
9141
+ zero
9142
+ zone
9143
+ zoo`.split("\n");
9144
+
9145
+ //#endregion
9146
+ //#region packages/provider/src/MnemonicKeyDerivation.ts
9147
+ /**
9148
+ * MnemonicKeyDerivation
9149
+ *
9150
+ * Pure, stateless functions for BIP-39 mnemonic-based Ed25519 identity
9151
+ * derivation and AES-256-GCM seed wrapping. No IndexedDB, no WebAuthn,
9152
+ * no DOM access — fully unit-testable.
9153
+ *
9154
+ * Derivation chain:
9155
+ * BIP-39 Mnemonic (+optional passphrase)
9156
+ * → PBKDF2-HMAC-SHA512 (2048 rounds, per BIP-39 spec)
9157
+ * → first 32 bytes as IKM
9158
+ * → HKDF-SHA256(salt="abracadabra-mnemonic-v1", info="abracadabra-identity-v1")
9159
+ * → Ed25519 seed (32 bytes)
9160
+ * → Ed25519 keypair + X25519 (Montgomery conversion)
9161
+ *
9162
+ * The HKDF salt differs from the passkey PRF path (which uses PRF_SALT),
9163
+ * providing domain separation: identical raw input bytes can never produce
9164
+ * the same Ed25519 seed across the two derivation methods.
9165
+ *
9166
+ * Dependencies: @scure/bip39, @noble/ed25519, @noble/hashes, @noble/curves
9167
+ */
9168
+ /** HKDF salt for mnemonic → Ed25519 seed derivation. */
9169
+ const MNEMONIC_HKDF_SALT = /* @__PURE__ */ new TextEncoder().encode("abracadabra-mnemonic-v1");
9170
+ /** HKDF info string — intentionally matches the passkey path's HKDF_INFO. */
9171
+ const MNEMONIC_HKDF_INFO = /* @__PURE__ */ new TextEncoder().encode("abracadabra-identity-v1");
9172
+ /** HKDF info string for deriving the AES-GCM seed-wrapping key from PRF output. */
9173
+ const SEED_WRAP_INFO = /* @__PURE__ */ new TextEncoder().encode("abracadabra-seed-wrap-v1");
9174
+ function toBase64url$1(bytes) {
9175
+ return btoa(String.fromCharCode(...bytes)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
9176
+ }
9177
+ /**
9178
+ * Generate a new BIP-39 mnemonic phrase.
9179
+ * @param strength 128 for 12 words (default), 256 for 24 words.
9180
+ */
9181
+ function generateMnemonic(strength = 128) {
9182
+ return generateMnemonic$1(wordlist, strength);
9183
+ }
9184
+ /**
9185
+ * Validate a BIP-39 mnemonic (wordlist + checksum).
9186
+ */
9187
+ function validateMnemonic(mnemonic) {
9188
+ return validateMnemonic$1(mnemonic, wordlist);
9189
+ }
9190
+ /**
9191
+ * Derive a 32-byte Ed25519 seed from a BIP-39 mnemonic.
9192
+ *
9193
+ * Chain: mnemonic → PBKDF2-HMAC-SHA512 (2048 rounds) → first 32 bytes →
9194
+ * HKDF-SHA256(salt, info) → 32-byte seed.
9195
+ *
9196
+ * @param mnemonic Valid BIP-39 mnemonic (12 or 24 words).
9197
+ * @param passphrase Optional BIP-39 passphrase ("25th word").
9198
+ * @returns 32-byte Ed25519 seed. Caller MUST wipe after use: `seed.fill(0)`.
9199
+ */
9200
+ function mnemonicToEd25519Seed(mnemonic, passphrase) {
9201
+ const bip39Seed = mnemonicToSeedSync(mnemonic, passphrase ?? "");
9202
+ const seed = hkdf(sha256, bip39Seed.subarray(0, 32), MNEMONIC_HKDF_SALT, MNEMONIC_HKDF_INFO, 32);
9203
+ bip39Seed.fill(0);
9204
+ return seed;
9205
+ }
9206
+ /**
9207
+ * Derive the full Ed25519 + X25519 keypair from a BIP-39 mnemonic.
9208
+ *
9209
+ * @param mnemonic Valid BIP-39 mnemonic.
9210
+ * @param passphrase Optional BIP-39 passphrase.
9211
+ * @returns Keys and seed. Caller MUST wipe `seed` after use.
9212
+ */
9213
+ async function mnemonicToKeyPair(mnemonic, passphrase) {
9214
+ const seed = mnemonicToEd25519Seed(mnemonic, passphrase);
9215
+ const publicKey = await ed.getPublicKeyAsync(seed);
9216
+ const publicKeyB64 = toBase64url$1(publicKey);
9217
+ const x25519PublicKey = ed25519.utils.toMontgomery(publicKey);
9218
+ return {
9219
+ seed,
9220
+ publicKey,
9221
+ publicKeyB64,
9222
+ x25519PublicKey,
9223
+ x25519PublicKeyB64: toBase64url$1(x25519PublicKey)
9224
+ };
9225
+ }
9226
+ /**
9227
+ * Derive a 32-byte AES-256-GCM key from WebAuthn PRF output for seed wrapping.
9228
+ *
9229
+ * @param prfOutput Raw PRF output from WebAuthn assertion (32 bytes typical).
9230
+ * @param wrapSalt Random 32-byte salt, stored alongside the ciphertext.
9231
+ */
9232
+ function deriveSeedWrappingKey(prfOutput, wrapSalt) {
9233
+ return hkdf(sha256, new Uint8Array(prfOutput), wrapSalt, SEED_WRAP_INFO, 32);
9234
+ }
9235
+ /**
9236
+ * Encrypt an Ed25519 seed with AES-256-GCM.
9237
+ *
9238
+ * @param seed 32-byte Ed25519 seed to protect.
9239
+ * @param wrappingKeyBytes 32-byte AES key from `deriveSeedWrappingKey`.
9240
+ * @returns Ciphertext (48 bytes: 32 plaintext + 16 auth tag) and 12-byte IV.
9241
+ */
9242
+ async function wrapSeed(seed, wrappingKeyBytes) {
9243
+ const iv = crypto.getRandomValues(new Uint8Array(12));
9244
+ const key = await crypto.subtle.importKey("raw", wrappingKeyBytes, "AES-GCM", false, ["encrypt"]);
9245
+ return {
9246
+ ciphertext: await crypto.subtle.encrypt({
9247
+ name: "AES-GCM",
9248
+ iv
9249
+ }, key, seed),
9250
+ iv
9251
+ };
9252
+ }
9253
+ /**
9254
+ * Decrypt an Ed25519 seed from AES-256-GCM ciphertext.
9255
+ *
9256
+ * @param ciphertext Encrypted seed (48 bytes).
9257
+ * @param iv 12-byte GCM nonce.
9258
+ * @param wrappingKeyBytes 32-byte AES key from `deriveSeedWrappingKey`.
9259
+ * @returns 32-byte Ed25519 seed. Caller MUST wipe after use.
9260
+ * @throws If the auth tag is invalid (wrong key or tampered data).
9261
+ */
9262
+ async function unwrapSeed(ciphertext, iv, wrappingKeyBytes) {
9263
+ const key = await crypto.subtle.importKey("raw", wrappingKeyBytes, "AES-GCM", false, ["decrypt"]);
9264
+ const plaintext = await crypto.subtle.decrypt({
9265
+ name: "AES-GCM",
9266
+ iv
9267
+ }, key, ciphertext);
9268
+ return new Uint8Array(plaintext);
9269
+ }
9270
+
7069
9271
  //#endregion
7070
9272
  //#region packages/provider/src/CryptoIdentityKeystore.ts
7071
9273
  /**
7072
9274
  * CryptoIdentityKeystore
7073
9275
  *
7074
- * Per-user Ed25519 keypair derived deterministically from a synced WebAuthn
7075
- * passkey's PRF extension output. The same passkey on any device produces the
7076
- * same identity — no private key storage needed.
9276
+ * Ed25519 identity management with two derivation modes:
7077
9277
  *
7078
- * Derivation chain:
7079
- * Synced Passkey PRF(constant salt) → HKDF-SHA256 → Ed25519 seed → keypair
9278
+ * 1. **Passkey-only (legacy)**: PRF output → HKDF → Ed25519 seed.
9279
+ * The passkey IS the identity source.
9280
+ *
9281
+ * 2. **Mnemonic-rooted**: BIP-39 mnemonic → Ed25519 seed, encrypted by
9282
+ * passkey PRF for day-to-day convenience. The mnemonic IS the identity
9283
+ * source; the passkey is a convenience wrapper. Recovery via mnemonic
9284
+ * re-derives the exact same key.
7080
9285
  *
7081
- * IndexedDB is used only as a lightweight cache for the public key and
7082
- * credential ID. Loss of IndexedDB is non-catastrophic — a passkey assertion
7083
- * re-derives everything.
9286
+ * Both modes coexist. IndexedDB records with `encryptedSeed` use mode 2;
9287
+ * records without it use mode 1 (backward compatible).
7084
9288
  *
7085
- * Dependencies: @noble/ed25519, @noble/hashes (for HKDF), @noble/curves (for X25519)
9289
+ * Dependencies: @noble/ed25519, @noble/hashes, @noble/curves, @scure/bip39
7086
9290
  */
7087
9291
  /**
7088
9292
  * Fixed PRF eval salt. Must be constant across all devices so the same synced
@@ -7138,7 +9342,7 @@ const DB_NAME = "abracadabra:identity";
7138
9342
  const STORE_NAME = "identity";
7139
9343
  function openDb$4() {
7140
9344
  return new Promise((resolve, reject) => {
7141
- const req = indexedDB.open(DB_NAME, 2);
9345
+ const req = indexedDB.open(DB_NAME, 3);
7142
9346
  req.onupgradeneeded = () => {
7143
9347
  const db = req.result;
7144
9348
  if (!db.objectStoreNames.contains(STORE_NAME)) db.createObjectStore(STORE_NAME);
@@ -7410,6 +9614,169 @@ var CryptoIdentityKeystore = class {
7410
9614
  }
7411
9615
  }
7412
9616
  /**
9617
+ * Register a new identity rooted in a BIP-39 mnemonic. Optionally wraps the
9618
+ * derived seed with a passkey for biometric day-to-day access.
9619
+ *
9620
+ * @param username - Display name for the identity.
9621
+ * @param mnemonic - Valid BIP-39 mnemonic (12 or 24 words).
9622
+ * @param passphrase - Optional BIP-39 passphrase ("25th word").
9623
+ * @param rpId - WebAuthn relying party ID (omit to skip passkey wrapping).
9624
+ * @param rpName - WebAuthn relying party display name.
9625
+ * @returns Public keys and optional credential ID.
9626
+ */
9627
+ async registerWithMnemonic(username, mnemonic, passphrase, rpId, rpName) {
9628
+ const kp = await mnemonicToKeyPair(mnemonic, passphrase);
9629
+ try {
9630
+ if (rpId && rpName) {
9631
+ const credential = await navigator.credentials.create({ publicKey: {
9632
+ challenge: crypto.getRandomValues(new Uint8Array(32)),
9633
+ rp: {
9634
+ id: rpId,
9635
+ name: rpName
9636
+ },
9637
+ user: {
9638
+ id: new TextEncoder().encode(username),
9639
+ name: username,
9640
+ displayName: username
9641
+ },
9642
+ pubKeyCredParams: [{
9643
+ alg: -7,
9644
+ type: "public-key"
9645
+ }, {
9646
+ alg: -257,
9647
+ type: "public-key"
9648
+ }],
9649
+ authenticatorSelection: {
9650
+ residentKey: "required",
9651
+ requireResidentKey: true,
9652
+ userVerification: "required"
9653
+ },
9654
+ extensions: { prf: { eval: { first: PRF_SALT.buffer } } }
9655
+ } });
9656
+ if (!credential) throw new Error("WebAuthn credential creation cancelled");
9657
+ const prfOutput = extractPrfOutput(credential);
9658
+ const wrapSalt = crypto.getRandomValues(new Uint8Array(32));
9659
+ const wrapKey = deriveSeedWrappingKey(prfOutput, wrapSalt);
9660
+ const { ciphertext, iv } = await wrapSeed(kp.seed, wrapKey);
9661
+ wrapKey.fill(0);
9662
+ const credentialIdB64 = toBase64url(new Uint8Array(credential.rawId));
9663
+ const db = await openDb$4();
9664
+ await dbPut(db, credentialIdB64, {
9665
+ username,
9666
+ publicKey: kp.publicKeyB64,
9667
+ credentialId: credential.rawId,
9668
+ encryptedSeed: ciphertext,
9669
+ seedIv: iv,
9670
+ wrapSalt,
9671
+ authMethod: "mnemonic"
9672
+ });
9673
+ db.close();
9674
+ return {
9675
+ publicKey: kp.publicKeyB64,
9676
+ x25519PublicKey: kp.x25519PublicKeyB64,
9677
+ credentialId: credentialIdB64
9678
+ };
9679
+ }
9680
+ return {
9681
+ publicKey: kp.publicKeyB64,
9682
+ x25519PublicKey: kp.x25519PublicKeyB64
9683
+ };
9684
+ } finally {
9685
+ kp.seed.fill(0);
9686
+ }
9687
+ }
9688
+ /**
9689
+ * Wrap an existing mnemonic-derived seed with a new passkey. Use this when
9690
+ * a user logged in via mnemonic and wants to add biometric convenience.
9691
+ *
9692
+ * @param mnemonic - The user's BIP-39 mnemonic.
9693
+ * @param passphrase - Optional BIP-39 passphrase.
9694
+ * @param rpId - WebAuthn relying party ID.
9695
+ * @param rpName - WebAuthn relying party display name.
9696
+ * @returns The new credential ID.
9697
+ */
9698
+ async wrapSeedWithPasskey(mnemonic, passphrase, rpId, rpName) {
9699
+ const kp = await mnemonicToKeyPair(mnemonic, passphrase);
9700
+ try {
9701
+ const credential = await navigator.credentials.create({ publicKey: {
9702
+ challenge: crypto.getRandomValues(new Uint8Array(32)),
9703
+ rp: {
9704
+ id: rpId,
9705
+ name: rpName
9706
+ },
9707
+ user: {
9708
+ id: fromBase64url(kp.publicKeyB64),
9709
+ name: kp.publicKeyB64.slice(0, 16),
9710
+ displayName: kp.publicKeyB64.slice(0, 16)
9711
+ },
9712
+ pubKeyCredParams: [{
9713
+ alg: -7,
9714
+ type: "public-key"
9715
+ }, {
9716
+ alg: -257,
9717
+ type: "public-key"
9718
+ }],
9719
+ authenticatorSelection: {
9720
+ residentKey: "required",
9721
+ requireResidentKey: true,
9722
+ userVerification: "required"
9723
+ },
9724
+ extensions: { prf: { eval: { first: PRF_SALT.buffer } } }
9725
+ } });
9726
+ if (!credential) throw new Error("WebAuthn credential creation cancelled");
9727
+ const prfOutput = extractPrfOutput(credential);
9728
+ const wrapSalt = crypto.getRandomValues(new Uint8Array(32));
9729
+ const wrapKey = deriveSeedWrappingKey(prfOutput, wrapSalt);
9730
+ const { ciphertext, iv } = await wrapSeed(kp.seed, wrapKey);
9731
+ wrapKey.fill(0);
9732
+ const credentialIdB64 = toBase64url(new Uint8Array(credential.rawId));
9733
+ let username = "";
9734
+ try {
9735
+ const db = await openDb$4();
9736
+ const existing = (await dbGetAll(db)).find((e) => e.value.publicKey === kp.publicKeyB64);
9737
+ if (existing) username = existing.value.username;
9738
+ db.close();
9739
+ } catch {}
9740
+ const db = await openDb$4();
9741
+ await dbPut(db, credentialIdB64, {
9742
+ username,
9743
+ publicKey: kp.publicKeyB64,
9744
+ credentialId: credential.rawId,
9745
+ encryptedSeed: ciphertext,
9746
+ seedIv: iv,
9747
+ wrapSalt,
9748
+ authMethod: "mnemonic"
9749
+ });
9750
+ db.close();
9751
+ return { credentialId: credentialIdB64 };
9752
+ } finally {
9753
+ kp.seed.fill(0);
9754
+ }
9755
+ }
9756
+ /**
9757
+ * Sign a challenge directly with a provided seed. No WebAuthn prompt.
9758
+ * For ephemeral mnemonic sessions where the seed is held in memory.
9759
+ *
9760
+ * The caller manages the seed lifecycle (wiping on session end).
9761
+ */
9762
+ static async signWithSeed(challengeB64, seed) {
9763
+ const challengeBytes = fromBase64url(challengeB64);
9764
+ return toBase64url(await ed.signAsync(challengeBytes, seed));
9765
+ }
9766
+ /**
9767
+ * Stateless mnemonic sign: derive seed, sign, wipe. No IndexedDB, no WebAuthn.
9768
+ * Useful for CLI or one-shot operations.
9769
+ */
9770
+ static async signWithMnemonic(mnemonic, challengeB64, passphrase) {
9771
+ const seed = mnemonicToEd25519Seed(mnemonic, passphrase);
9772
+ try {
9773
+ const challengeBytes = fromBase64url(challengeB64);
9774
+ return toBase64url(await ed.signAsync(challengeBytes, seed));
9775
+ } finally {
9776
+ seed.fill(0);
9777
+ }
9778
+ }
9779
+ /**
7413
9780
  * Perform a WebAuthn assertion with PRF, derive the Ed25519 seed, and
7414
9781
  * update the IndexedDB cache. Returns the seed (caller MUST wipe it).
7415
9782
  */
@@ -7435,15 +9802,32 @@ var CryptoIdentityKeystore = class {
7435
9802
  extensions: { prf: { eval: { first: PRF_SALT.buffer } } }
7436
9803
  } });
7437
9804
  if (!assertion) throw new Error("WebAuthn assertion cancelled");
7438
- const seed = deriveEd25519Seed(extractPrfOutput(assertion));
7439
- const publicKeyB64 = toBase64url(await ed.getPublicKeyAsync(seed));
9805
+ const prfOutput = extractPrfOutput(assertion);
7440
9806
  const credentialIdB64 = toBase64url(new Uint8Array(assertion.rawId));
9807
+ let stored;
7441
9808
  try {
7442
9809
  const db = await openDb$4();
9810
+ stored = await dbGet(db, credentialIdB64);
9811
+ db.close();
9812
+ } catch {}
9813
+ let seed;
9814
+ if (stored?.encryptedSeed && stored.seedIv && stored.wrapSalt) {
9815
+ const wrapKey = deriveSeedWrappingKey(prfOutput, stored.wrapSalt);
9816
+ seed = await unwrapSeed(stored.encryptedSeed, stored.seedIv, wrapKey);
9817
+ wrapKey.fill(0);
9818
+ } else seed = deriveEd25519Seed(prfOutput);
9819
+ const publicKeyB64 = toBase64url(await ed.getPublicKeyAsync(seed));
9820
+ try {
9821
+ const db = await openDb$4();
9822
+ const existing = await dbGet(db, credentialIdB64);
7443
9823
  await dbPut(db, credentialIdB64, {
7444
- username: (await dbGet(db, credentialIdB64))?.username ?? "",
9824
+ username: existing?.username ?? "",
7445
9825
  publicKey: publicKeyB64,
7446
- credentialId: assertion.rawId
9826
+ credentialId: assertion.rawId,
9827
+ encryptedSeed: existing?.encryptedSeed,
9828
+ seedIv: existing?.seedIv,
9829
+ wrapSalt: existing?.wrapSalt,
9830
+ authMethod: existing?.authMethod
7447
9831
  });
7448
9832
  db.close();
7449
9833
  } catch {}
@@ -10098,6 +12482,8 @@ var AbracadabraWebRTC = class AbracadabraWebRTC extends EventEmitter {
10098
12482
  this.signaling.destroy();
10099
12483
  this.signaling = null;
10100
12484
  }
12485
+ this._resolvedE2ee = null;
12486
+ this._resolveE2eePromise = null;
10101
12487
  this.removeAllListeners();
10102
12488
  }
10103
12489
  setMuted(muted) {
@@ -10239,28 +12625,54 @@ var AbracadabraWebRTC = class AbracadabraWebRTC extends EventEmitter {
10239
12625
  return this._resolvedE2ee;
10240
12626
  }
10241
12627
  attachDataHandlers(peerId, pc) {
10242
- if (this.config.e2ee) this.resolveE2ee().then((identity) => {
12628
+ if (!this.config.e2ee) {
12629
+ this.startDataSync(peerId, pc);
12630
+ return;
12631
+ }
12632
+ let e2ee = null;
12633
+ const pendingMessages = [];
12634
+ let pendingKeyExchangeChannel = null;
12635
+ pc.router.on("channelMessage", async ({ name, data }) => {
12636
+ if (name !== KEY_EXCHANGE_CHANNEL) return;
12637
+ const buf = data instanceof ArrayBuffer ? new Uint8Array(data) : data;
12638
+ if (!e2ee) {
12639
+ pendingMessages.push(buf);
12640
+ return;
12641
+ }
12642
+ try {
12643
+ await e2ee.handleKeyExchange(buf);
12644
+ } catch (err) {
12645
+ this.emit("e2eeFailed", {
12646
+ peerId,
12647
+ error: err
12648
+ });
12649
+ }
12650
+ });
12651
+ pc.router.on("channelOpen", ({ name, channel }) => {
12652
+ if (name !== KEY_EXCHANGE_CHANNEL) return;
12653
+ if (!e2ee) {
12654
+ pendingKeyExchangeChannel = channel;
12655
+ return;
12656
+ }
12657
+ channel.send(e2ee.getKeyExchangeMessage());
12658
+ });
12659
+ this.resolveE2ee().then(async (identity) => {
10243
12660
  if (!identity) {
10244
12661
  this.startDataSync(peerId, pc);
10245
12662
  return;
10246
12663
  }
10247
- const e2ee = new E2EEChannel(identity, this.config.docId);
12664
+ e2ee = new E2EEChannel(identity, this.config.docId);
10248
12665
  this.e2eeChannels.set(peerId, e2ee);
10249
12666
  pc.router.setEncryptor(e2ee);
10250
- pc.router.on("channelMessage", async ({ name, data }) => {
10251
- if (name === KEY_EXCHANGE_CHANNEL) try {
10252
- const buf = data instanceof ArrayBuffer ? new Uint8Array(data) : data;
10253
- await e2ee.handleKeyExchange(buf);
10254
- } catch (err) {
10255
- this.emit("e2eeFailed", {
10256
- peerId,
10257
- error: err
10258
- });
10259
- }
10260
- });
10261
- pc.router.on("channelOpen", ({ name, channel }) => {
10262
- if (name === KEY_EXCHANGE_CHANNEL) channel.send(e2ee.getKeyExchangeMessage());
10263
- });
12667
+ if (pendingKeyExchangeChannel) pendingKeyExchangeChannel.send(e2ee.getKeyExchangeMessage());
12668
+ for (const msg of pendingMessages) try {
12669
+ await e2ee.handleKeyExchange(msg);
12670
+ } catch (err) {
12671
+ this.emit("e2eeFailed", {
12672
+ peerId,
12673
+ error: err
12674
+ });
12675
+ }
10264
12676
  e2ee.on("established", () => {
10265
12677
  this.emit("e2eeEstablished", { peerId });
10266
12678
  this.startDataSync(peerId, pc);
@@ -10278,7 +12690,6 @@ var AbracadabraWebRTC = class AbracadabraWebRTC extends EventEmitter {
10278
12690
  });
10279
12691
  this.startDataSync(peerId, pc);
10280
12692
  });
10281
- else this.startDataSync(peerId, pc);
10282
12693
  }
10283
12694
  startDataSync(peerId, pc) {
10284
12695
  if (this.config.document && this.config.enableDocSync) {
@@ -11561,5 +13972,5 @@ var DeviceRegistrationService = class {
11561
13972
  };
11562
13973
 
11563
13974
  //#endregion
11564
- export { AbracadabraBaseProvider, AbracadabraClient, AbracadabraProvider, AbracadabraWS, AbracadabraWebRTC, AuthMessageType, AwarenessError, BackgroundSyncManager, BackgroundSyncPersistence, BroadcastChannelSync, CHANNEL_NAMES, ConnectionTimeout, CryptoIdentityKeystore, DEFAULT_FILE_CHUNK_SIZE, DEFAULT_ICE_SERVERS, DataChannelRouter, DevicePairingChannel, DeviceRegistrationService, DocKeyManager, DocumentCache, E2EAbracadabraProvider, E2EEChannel, E2EOfflineStore, EncryptedYMap, EncryptedYText, FileBlobStore, FileTransferChannel, FileTransferHandle, Forbidden, HocuspocusProvider, HocuspocusProviderWebsocket, IdentityDocProvider, KEY_EXCHANGE_CHANNEL, ManualSignaling, MessageTooBig, MessageType, OfflineStore, PeerConnection, ResetConnection, SearchIndex, SignalingSocket, SubdocMessage, Unauthorized, WebSocketStatus, WsReadyStates, YjsDataChannel, attachUpdatedAtObserver, awarenessStatesToArray, decryptField, deriveIdentityDocId, encryptField, makeEncryptedYMap, makeEncryptedYText, readAuthMessage, writeAuthenticated, writeAuthentication, writePermissionDenied, writeTokenSyncRequest };
13975
+ export { AbracadabraBaseProvider, AbracadabraClient, AbracadabraProvider, AbracadabraWS, AbracadabraWebRTC, AuthMessageType, AwarenessError, BackgroundSyncManager, BackgroundSyncPersistence, BroadcastChannelSync, CHANNEL_NAMES, ConnectionTimeout, CryptoIdentityKeystore, DEFAULT_FILE_CHUNK_SIZE, DEFAULT_ICE_SERVERS, DataChannelRouter, DevicePairingChannel, DeviceRegistrationService, DocKeyManager, DocumentCache, E2EAbracadabraProvider, E2EEChannel, E2EOfflineStore, EncryptedYMap, EncryptedYText, FileBlobStore, FileTransferChannel, FileTransferHandle, Forbidden, HocuspocusProvider, HocuspocusProviderWebsocket, IdentityDocProvider, KEY_EXCHANGE_CHANNEL, ManualSignaling, MessageTooBig, MessageType, OfflineStore, PeerConnection, ResetConnection, SearchIndex, SignalingSocket, SubdocMessage, Unauthorized, WebSocketStatus, WsReadyStates, YjsDataChannel, attachUpdatedAtObserver, awarenessStatesToArray, wordlist as bip39Wordlist, decryptField, deriveIdentityDocId, deriveSeedWrappingKey, encryptField, generateMnemonic, makeEncryptedYMap, makeEncryptedYText, mnemonicToEd25519Seed, mnemonicToKeyPair, readAuthMessage, unwrapSeed, validateMnemonic, wrapSeed, writeAuthenticated, writeAuthentication, writePermissionDenied, writeTokenSyncRequest };
11565
13976
  //# sourceMappingURL=abracadabra-provider.esm.js.map