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