From 8346eb9e052d10abf4fb65b66838aaab47152e2a Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Fri, 30 Aug 2024 18:52:00 -0700 Subject: typescript --- src/lib/english.js | 2048 ---------------------------------------------------- src/lib/english.ts | 2048 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/handler.js | 14 - src/lib/handler.ts | 14 + src/lib/invoice.js | 32 - src/lib/invoice.ts | 32 + src/lib/parse.js | 87 --- src/lib/parse.ts | 87 +++ src/lib/punks.js | 66 -- src/lib/punks.ts | 66 ++ src/lib/samples.js | 89 --- src/lib/samples.ts | 89 +++ src/lib/socket.js | 92 --- src/lib/socket.ts | 92 +++ src/lib/store.js | 59 -- src/lib/store.ts | 59 ++ src/lib/ticket.js | 31 - src/lib/ticket.ts | 31 + src/lib/tickets.js | 52 -- src/lib/tickets.ts | 52 ++ src/lib/upload.js | 18 - src/lib/upload.ts | 18 + src/lib/utils.js | 339 --------- src/lib/utils.ts | 339 +++++++++ 24 files changed, 2927 insertions(+), 2927 deletions(-) delete mode 100644 src/lib/english.js create mode 100644 src/lib/english.ts delete mode 100644 src/lib/handler.js create mode 100644 src/lib/handler.ts delete mode 100644 src/lib/invoice.js create mode 100644 src/lib/invoice.ts delete mode 100644 src/lib/parse.js create mode 100644 src/lib/parse.ts delete mode 100644 src/lib/punks.js create mode 100644 src/lib/punks.ts delete mode 100644 src/lib/samples.js create mode 100644 src/lib/samples.ts delete mode 100644 src/lib/socket.js create mode 100644 src/lib/socket.ts delete mode 100644 src/lib/store.js create mode 100644 src/lib/store.ts delete mode 100644 src/lib/ticket.js create mode 100644 src/lib/ticket.ts delete mode 100644 src/lib/tickets.js create mode 100644 src/lib/tickets.ts delete mode 100644 src/lib/upload.js create mode 100644 src/lib/upload.ts delete mode 100644 src/lib/utils.js create mode 100644 src/lib/utils.ts (limited to 'src/lib') diff --git a/src/lib/english.js b/src/lib/english.js deleted file mode 100644 index 52a0da82..00000000 --- a/src/lib/english.js +++ /dev/null @@ -1,2048 +0,0 @@ -export default `abandon -ability -able -about -above -absent -absorb -abstract -absurd -abuse -access -accident -account -accuse -achieve -acid -acoustic -acquire -across -act -action -actor -actress -actual -adapt -add -addict -address -adjust -admit -adult -advance -advice -aerobic -affair -afford -afraid -again -age -agent -agree -ahead -aim -air -airport -aisle -alarm -album -alcohol -alert -alien -all -alley -allow -almost -alone -alpha -already -also -alter -always -amateur -amazing -among -amount -amused -analyst -anchor -ancient -anger -angle -angry -animal -ankle -announce -annual -another -answer -antenna -antique -anxiety -any -apart -apology -appear -apple -approve -april -arch -arctic -area -arena -argue -arm -armed -armor -army -around -arrange -arrest -arrive -arrow -art -artefact -artist -artwork -ask -aspect -assault -asset -assist -assume -asthma -athlete -atom -attack -attend -attitude -attract -auction -audit -august -aunt -author -auto -autumn -average -avocado -avoid -awake -aware -away -awesome -awful -awkward -axis -baby -bachelor -bacon -badge -bag -balance -balcony -ball -bamboo -banana -banner -bar -barely -bargain -barrel -base -basic -basket -battle -beach -bean -beauty -because -become -beef -before -begin -behave -behind -believe -below -belt -bench -benefit -best -betray -better -between -beyond -bicycle -bid -bike -bind -biology -bird -birth -bitter -black -blade -blame -blanket -blast -bleak -bless -blind -blood -blossom -blouse -blue -blur -blush -board -boat -body -boil -bomb -bone -bonus -book -boost -border -boring -borrow -boss -bottom -bounce -box -boy -bracket -brain -brand -brass -brave -bread -breeze -brick -bridge -brief -bright -bring -brisk -broccoli -broken -bronze -broom -brother -brown -brush -bubble -buddy -budget -buffalo -build -bulb -bulk -bullet -bundle -bunker -burden -burger -burst -bus -business -busy -butter -buyer -buzz -cabbage -cabin -cable -cactus -cage -cake -call -calm -camera -camp -can -canal -cancel -candy -cannon -canoe -canvas -canyon -capable -capital -captain -car -carbon -card -cargo -carpet -carry -cart -case -cash -casino -castle -casual -cat -catalog -catch -category -cattle -caught -cause -caution -cave -ceiling -celery -cement -census -century -cereal -certain -chair -chalk -champion -change -chaos -chapter -charge -chase -chat -cheap -check -cheese -chef -cherry -chest -chicken -chief -child -chimney -choice -choose -chronic -chuckle -chunk -churn -cigar -cinnamon -circle -citizen -city -civil -claim -clap -clarify -claw -clay -clean -clerk -clever -click -client -cliff -climb -clinic -clip -clock -clog -close -cloth -cloud -clown -club -clump -cluster -clutch -coach -coast -coconut -code -coffee -coil -coin -collect -color -column -combine -come -comfort -comic -common -company -concert -conduct -confirm -congress -connect -consider -control -convince -cook -cool -copper -copy -coral -core -corn -correct -cost -cotton -couch -country -couple -course -cousin -cover -coyote -crack -cradle -craft -cram -crane -crash -crater -crawl -crazy -cream -credit -creek -crew -cricket -crime -crisp -critic -crop -cross -crouch -crowd -crucial -cruel -cruise -crumble -crunch -crush -cry -crystal -cube -culture -cup -cupboard -curious -current -curtain -curve -cushion -custom -cute -cycle -dad -damage -damp -dance -danger -daring -dash -daughter -dawn -day -deal -debate -debris -decade -december -decide -decline -decorate -decrease -deer -defense -define -defy -degree -delay -deliver -demand -demise -denial -dentist -deny -depart -depend -deposit -depth -deputy -derive -describe -desert -design -desk -despair -destroy -detail -detect -develop -device -devote -diagram -dial -diamond -diary -dice -diesel -diet -differ -digital -dignity -dilemma -dinner -dinosaur -direct -dirt -disagree -discover -disease -dish -dismiss -disorder -display -distance -divert -divide -divorce -dizzy -doctor -document -dog -doll -dolphin -domain -donate -donkey -donor -door -dose -double -dove -draft -dragon -drama -drastic -draw -dream -dress -drift -drill -drink -drip -drive -drop -drum -dry -duck -dumb -dune -during -dust -dutch -duty -dwarf -dynamic -eager -eagle -early -earn -earth -easily -east -easy -echo -ecology -economy -edge -edit -educate -effort -egg -eight -either -elbow -elder -electric -elegant -element -elephant -elevator -elite -else -embark -embody -embrace -emerge -emotion -employ -empower -empty -enable -enact -end -endless -endorse -enemy -energy -enforce -engage -engine -enhance -enjoy -enlist -enough -enrich -enroll -ensure -enter -entire -entry -envelope -episode -equal -equip -era -erase -erode -erosion -error -erupt -escape -essay -essence -estate -eternal -ethics -evidence -evil -evoke -evolve -exact -example -excess -exchange -excite -exclude -excuse -execute -exercise -exhaust -exhibit -exile -exist -exit -exotic -expand -expect -expire -explain -expose -express -extend -extra -eye -eyebrow -fabric -face -faculty -fade -faint -faith -fall -false -fame -family -famous -fan -fancy -fantasy -farm -fashion -fat -fatal -father -fatigue -fault -favorite -feature -february -federal -fee -feed -feel -female -fence -festival -fetch -fever -few -fiber -fiction -field -figure -file -film -filter -final -find -fine -finger -finish -fire -firm -first -fiscal -fish -fit -fitness -fix -flag -flame -flash -flat -flavor -flee -flight -flip -float -flock -floor -flower -fluid -flush -fly -foam -focus -fog -foil -fold -follow -food -foot -force -forest -forget -fork -fortune -forum -forward -fossil -foster -found -fox -fragile -frame -frequent -fresh -friend -fringe -frog -front -frost -frown -frozen -fruit -fuel -fun -funny -furnace -fury -future -gadget -gain -galaxy -gallery -game -gap -garage -garbage -garden -garlic -garment -gas -gasp -gate -gather -gauge -gaze -general -genius -genre -gentle -genuine -gesture -ghost -giant -gift -giggle -ginger -giraffe -girl -give -glad -glance -glare -glass -glide -glimpse -globe -gloom -glory -glove -glow -glue -goat -goddess -gold -good -goose -gorilla -gospel -gossip -govern -gown -grab -grace -grain -grant -grape -grass -gravity -great -green -grid -grief -grit -grocery -group -grow -grunt -guard -guess -guide -guilt -guitar -gun -gym -habit -hair -half -hammer -hamster -hand -happy -harbor -hard -harsh -harvest -hat -have -hawk -hazard -head -health -heart -heavy -hedgehog -height -hello -helmet -help -hen -hero -hidden -high -hill -hint -hip -hire -history -hobby -hockey -hold -hole -holiday -hollow -home -honey -hood -hope -horn -horror -horse -hospital -host -hotel -hour -hover -hub -huge -human -humble -humor -hundred -hungry -hunt -hurdle -hurry -hurt -husband -hybrid -ice -icon -idea -identify -idle -ignore -ill -illegal -illness -image -imitate -immense -immune -impact -impose -improve -impulse -inch -include -income -increase -index -indicate -indoor -industry -infant -inflict -inform -inhale -inherit -initial -inject -injury -inmate -inner -innocent -input -inquiry -insane -insect -inside -inspire -install -intact -interest -into -invest -invite -involve -iron -island -isolate -issue -item -ivory -jacket -jaguar -jar -jazz -jealous -jeans -jelly -jewel -job -join -joke -journey -joy -judge -juice -jump -jungle -junior -junk -just -kangaroo -keen -keep -ketchup -key -kick -kid -kidney -kind -kingdom -kiss -kit -kitchen -kite -kitten -kiwi -knee -knife -knock -know -lab -label -labor -ladder -lady -lake -lamp -language -laptop -large -later -latin -laugh -laundry -lava -law -lawn -lawsuit -layer -lazy -leader -leaf -learn -leave -lecture -left -leg -legal -legend -leisure -lemon -lend -length -lens -leopard -lesson -letter -level -liar -liberty -library -license -life -lift -light -like -limb -limit -link -lion -liquid -list -little -live -lizard -load -loan -lobster -local -lock -logic -lonely -long -loop -lottery -loud -lounge -love -loyal -lucky -luggage -lumber -lunar -lunch -luxury -lyrics -machine -mad -magic -magnet -maid -mail -main -major -make -mammal -man -manage -mandate -mango -mansion -manual -maple -marble -march -margin -marine -market -marriage -mask -mass -master -match -material -math -matrix -matter -maximum -maze -meadow -mean -measure -meat -mechanic -medal -media -melody -melt -member -memory -mention -menu -mercy -merge -merit -merry -mesh -message -metal -method -middle -midnight -milk -million -mimic -mind -minimum -minor -minute -miracle -mirror -misery -miss -mistake -mix -mixed -mixture -mobile -model -modify -mom -moment -monitor -monkey -monster -month -moon -moral -more -morning -mosquito -mother -motion -motor -mountain -mouse -move -movie -much -muffin -mule -multiply -muscle -museum -mushroom -music -must -mutual -myself -mystery -myth -naive -name -napkin -narrow -nasty -nation -nature -near -neck -need -negative -neglect -neither -nephew -nerve -nest -net -network -neutral -never -news -next -nice -night -noble -noise -nominee -noodle -normal -north -nose -notable -note -nothing -notice -novel -now -nuclear -number -nurse -nut -oak -obey -object -oblige -obscure -observe -obtain -obvious -occur -ocean -october -odor -off -offer -office -often -oil -okay -old -olive -olympic -omit -once -one -onion -online -only -open -opera -opinion -oppose -option -orange -orbit -orchard -order -ordinary -organ -orient -original -orphan -ostrich -other -outdoor -outer -output -outside -oval -oven -over -own -owner -oxygen -oyster -ozone -pact -paddle -page -pair -palace -palm -panda -panel -panic -panther -paper -parade -parent -park -parrot -party -pass -patch -path -patient -patrol -pattern -pause -pave -payment -peace -peanut -pear -peasant -pelican -pen -penalty -pencil -people -pepper -perfect -permit -person -pet -phone -photo -phrase -physical -piano -picnic -picture -piece -pig -pigeon -pill -pilot -pink -pioneer -pipe -pistol -pitch -pizza -place -planet -plastic -plate -play -please -pledge -pluck -plug -plunge -poem -poet -point -polar -pole -police -pond -pony -pool -popular -portion -position -possible -post -potato -pottery -poverty -powder -power -practice -praise -predict -prefer -prepare -present -pretty -prevent -price -pride -primary -print -priority -prison -private -prize -problem -process -produce -profit -program -project -promote -proof -property -prosper -protect -proud -provide -public -pudding -pull -pulp -pulse -pumpkin -punch -pupil -puppy -purchase -purity -purpose -purse -push -put -puzzle -pyramid -quality -quantum -quarter -question -quick -quit -quiz -quote -rabbit -raccoon -race -rack -radar -radio -rail -rain -raise -rally -ramp -ranch -random -range -rapid -rare -rate -rather -raven -raw -razor -ready -real -reason -rebel -rebuild -recall -receive -recipe -record -recycle -reduce -reflect -reform -refuse -region -regret -regular -reject -relax -release -relief -rely -remain -remember -remind -remove -render -renew -rent -reopen -repair -repeat -replace -report -require -rescue -resemble -resist -resource -response -result -retire -retreat -return -reunion -reveal -review -reward -rhythm -rib -ribbon -rice -rich -ride -ridge -rifle -right -rigid -ring -riot -ripple -risk -ritual -rival -river -road -roast -robot -robust -rocket -romance -roof -rookie -room -rose -rotate -rough -round -route -royal -rubber -rude -rug -rule -run -runway -rural -sad -saddle -sadness -safe -sail -salad -salmon -salon -salt -salute -same -sample -sand -satisfy -satoshi -sauce -sausage -save -say -scale -scan -scare -scatter -scene -scheme -school -science -scissors -scorpion -scout -scrap -screen -script -scrub -sea -search -season -seat -second -secret -section -security -seed -seek -segment -select -sell -seminar -senior -sense -sentence -series -service -session -settle -setup -seven -shadow -shaft -shallow -share -shed -shell -sheriff -shield -shift -shine -ship -shiver -shock -shoe -shoot -shop -short -shoulder -shove -shrimp -shrug -shuffle -shy -sibling -sick -side -siege -sight -sign -silent -silk -silly -silver -similar -simple -since -sing -siren -sister -situate -six -size -skate -sketch -ski -skill -skin -skirt -skull -slab -slam -sleep -slender -slice -slide -slight -slim -slogan -slot -slow -slush -small -smart -smile -smoke -smooth -snack -snake -snap -sniff -snow -soap -soccer -social -sock -soda -soft -solar -soldier -solid -solution -solve -someone -song -soon -sorry -sort -soul -sound -soup -source -south -space -spare -spatial -spawn -speak -special -speed -spell -spend -sphere -spice -spider -spike -spin -spirit -split -spoil -sponsor -spoon -sport -spot -spray -spread -spring -spy -square -squeeze -squirrel -stable -stadium -staff -stage -stairs -stamp -stand -start -state -stay -steak -steel -stem -step -stereo -stick -still -sting -stock -stomach -stone -stool -story -stove -strategy -street -strike -strong -struggle -student -stuff -stumble -style -subject -submit -subway -success -such -sudden -suffer -sugar -suggest -suit -summer -sun -sunny -sunset -super -supply -supreme -sure -surface -surge -surprise -surround -survey -suspect -sustain -swallow -swamp -swap -swarm -swear -sweet -swift -swim -swing -switch -sword -symbol -symptom -syrup -system -table -tackle -tag -tail -talent -talk -tank -tape -target -task -taste -tattoo -taxi -teach -team -tell -ten -tenant -tennis -tent -term -test -text -thank -that -theme -then -theory -there -they -thing -this -thought -three -thrive -throw -thumb -thunder -ticket -tide -tiger -tilt -timber -time -tiny -tip -tired -tissue -title -toast -tobacco -today -toddler -toe -together -toilet -token -tomato -tomorrow -tone -tongue -tonight -tool -tooth -top -topic -topple -torch -tornado -tortoise -toss -total -tourist -toward -tower -town -toy -track -trade -traffic -tragic -train -transfer -trap -trash -travel -tray -treat -tree -trend -trial -tribe -trick -trigger -trim -trip -trophy -trouble -truck -true -truly -trumpet -trust -truth -try -tube -tuition -tumble -tuna -tunnel -turkey -turn -turtle -twelve -twenty -twice -twin -twist -two -type -typical -ugly -umbrella -unable -unaware -uncle -uncover -under -undo -unfair -unfold -unhappy -uniform -unique -unit -universe -unknown -unlock -until -unusual -unveil -update -upgrade -uphold -upon -upper -upset -urban -urge -usage -use -used -useful -useless -usual -utility -vacant -vacuum -vague -valid -valley -valve -van -vanish -vapor -various -vast -vault -vehicle -velvet -vendor -venture -venue -verb -verify -version -very -vessel -veteran -viable -vibrant -vicious -victory -video -view -village -vintage -violin -virtual -virus -visa -visit -visual -vital -vivid -vocal -voice -void -volcano -volume -vote -voyage -wage -wagon -wait -walk -wall -walnut -want -warfare -warm -warrior -wash -wasp -waste -water -wave -way -wealth -weapon -wear -weasel -weather -web -wedding -weekend -weird -welcome -west -wet -whale -what -wheat -wheel -when -where -whip -whisper -wide -width -wife -wild -will -win -window -wine -wing -wink -winner -winter -wire -wisdom -wise -wish -witness -wolf -woman -wonder -wood -wool -word -work -world -worry -worth -wrap -wreck -wrestle -wrist -write -wrong -yard -year -yellow -you -young -youth -zebra -zero -zone -zoo`.split("\n"); diff --git a/src/lib/english.ts b/src/lib/english.ts new file mode 100644 index 00000000..52a0da82 --- /dev/null +++ b/src/lib/english.ts @@ -0,0 +1,2048 @@ +export default `abandon +ability +able +about +above +absent +absorb +abstract +absurd +abuse +access +accident +account +accuse +achieve +acid +acoustic +acquire +across +act +action +actor +actress +actual +adapt +add +addict +address +adjust +admit +adult +advance +advice +aerobic +affair +afford +afraid +again +age +agent +agree +ahead +aim +air +airport +aisle +alarm +album +alcohol +alert +alien +all +alley +allow +almost +alone +alpha +already +also +alter +always +amateur +amazing +among +amount +amused +analyst +anchor +ancient +anger +angle +angry +animal +ankle +announce +annual +another +answer +antenna +antique +anxiety +any +apart +apology +appear +apple +approve +april +arch +arctic +area +arena +argue +arm +armed +armor +army +around +arrange +arrest +arrive +arrow +art +artefact +artist +artwork +ask +aspect +assault +asset +assist +assume +asthma +athlete +atom +attack +attend +attitude +attract +auction +audit +august +aunt +author +auto +autumn +average +avocado +avoid +awake +aware +away +awesome +awful +awkward +axis +baby +bachelor +bacon +badge +bag +balance +balcony +ball +bamboo +banana +banner +bar +barely +bargain +barrel +base +basic +basket +battle +beach +bean +beauty +because +become +beef +before +begin +behave +behind +believe +below +belt +bench +benefit +best +betray +better +between +beyond +bicycle +bid +bike +bind +biology +bird +birth +bitter +black +blade +blame +blanket +blast +bleak +bless +blind +blood +blossom +blouse +blue +blur +blush +board +boat +body +boil +bomb +bone +bonus +book +boost +border +boring +borrow +boss +bottom +bounce +box +boy +bracket +brain +brand +brass +brave +bread +breeze +brick +bridge +brief +bright +bring +brisk +broccoli +broken +bronze +broom +brother +brown +brush +bubble +buddy +budget +buffalo +build +bulb +bulk +bullet +bundle +bunker +burden +burger +burst +bus +business +busy +butter +buyer +buzz +cabbage +cabin +cable +cactus +cage +cake +call +calm +camera +camp +can +canal +cancel +candy +cannon +canoe +canvas +canyon +capable +capital +captain +car +carbon +card +cargo +carpet +carry +cart +case +cash +casino +castle +casual +cat +catalog +catch +category +cattle +caught +cause +caution +cave +ceiling +celery +cement +census +century +cereal +certain +chair +chalk +champion +change +chaos +chapter +charge +chase +chat +cheap +check +cheese +chef +cherry +chest +chicken +chief +child +chimney +choice +choose +chronic +chuckle +chunk +churn +cigar +cinnamon +circle +citizen +city +civil +claim +clap +clarify +claw +clay +clean +clerk +clever +click +client +cliff +climb +clinic +clip +clock +clog +close +cloth +cloud +clown +club +clump +cluster +clutch +coach +coast +coconut +code +coffee +coil +coin +collect +color +column +combine +come +comfort +comic +common +company +concert +conduct +confirm +congress +connect +consider +control +convince +cook +cool +copper +copy +coral +core +corn +correct +cost +cotton +couch +country +couple +course +cousin +cover +coyote +crack +cradle +craft +cram +crane +crash +crater +crawl +crazy +cream +credit +creek +crew +cricket +crime +crisp +critic +crop +cross +crouch +crowd +crucial +cruel +cruise +crumble +crunch +crush +cry +crystal +cube +culture +cup +cupboard +curious +current +curtain +curve +cushion +custom +cute +cycle +dad +damage +damp +dance +danger +daring +dash +daughter +dawn +day +deal +debate +debris +decade +december +decide +decline +decorate +decrease +deer +defense +define +defy +degree +delay +deliver +demand +demise +denial +dentist +deny +depart +depend +deposit +depth +deputy +derive +describe +desert +design +desk +despair +destroy +detail +detect +develop +device +devote +diagram +dial +diamond +diary +dice +diesel +diet +differ +digital +dignity +dilemma +dinner +dinosaur +direct +dirt +disagree +discover +disease +dish +dismiss +disorder +display +distance +divert +divide +divorce +dizzy +doctor +document +dog +doll +dolphin +domain +donate +donkey +donor +door +dose +double +dove +draft +dragon +drama +drastic +draw +dream +dress +drift +drill +drink +drip +drive +drop +drum +dry +duck +dumb +dune +during +dust +dutch +duty +dwarf +dynamic +eager +eagle +early +earn +earth +easily +east +easy +echo +ecology +economy +edge +edit +educate +effort +egg +eight +either +elbow +elder +electric +elegant +element +elephant +elevator +elite +else +embark +embody +embrace +emerge +emotion +employ +empower +empty +enable +enact +end +endless +endorse +enemy +energy +enforce +engage +engine +enhance +enjoy +enlist +enough +enrich +enroll +ensure +enter +entire +entry +envelope +episode +equal +equip +era +erase +erode +erosion +error +erupt +escape +essay +essence +estate +eternal +ethics +evidence +evil +evoke +evolve +exact +example +excess +exchange +excite +exclude +excuse +execute +exercise +exhaust +exhibit +exile +exist +exit +exotic +expand +expect +expire +explain +expose +express +extend +extra +eye +eyebrow +fabric +face +faculty +fade +faint +faith +fall +false +fame +family +famous +fan +fancy +fantasy +farm +fashion +fat +fatal +father +fatigue +fault +favorite +feature +february +federal +fee +feed +feel +female +fence +festival +fetch +fever +few +fiber +fiction +field +figure +file +film +filter +final +find +fine +finger +finish +fire +firm +first +fiscal +fish +fit +fitness +fix +flag +flame +flash +flat +flavor +flee +flight +flip +float +flock +floor +flower +fluid +flush +fly +foam +focus +fog +foil +fold +follow +food +foot +force +forest +forget +fork +fortune +forum +forward +fossil +foster +found +fox +fragile +frame +frequent +fresh +friend +fringe +frog +front +frost +frown +frozen +fruit +fuel +fun +funny +furnace +fury +future +gadget +gain +galaxy +gallery +game +gap +garage +garbage +garden +garlic +garment +gas +gasp +gate +gather +gauge +gaze +general +genius +genre +gentle +genuine +gesture +ghost +giant +gift +giggle +ginger +giraffe +girl +give +glad +glance +glare +glass +glide +glimpse +globe +gloom +glory +glove +glow +glue +goat +goddess +gold +good +goose +gorilla +gospel +gossip +govern +gown +grab +grace +grain +grant +grape +grass +gravity +great +green +grid +grief +grit +grocery +group +grow +grunt +guard +guess +guide +guilt +guitar +gun +gym +habit +hair +half +hammer +hamster +hand +happy +harbor +hard +harsh +harvest +hat +have +hawk +hazard +head +health +heart +heavy +hedgehog +height +hello +helmet +help +hen +hero +hidden +high +hill +hint +hip +hire +history +hobby +hockey +hold +hole +holiday +hollow +home +honey +hood +hope +horn +horror +horse +hospital +host +hotel +hour +hover +hub +huge +human +humble +humor +hundred +hungry +hunt +hurdle +hurry +hurt +husband +hybrid +ice +icon +idea +identify +idle +ignore +ill +illegal +illness +image +imitate +immense +immune +impact +impose +improve +impulse +inch +include +income +increase +index +indicate +indoor +industry +infant +inflict +inform +inhale +inherit +initial +inject +injury +inmate +inner +innocent +input +inquiry +insane +insect +inside +inspire +install +intact +interest +into +invest +invite +involve +iron +island +isolate +issue +item +ivory +jacket +jaguar +jar +jazz +jealous +jeans +jelly +jewel +job +join +joke +journey +joy +judge +juice +jump +jungle +junior +junk +just +kangaroo +keen +keep +ketchup +key +kick +kid +kidney +kind +kingdom +kiss +kit +kitchen +kite +kitten +kiwi +knee +knife +knock +know +lab +label +labor +ladder +lady +lake +lamp +language +laptop +large +later +latin +laugh +laundry +lava +law +lawn +lawsuit +layer +lazy +leader +leaf +learn +leave +lecture +left +leg +legal +legend +leisure +lemon +lend +length +lens +leopard +lesson +letter +level +liar +liberty +library +license +life +lift +light +like +limb +limit +link +lion +liquid +list +little +live +lizard +load +loan +lobster +local +lock +logic +lonely +long +loop +lottery +loud +lounge +love +loyal +lucky +luggage +lumber +lunar +lunch +luxury +lyrics +machine +mad +magic +magnet +maid +mail +main +major +make +mammal +man +manage +mandate +mango +mansion +manual +maple +marble +march +margin +marine +market +marriage +mask +mass +master +match +material +math +matrix +matter +maximum +maze +meadow +mean +measure +meat +mechanic +medal +media +melody +melt +member +memory +mention +menu +mercy +merge +merit +merry +mesh +message +metal +method +middle +midnight +milk +million +mimic +mind +minimum +minor +minute +miracle +mirror +misery +miss +mistake +mix +mixed +mixture +mobile +model +modify +mom +moment +monitor +monkey +monster +month +moon +moral +more +morning +mosquito +mother +motion +motor +mountain +mouse +move +movie +much +muffin +mule +multiply +muscle +museum +mushroom +music +must +mutual +myself +mystery +myth +naive +name +napkin +narrow +nasty +nation +nature +near +neck +need +negative +neglect +neither +nephew +nerve +nest +net +network +neutral +never +news +next +nice +night +noble +noise +nominee +noodle +normal +north +nose +notable +note +nothing +notice +novel +now +nuclear +number +nurse +nut +oak +obey +object +oblige +obscure +observe +obtain +obvious +occur +ocean +october +odor +off +offer +office +often +oil +okay +old +olive +olympic +omit +once +one +onion +online +only +open +opera +opinion +oppose +option +orange +orbit +orchard +order +ordinary +organ +orient +original +orphan +ostrich +other +outdoor +outer +output +outside +oval +oven +over +own +owner +oxygen +oyster +ozone +pact +paddle +page +pair +palace +palm +panda +panel +panic +panther +paper +parade +parent +park +parrot +party +pass +patch +path +patient +patrol +pattern +pause +pave +payment +peace +peanut +pear +peasant +pelican +pen +penalty +pencil +people +pepper +perfect +permit +person +pet +phone +photo +phrase +physical +piano +picnic +picture +piece +pig +pigeon +pill +pilot +pink +pioneer +pipe +pistol +pitch +pizza +place +planet +plastic +plate +play +please +pledge +pluck +plug +plunge +poem +poet +point +polar +pole +police +pond +pony +pool +popular +portion +position +possible +post +potato +pottery +poverty +powder +power +practice +praise +predict +prefer +prepare +present +pretty +prevent +price +pride +primary +print +priority +prison +private +prize +problem +process +produce +profit +program +project +promote +proof +property +prosper +protect +proud +provide +public +pudding +pull +pulp +pulse +pumpkin +punch +pupil +puppy +purchase +purity +purpose +purse +push +put +puzzle +pyramid +quality +quantum +quarter +question +quick +quit +quiz +quote +rabbit +raccoon +race +rack +radar +radio +rail +rain +raise +rally +ramp +ranch +random +range +rapid +rare +rate +rather +raven +raw +razor +ready +real +reason +rebel +rebuild +recall +receive +recipe +record +recycle +reduce +reflect +reform +refuse +region +regret +regular +reject +relax +release +relief +rely +remain +remember +remind +remove +render +renew +rent +reopen +repair +repeat +replace +report +require +rescue +resemble +resist +resource +response +result +retire +retreat +return +reunion +reveal +review +reward +rhythm +rib +ribbon +rice +rich +ride +ridge +rifle +right +rigid +ring +riot +ripple +risk +ritual +rival +river +road +roast +robot +robust +rocket +romance +roof +rookie +room +rose +rotate +rough +round +route +royal +rubber +rude +rug +rule +run +runway +rural +sad +saddle +sadness +safe +sail +salad +salmon +salon +salt +salute +same +sample +sand +satisfy +satoshi +sauce +sausage +save +say +scale +scan +scare +scatter +scene +scheme +school +science +scissors +scorpion +scout +scrap +screen +script +scrub +sea +search +season +seat +second +secret +section +security +seed +seek +segment +select +sell +seminar +senior +sense +sentence +series +service +session +settle +setup +seven +shadow +shaft +shallow +share +shed +shell +sheriff +shield +shift +shine +ship +shiver +shock +shoe +shoot +shop +short +shoulder +shove +shrimp +shrug +shuffle +shy +sibling +sick +side +siege +sight +sign +silent +silk +silly +silver +similar +simple +since +sing +siren +sister +situate +six +size +skate +sketch +ski +skill +skin +skirt +skull +slab +slam +sleep +slender +slice +slide +slight +slim +slogan +slot +slow +slush +small +smart +smile +smoke +smooth +snack +snake +snap +sniff +snow +soap +soccer +social +sock +soda +soft +solar +soldier +solid +solution +solve +someone +song +soon +sorry +sort +soul +sound +soup +source +south +space +spare +spatial +spawn +speak +special +speed +spell +spend +sphere +spice +spider +spike +spin +spirit +split +spoil +sponsor +spoon +sport +spot +spray +spread +spring +spy +square +squeeze +squirrel +stable +stadium +staff +stage +stairs +stamp +stand +start +state +stay +steak +steel +stem +step +stereo +stick +still +sting +stock +stomach +stone +stool +story +stove +strategy +street +strike +strong +struggle +student +stuff +stumble +style +subject +submit +subway +success +such +sudden +suffer +sugar +suggest +suit +summer +sun +sunny +sunset +super +supply +supreme +sure +surface +surge +surprise +surround +survey +suspect +sustain +swallow +swamp +swap +swarm +swear +sweet +swift +swim +swing +switch +sword +symbol +symptom +syrup +system +table +tackle +tag +tail +talent +talk +tank +tape +target +task +taste +tattoo +taxi +teach +team +tell +ten +tenant +tennis +tent +term +test +text +thank +that +theme +then +theory +there +they +thing +this +thought +three +thrive +throw +thumb +thunder +ticket +tide +tiger +tilt +timber +time +tiny +tip +tired +tissue +title +toast +tobacco +today +toddler +toe +together +toilet +token +tomato +tomorrow +tone +tongue +tonight +tool +tooth +top +topic +topple +torch +tornado +tortoise +toss +total +tourist +toward +tower +town +toy +track +trade +traffic +tragic +train +transfer +trap +trash +travel +tray +treat +tree +trend +trial +tribe +trick +trigger +trim +trip +trophy +trouble +truck +true +truly +trumpet +trust +truth +try +tube +tuition +tumble +tuna +tunnel +turkey +turn +turtle +twelve +twenty +twice +twin +twist +two +type +typical +ugly +umbrella +unable +unaware +uncle +uncover +under +undo +unfair +unfold +unhappy +uniform +unique +unit +universe +unknown +unlock +until +unusual +unveil +update +upgrade +uphold +upon +upper +upset +urban +urge +usage +use +used +useful +useless +usual +utility +vacant +vacuum +vague +valid +valley +valve +van +vanish +vapor +various +vast +vault +vehicle +velvet +vendor +venture +venue +verb +verify +version +very +vessel +veteran +viable +vibrant +vicious +victory +video +view +village +vintage +violin +virtual +virus +visa +visit +visual +vital +vivid +vocal +voice +void +volcano +volume +vote +voyage +wage +wagon +wait +walk +wall +walnut +want +warfare +warm +warrior +wash +wasp +waste +water +wave +way +wealth +weapon +wear +weasel +weather +web +wedding +weekend +weird +welcome +west +wet +whale +what +wheat +wheel +when +where +whip +whisper +wide +width +wife +wild +will +win +window +wine +wing +wink +winner +winter +wire +wisdom +wise +wish +witness +wolf +woman +wonder +wood +wool +word +work +world +worry +worth +wrap +wreck +wrestle +wrist +write +wrong +yard +year +yellow +you +young +youth +zebra +zero +zone +zoo`.split("\n"); diff --git a/src/lib/handler.js b/src/lib/handler.js deleted file mode 100644 index 05e484ec..00000000 --- a/src/lib/handler.js +++ /dev/null @@ -1,14 +0,0 @@ -import { goto } from "$app/navigation"; -import { applyAction } from "$app/forms"; - -export default (submitting) => - ({ formElement, formData, action, cancel }) => { - submitting = true; - return async ({ result }) => { - if (result.type === "redirect") { - goto(result.location); - } else { - await applyAction(result); - } - }; - }; diff --git a/src/lib/handler.ts b/src/lib/handler.ts new file mode 100644 index 00000000..05e484ec --- /dev/null +++ b/src/lib/handler.ts @@ -0,0 +1,14 @@ +import { goto } from "$app/navigation"; +import { applyAction } from "$app/forms"; + +export default (submitting) => + ({ formElement, formData, action, cancel }) => { + submitting = true; + return async ({ result }) => { + if (result.type === "redirect") { + goto(result.location); + } else { + await applyAction(result); + } + }; + }; diff --git a/src/lib/invoice.js b/src/lib/invoice.js deleted file mode 100644 index d2d3d13d..00000000 --- a/src/lib/invoice.js +++ /dev/null @@ -1,32 +0,0 @@ -import { auth, get, post } from "$lib/utils"; -import { redirect } from "@sveltejs/kit"; - -export default async ({ cookies, request, url }) => { - let form = await request.formData(); - - let rates = await get("/rates"); - let amount = parseInt(form.get("amount")); - - let invoice = { - amount, - items: JSON.parse(form.get("items")), - memo: form.get("memo"), - memoPrompt: form.get("memoPrompt"), - tip: parseInt(form.get("tip")) || 0, - type: form.get("type"), - prompt: form.get("prompt") === "true", - rate: parseFloat(form.get("rate")) || rates[form.get("currency")], - }; - - let user = { username: form.get("username"), currency: form.get("currency") }; - - invoice = await post("/invoice", { invoice, user }, auth(cookies)); - let { id } = invoice; - - if (invoice.prompt && invoice.tip === null) - redirect(307, `/${user.username}/invoice/${id}/tip`); - - if (invoice.memoPrompt && !invoice.memo) { - redirect(307, `/${user.username}/invoice/${id}/memo`); - } else redirect(307, `/${user.username}/invoice/${id}`); -}; diff --git a/src/lib/invoice.ts b/src/lib/invoice.ts new file mode 100644 index 00000000..d2d3d13d --- /dev/null +++ b/src/lib/invoice.ts @@ -0,0 +1,32 @@ +import { auth, get, post } from "$lib/utils"; +import { redirect } from "@sveltejs/kit"; + +export default async ({ cookies, request, url }) => { + let form = await request.formData(); + + let rates = await get("/rates"); + let amount = parseInt(form.get("amount")); + + let invoice = { + amount, + items: JSON.parse(form.get("items")), + memo: form.get("memo"), + memoPrompt: form.get("memoPrompt"), + tip: parseInt(form.get("tip")) || 0, + type: form.get("type"), + prompt: form.get("prompt") === "true", + rate: parseFloat(form.get("rate")) || rates[form.get("currency")], + }; + + let user = { username: form.get("username"), currency: form.get("currency") }; + + invoice = await post("/invoice", { invoice, user }, auth(cookies)); + let { id } = invoice; + + if (invoice.prompt && invoice.tip === null) + redirect(307, `/${user.username}/invoice/${id}/tip`); + + if (invoice.memoPrompt && !invoice.memo) { + redirect(307, `/${user.username}/invoice/${id}/memo`); + } else redirect(307, `/${user.username}/invoice/${id}`); +}; diff --git a/src/lib/parse.js b/src/lib/parse.js deleted file mode 100644 index 09c6f320..00000000 --- a/src/lib/parse.js +++ /dev/null @@ -1,87 +0,0 @@ -import { auth, get, isLiquid, post } from "$lib/utils"; -import bip21 from "bip21"; -import { validate } from "bitcoin-address-validation"; -import { PUBLIC_DOMAIN } from "$env/static/public"; -import { redirect } from "@sveltejs/kit"; - -export default async (t, host, cookies) => { - if (!t) return; - - if (t.startsWith("http")) redirect(307, t); - if (t.startsWith(host)) redirect(307, `http://${t}`); - - let amount, id, user; - - t = t.trim(); - t.toLowerCase().startsWith("bitcoin:") && - ({ - address: t, - options: { amount }, - } = bip21.decode(t)); - - if (t.startsWith("lightning:")) t = t.replace("lightning:", ""); - if (t.endsWith(`@${PUBLIC_DOMAIN}`)) t = t.split("@")[0]; - if (t.includes("@") && t.includes(".")) { - try { - t = await get(`/encode?address=${t}`); - } catch (e) {} - } - - if (t.includes("/fund")) redirect(307, t.substring(t.indexOf("/fund"))); - - // lightning - if (t.toLowerCase().startsWith("lightning:")) - t = t.toLowerCase().replace("lightning:", ""); - if (t.toLowerCase().startsWith("lnurl")) redirect(307, `/ln/${t}`); - if (t.includes(":")) t = t.split(":")[1]; - - if (t.toLowerCase().startsWith("ln")) { - try { - ({ id } = await get(`/invoice/${t}`)); - } catch (e) { - redirect(307, `/send/lightning/${t}`); - } - } - - // bitcoin - if (validate(t) || isLiquid(t)) { - try { - ({ id, user } = await get(`/invoice/${t}`)); - } catch (e) { - let r = `/send/bitcoin/${t}`; - if (amount) r += "/" + amount; - redirect(307, r); - } - - if (user) redirect(307, `/pay/${user.username}`); - else if (id) redirect(307, `/send/${id}`); - } - - if (t.startsWith("cashu")) { - let { id } = await post("/cash", { token: t }, auth); - redirect(307, `/ecash/${id}`); - } - - // user - try { - user = await get(`/users/${t.split("/")[0]}`); - if (user.anon) user = null; - } catch (e) {} - - if (user) redirect(307, `/pay/${t}`); - - let fund; - try { - fund = await get(`/fund/${t}`); - } catch (e) {} - - if (fund) redirect(307, `/send/fund/${t}`); - - // invoice - let invoice; - try { - invoice = await get(`/invoice/${t}`); - } catch (e) {} - - if (invoice) redirect(307, `/send/invoice/${invoice.id}`); -}; diff --git a/src/lib/parse.ts b/src/lib/parse.ts new file mode 100644 index 00000000..09c6f320 --- /dev/null +++ b/src/lib/parse.ts @@ -0,0 +1,87 @@ +import { auth, get, isLiquid, post } from "$lib/utils"; +import bip21 from "bip21"; +import { validate } from "bitcoin-address-validation"; +import { PUBLIC_DOMAIN } from "$env/static/public"; +import { redirect } from "@sveltejs/kit"; + +export default async (t, host, cookies) => { + if (!t) return; + + if (t.startsWith("http")) redirect(307, t); + if (t.startsWith(host)) redirect(307, `http://${t}`); + + let amount, id, user; + + t = t.trim(); + t.toLowerCase().startsWith("bitcoin:") && + ({ + address: t, + options: { amount }, + } = bip21.decode(t)); + + if (t.startsWith("lightning:")) t = t.replace("lightning:", ""); + if (t.endsWith(`@${PUBLIC_DOMAIN}`)) t = t.split("@")[0]; + if (t.includes("@") && t.includes(".")) { + try { + t = await get(`/encode?address=${t}`); + } catch (e) {} + } + + if (t.includes("/fund")) redirect(307, t.substring(t.indexOf("/fund"))); + + // lightning + if (t.toLowerCase().startsWith("lightning:")) + t = t.toLowerCase().replace("lightning:", ""); + if (t.toLowerCase().startsWith("lnurl")) redirect(307, `/ln/${t}`); + if (t.includes(":")) t = t.split(":")[1]; + + if (t.toLowerCase().startsWith("ln")) { + try { + ({ id } = await get(`/invoice/${t}`)); + } catch (e) { + redirect(307, `/send/lightning/${t}`); + } + } + + // bitcoin + if (validate(t) || isLiquid(t)) { + try { + ({ id, user } = await get(`/invoice/${t}`)); + } catch (e) { + let r = `/send/bitcoin/${t}`; + if (amount) r += "/" + amount; + redirect(307, r); + } + + if (user) redirect(307, `/pay/${user.username}`); + else if (id) redirect(307, `/send/${id}`); + } + + if (t.startsWith("cashu")) { + let { id } = await post("/cash", { token: t }, auth); + redirect(307, `/ecash/${id}`); + } + + // user + try { + user = await get(`/users/${t.split("/")[0]}`); + if (user.anon) user = null; + } catch (e) {} + + if (user) redirect(307, `/pay/${t}`); + + let fund; + try { + fund = await get(`/fund/${t}`); + } catch (e) {} + + if (fund) redirect(307, `/send/fund/${t}`); + + // invoice + let invoice; + try { + invoice = await get(`/invoice/${t}`); + } catch (e) {} + + if (invoice) redirect(307, `/send/invoice/${invoice.id}`); +}; diff --git a/src/lib/punks.js b/src/lib/punks.js deleted file mode 100644 index e5551062..00000000 --- a/src/lib/punks.js +++ /dev/null @@ -1,66 +0,0 @@ -export default [ - "6e1f1626a9308abd0b7732fecbc7d49366ced46dead63ef3603fb0f4ec7aa53d", - "96ea95735b61c48c6f465db8ca0246a62539f34c3a977be6338770d92461da89", - "8c18c036b257d7b9c5a970a786efa04c320f3cf5afa73fa310a6603744d1ee3a", - "a7a6187e54e83acdb893d456c8b4ad6877e4738ea9e0d47c9b2070bf2c98a35f", - "836d72150b6f3033b6220d15ac9d49457d81041a700d12898bd3b8e737b4d265", - "e3d1c40538a8aed282a430647e3ff16ff94b64b8ed0a7cf427e8b0e2780a9b2a", - "2155224ef35cfb4bbdb06d982b42bb9b93d97b2bc691c22c804e1759a0a04882", - "5f6549ad9dd15dd57c204b1a9b60c68c376e77d7d114cfa13219e6a1a71f901f", - "ba8dd5a7070aee7102d4f8bc83ac497091e2e473a0f448a1c513569167dd0791", - "4f07e1da3685a858970a9f39300564971e97257f5d37b55a6d9882014aecc421", - "01aa9348244c4b65de3df758d49c98076e17a109aef04bc211abc77cf42dc51d", - "080574eb9e0613926e0e5d9b667c132e12965a1b1d47218a0b290a2d55c55d2f", - "08ce4840184f63a779bcd1f91bbcb56a2e8cba75c3ba2dbd290a559a57e4238e", - "27caa38c14a85ad64b4c4469a34e61a3965a1cbc4cad9a85707da374301c830d", - "eccc90741370ba4acc70bc65f4ccc38fddb1327d977c366156018974bc52fe4a", - "3759946d9e875ac2fc5c51ed850686193bb1e0716219e42efd52f3965993b275", - "db5fe28b8ddb9ae5e4f5e0e757ee60bc938bffbdfdd38de807939e212d3c5066", - "3f8f861e663accee51e68b987705ce647a7446b7f118abc94c632e158acbb44f", - "43bab95a047112dca6705506f916a97252363a20da4a4c0a5ab7b676e11083fc", - "d3018e45c66dd485697f738ad191af98267e6255d562496dd06b1a662e0c7a88", - "0ec2e8d07e053d686140857493ece653cde52764a60aa1d25651d81811d44a3d", - "4595bb092682af7177799464364c047fbfa7ede767336734949bce5d085fce15", - "6524936709e0719f9e28bf1caac91f86f323d1a79f10ab65a03fa9ea2e6b3270", - "8ba4736edc68da8e5b21c23af4de1f9131f47778c2a5b2a970a799223a9380b3", - "2aaba839e8546a8cb6d04a81ff5be83ac4e700ca4491607a16ebd60dc4995750", - "5f88f7f579ce50d7bcf60d6e9556f77acf361ba54caf3eb61dc4f2ca9c94c6a2", - "d1ca262272613d7386fecce7f1ad268188940b59ea83fdd1f8d7ab85771e3f43", - "5211890e4128d8d730802cc75ee105867e8878581d5e72ffc98a0d60027a5398", - "c1dececcbd7b623bfaa726392512e6ea110db93a0649dd01bf9e559318514f7c", - "43ce93c9835e983403a01329918d184832c5516e1b0ea4e0878b4c4def042777", - "c84724a398bda8d20436fb0663d059c196628fa71192bb720fa5adf6137bed9b", - "f307620a90a36045fa550316d61be4755c1f6c7f3fc81c95fc4d590ac568b2c4", - "78ae0118856a1f17c13f292628fcf3dccc150c7278578caaceb9f35ca8bc9f55", - "9d9a9a40c490f05d7dbafde8bf60d68aab7dcb79a7976eef62d1448a4549816b", - "f6017bec50563dbbb24b979214ae225f96b01dea5b090b174038ff2842a1c6b1", - "6dbec748ea87e959390b0df429c005fccffe9e672864f555c14c7a407b940870", - "11701e76233395ebdba8d1d50334d1a0cc3a158f3452260c9a7b9a067b78d753", - "7354f3829dd05c838aa16d66b00316f7994797927a4d3b594c8af04a2b4ae86a", - "14d254333c6240fbdacbbbe261f7ae15be2e83bffcf084f4f59f459bae0a4571", - "7849ac0f31056265efb0110038f86e61effe17b7db836377d88433b73312e65a", - "9018be885177c675baf9b36978428d841ca30a9185e11de1a31238a08e3ec1af", - "777c5715de7423597fea6c03c496ea46414f0508cd96e119261f002965beb805", - "b742b7509a97c2b346ea762f0510e8475b30dc988417f0f146ae00a800c6dd56", - "7af3029a826e6dfba23ad502901a3632ef4ee047bd45d618b1f106717b0af7ea", - "82390020b2bca461204cc49b20ee6fec1b93dad476726f377785d04040a4d6c3", - "6bc2990699be7f610c9f6a49bc7a19b034040727bc3de63fee89a1573fe00673", - "50c7c2e8e8c7f4aabffb195187a1ac1105f5712859f02d491d794ba2d8498e08", - "5d1d3769cd141603ce907df5dca159e389ca4d75338eddbe1b7db1c0766cbfd6", - "4d8ad7a761d068b7ef9b058fb4ba924b276e7a45a3ad47a79b767e08e821e038", - "d5b5b2167602f7277cdac76cfda8bdad0befcb8ff12df495dfabf40c91d1120c", - "6f2618272bb0164247e9b0f40b19f020c1c9253510dc658a3cc078d079ef01bf", - "fd502d5007bfc62a91eb7a34c1ae23b9de4a20cf5e1bbd86dadc421d7083099c", - "914813583b901044970b9c7d6dcdfde4344339325f5988d0dd681d377f1243fb", - "85cb7cf0245613d08b3027f879f58a6db645bf0db107242beb856b340ee49ee8", - "d6dbb18d5df5e92c8c74ee59aa86d19dff25a5d0f9d030e84285a686f86804d7", - "65309f82cd9f9926a578d09e1ad13909f68a06d02b853760731a4225f7aecef4", - "433519d13f2b64fe82a90cd054797d4779507fea93c1054bd51c35ba846a0f7f", - "62a55d4d6e4b6f992a1c1840f041585c957affcdbf875202cf9e1db9def05aeb", - "e19eb1eeabdeffa04ccd792eb09776690cf2121887b26a7c5d20d66e3e8fd0fb", - "a80951fc593035abb2dda045a2076d29a30f5cc470e0a20db39c3ec588ed61d8", - "4f1b39906714266a7a1936bfa8e08c5d891285dd2b188b4bcd4afb0107671004", - "f46310b2e60727af071d09e759814f52f933688a0ff0995c7da373b381e70005", - "2cc94821f56d21918ba4f2770d97f280e06fd99f4199167e2f4ddc780f404c8a", - "698a2ca7a09e88fa6594801da037f4dbce6ae841d1d33736aebcf8f6fe104e01", -]; diff --git a/src/lib/punks.ts b/src/lib/punks.ts new file mode 100644 index 00000000..e5551062 --- /dev/null +++ b/src/lib/punks.ts @@ -0,0 +1,66 @@ +export default [ + "6e1f1626a9308abd0b7732fecbc7d49366ced46dead63ef3603fb0f4ec7aa53d", + "96ea95735b61c48c6f465db8ca0246a62539f34c3a977be6338770d92461da89", + "8c18c036b257d7b9c5a970a786efa04c320f3cf5afa73fa310a6603744d1ee3a", + "a7a6187e54e83acdb893d456c8b4ad6877e4738ea9e0d47c9b2070bf2c98a35f", + "836d72150b6f3033b6220d15ac9d49457d81041a700d12898bd3b8e737b4d265", + "e3d1c40538a8aed282a430647e3ff16ff94b64b8ed0a7cf427e8b0e2780a9b2a", + "2155224ef35cfb4bbdb06d982b42bb9b93d97b2bc691c22c804e1759a0a04882", + "5f6549ad9dd15dd57c204b1a9b60c68c376e77d7d114cfa13219e6a1a71f901f", + "ba8dd5a7070aee7102d4f8bc83ac497091e2e473a0f448a1c513569167dd0791", + "4f07e1da3685a858970a9f39300564971e97257f5d37b55a6d9882014aecc421", + "01aa9348244c4b65de3df758d49c98076e17a109aef04bc211abc77cf42dc51d", + "080574eb9e0613926e0e5d9b667c132e12965a1b1d47218a0b290a2d55c55d2f", + "08ce4840184f63a779bcd1f91bbcb56a2e8cba75c3ba2dbd290a559a57e4238e", + "27caa38c14a85ad64b4c4469a34e61a3965a1cbc4cad9a85707da374301c830d", + "eccc90741370ba4acc70bc65f4ccc38fddb1327d977c366156018974bc52fe4a", + "3759946d9e875ac2fc5c51ed850686193bb1e0716219e42efd52f3965993b275", + "db5fe28b8ddb9ae5e4f5e0e757ee60bc938bffbdfdd38de807939e212d3c5066", + "3f8f861e663accee51e68b987705ce647a7446b7f118abc94c632e158acbb44f", + "43bab95a047112dca6705506f916a97252363a20da4a4c0a5ab7b676e11083fc", + "d3018e45c66dd485697f738ad191af98267e6255d562496dd06b1a662e0c7a88", + "0ec2e8d07e053d686140857493ece653cde52764a60aa1d25651d81811d44a3d", + "4595bb092682af7177799464364c047fbfa7ede767336734949bce5d085fce15", + "6524936709e0719f9e28bf1caac91f86f323d1a79f10ab65a03fa9ea2e6b3270", + "8ba4736edc68da8e5b21c23af4de1f9131f47778c2a5b2a970a799223a9380b3", + "2aaba839e8546a8cb6d04a81ff5be83ac4e700ca4491607a16ebd60dc4995750", + "5f88f7f579ce50d7bcf60d6e9556f77acf361ba54caf3eb61dc4f2ca9c94c6a2", + "d1ca262272613d7386fecce7f1ad268188940b59ea83fdd1f8d7ab85771e3f43", + "5211890e4128d8d730802cc75ee105867e8878581d5e72ffc98a0d60027a5398", + "c1dececcbd7b623bfaa726392512e6ea110db93a0649dd01bf9e559318514f7c", + "43ce93c9835e983403a01329918d184832c5516e1b0ea4e0878b4c4def042777", + "c84724a398bda8d20436fb0663d059c196628fa71192bb720fa5adf6137bed9b", + "f307620a90a36045fa550316d61be4755c1f6c7f3fc81c95fc4d590ac568b2c4", + "78ae0118856a1f17c13f292628fcf3dccc150c7278578caaceb9f35ca8bc9f55", + "9d9a9a40c490f05d7dbafde8bf60d68aab7dcb79a7976eef62d1448a4549816b", + "f6017bec50563dbbb24b979214ae225f96b01dea5b090b174038ff2842a1c6b1", + "6dbec748ea87e959390b0df429c005fccffe9e672864f555c14c7a407b940870", + "11701e76233395ebdba8d1d50334d1a0cc3a158f3452260c9a7b9a067b78d753", + "7354f3829dd05c838aa16d66b00316f7994797927a4d3b594c8af04a2b4ae86a", + "14d254333c6240fbdacbbbe261f7ae15be2e83bffcf084f4f59f459bae0a4571", + "7849ac0f31056265efb0110038f86e61effe17b7db836377d88433b73312e65a", + "9018be885177c675baf9b36978428d841ca30a9185e11de1a31238a08e3ec1af", + "777c5715de7423597fea6c03c496ea46414f0508cd96e119261f002965beb805", + "b742b7509a97c2b346ea762f0510e8475b30dc988417f0f146ae00a800c6dd56", + "7af3029a826e6dfba23ad502901a3632ef4ee047bd45d618b1f106717b0af7ea", + "82390020b2bca461204cc49b20ee6fec1b93dad476726f377785d04040a4d6c3", + "6bc2990699be7f610c9f6a49bc7a19b034040727bc3de63fee89a1573fe00673", + "50c7c2e8e8c7f4aabffb195187a1ac1105f5712859f02d491d794ba2d8498e08", + "5d1d3769cd141603ce907df5dca159e389ca4d75338eddbe1b7db1c0766cbfd6", + "4d8ad7a761d068b7ef9b058fb4ba924b276e7a45a3ad47a79b767e08e821e038", + "d5b5b2167602f7277cdac76cfda8bdad0befcb8ff12df495dfabf40c91d1120c", + "6f2618272bb0164247e9b0f40b19f020c1c9253510dc658a3cc078d079ef01bf", + "fd502d5007bfc62a91eb7a34c1ae23b9de4a20cf5e1bbd86dadc421d7083099c", + "914813583b901044970b9c7d6dcdfde4344339325f5988d0dd681d377f1243fb", + "85cb7cf0245613d08b3027f879f58a6db645bf0db107242beb856b340ee49ee8", + "d6dbb18d5df5e92c8c74ee59aa86d19dff25a5d0f9d030e84285a686f86804d7", + "65309f82cd9f9926a578d09e1ad13909f68a06d02b853760731a4225f7aecef4", + "433519d13f2b64fe82a90cd054797d4779507fea93c1054bd51c35ba846a0f7f", + "62a55d4d6e4b6f992a1c1840f041585c957affcdbf875202cf9e1db9def05aeb", + "e19eb1eeabdeffa04ccd792eb09776690cf2121887b26a7c5d20d66e3e8fd0fb", + "a80951fc593035abb2dda045a2076d29a30f5cc470e0a20db39c3ec588ed61d8", + "4f1b39906714266a7a1936bfa8e08c5d891285dd2b188b4bcd4afb0107671004", + "f46310b2e60727af071d09e759814f52f933688a0ff0995c7da373b381e70005", + "2cc94821f56d21918ba4f2770d97f280e06fd99f4199167e2f4ddc780f404c8a", + "698a2ca7a09e88fa6594801da037f4dbce6ae841d1d33736aebcf8f6fe104e01", +]; diff --git a/src/lib/samples.js b/src/lib/samples.js deleted file mode 100644 index 17e4f4c8..00000000 --- a/src/lib/samples.js +++ /dev/null @@ -1,89 +0,0 @@ -import { PUBLIC_DOMAIN, PUBLIC_COINOS_URL } from "$env/static/public"; - -let api = PUBLIC_DOMAIN.includes("localhost") - ? `${PUBLIC_COINOS_URL}` - : `https://${PUBLIC_DOMAIN}/api`; - -export default { - register: `curl "${api}/register" -H "content-type: application/json" -d '{ - "user": { - "username": "demo", - "password": "hunter2" - } -}'`, - login: `curl "${api}/login" -H "content-type: application/json" -d '{ - "username": "demo", - "password": "hunter2" -}'`, - payments: `curl "${api}/payments" - -H "content-type: application/json" - -H "Authorization: Bearer $token" -`, - lightning: `curl "${api}/payments" - -H "content-type: application/json" - -H "Authorization: Bearer $token" - -d '{ - "payreq": "lnbc1pj94d8fsp5n77k340ps4m9jn7kp8he8yynpddvurv6mcsrrqpnq5l2jxdxzlwqpp5m96pqhc5nrlk8cqsu9ufdxxa43sarp8vwf9egvm2pg9nl0zu9r8qdq2vdhkjmn0wvxqztgcqpjrzjqwhmav82kntsppmkp8jp4vg4h9nns78tsy8mg7ve4lq5txrkp0h56zlarvqqdtcqqsqqqqqqqqqqp6cq9q9qyysgqzxlypywzphyujm3ga5j5csfcmqvlnae0fgnvymkaaw94eeg7py5rqzysyjkr3ev2snq63qpsc69vf54adkd0szvmvwt5cuadjnuy95sq4xfa40" -}'`, - bitcoin: `curl "${api}/bitcoin/send" - -H "content-type: application/json" - -H "Authorization: Bearer $token" - -d '{ - "amount": 5000, - "address": "bc1q3unh97w4rmelflrm2hvdwz37d8kray3vn4d5ca" -}'`, - internal: `curl "${api}/send" - -H "content-type: application/json" - -H "Authorization: Bearer $token" - -d '{ - "amount": 5000, - "username": "alice" -}'`, - rates: `curl "${api}/rates" - -H "content-type: application/json" -}'`, - lightningInvoice: `curl "${api}/invoice" - -H "content-type: application/json" - -H "Authorization: Bearer $token" - -d '{ - "invoice": { - "amount": 1000, - "type": "lightning" - } -}'`, - bitcoinAddress: `curl "${api}/invoice" - -H "content-type: application/json" - -H "Authorization: Bearer $token" - -d '{ - "invoice": { - "amount": 3141, - "type": "bitcoin" - } -}'`, - webhook: `curl "${api}/invoice" - -H "content-type: application/json" - -H "Authorization: Bearer $token" - -d '{ - "invoice": { - "type": "lightning", - "webhook": "https://example.com/payment/received", - "secret": "webhooksecret" - } -}'`, - fetchInvoice: `curl "${api}/invoice/bc1qmhfk9stzffhd9umzmld92vff7zg3mdlh7rvvaj" - -H "content-type: application/json"'`, - invoiceResponse: `{ - "amount":3141 - "tip":0 - "type":"bitcoin" - "prompt":false - "rate":31836.9702667 - "hash":"bc1qmhfk9stzffhd9umzmld92vff7zg3mdlh7rvvaj" - "text":"bitcoin:bc1qmhfk9stzffhd9umzmld92vff7zg3mdlh7rvvaj?amount=0.00003141" - "currency":"CAD" - "uid":"a9770421-3f65-11ed-9f57-0242ac2a0004" - "received":0 - "created":1677537428134 -}`, - socketAuth: `echo '{"type":"login","data":{"username":"user","password":"password"}}' | websocat -n https://coinos.io/ws`, -}; diff --git a/src/lib/samples.ts b/src/lib/samples.ts new file mode 100644 index 00000000..17e4f4c8 --- /dev/null +++ b/src/lib/samples.ts @@ -0,0 +1,89 @@ +import { PUBLIC_DOMAIN, PUBLIC_COINOS_URL } from "$env/static/public"; + +let api = PUBLIC_DOMAIN.includes("localhost") + ? `${PUBLIC_COINOS_URL}` + : `https://${PUBLIC_DOMAIN}/api`; + +export default { + register: `curl "${api}/register" -H "content-type: application/json" -d '{ + "user": { + "username": "demo", + "password": "hunter2" + } +}'`, + login: `curl "${api}/login" -H "content-type: application/json" -d '{ + "username": "demo", + "password": "hunter2" +}'`, + payments: `curl "${api}/payments" + -H "content-type: application/json" + -H "Authorization: Bearer $token" +`, + lightning: `curl "${api}/payments" + -H "content-type: application/json" + -H "Authorization: Bearer $token" + -d '{ + "payreq": "lnbc1pj94d8fsp5n77k340ps4m9jn7kp8he8yynpddvurv6mcsrrqpnq5l2jxdxzlwqpp5m96pqhc5nrlk8cqsu9ufdxxa43sarp8vwf9egvm2pg9nl0zu9r8qdq2vdhkjmn0wvxqztgcqpjrzjqwhmav82kntsppmkp8jp4vg4h9nns78tsy8mg7ve4lq5txrkp0h56zlarvqqdtcqqsqqqqqqqqqqp6cq9q9qyysgqzxlypywzphyujm3ga5j5csfcmqvlnae0fgnvymkaaw94eeg7py5rqzysyjkr3ev2snq63qpsc69vf54adkd0szvmvwt5cuadjnuy95sq4xfa40" +}'`, + bitcoin: `curl "${api}/bitcoin/send" + -H "content-type: application/json" + -H "Authorization: Bearer $token" + -d '{ + "amount": 5000, + "address": "bc1q3unh97w4rmelflrm2hvdwz37d8kray3vn4d5ca" +}'`, + internal: `curl "${api}/send" + -H "content-type: application/json" + -H "Authorization: Bearer $token" + -d '{ + "amount": 5000, + "username": "alice" +}'`, + rates: `curl "${api}/rates" + -H "content-type: application/json" +}'`, + lightningInvoice: `curl "${api}/invoice" + -H "content-type: application/json" + -H "Authorization: Bearer $token" + -d '{ + "invoice": { + "amount": 1000, + "type": "lightning" + } +}'`, + bitcoinAddress: `curl "${api}/invoice" + -H "content-type: application/json" + -H "Authorization: Bearer $token" + -d '{ + "invoice": { + "amount": 3141, + "type": "bitcoin" + } +}'`, + webhook: `curl "${api}/invoice" + -H "content-type: application/json" + -H "Authorization: Bearer $token" + -d '{ + "invoice": { + "type": "lightning", + "webhook": "https://example.com/payment/received", + "secret": "webhooksecret" + } +}'`, + fetchInvoice: `curl "${api}/invoice/bc1qmhfk9stzffhd9umzmld92vff7zg3mdlh7rvvaj" + -H "content-type: application/json"'`, + invoiceResponse: `{ + "amount":3141 + "tip":0 + "type":"bitcoin" + "prompt":false + "rate":31836.9702667 + "hash":"bc1qmhfk9stzffhd9umzmld92vff7zg3mdlh7rvvaj" + "text":"bitcoin:bc1qmhfk9stzffhd9umzmld92vff7zg3mdlh7rvvaj?amount=0.00003141" + "currency":"CAD" + "uid":"a9770421-3f65-11ed-9f57-0242ac2a0004" + "received":0 + "created":1677537428134 +}`, + socketAuth: `echo '{"type":"login","data":{"username":"user","password":"password"}}' | websocat -n https://coinos.io/ws`, +}; diff --git a/src/lib/socket.js b/src/lib/socket.js deleted file mode 100644 index 98d42ead..00000000 --- a/src/lib/socket.js +++ /dev/null @@ -1,92 +0,0 @@ -import { navigating } from "$app/stores"; -import { get } from "svelte/store"; -import { event, invoice, request, newPayment, last } from "$lib/store"; -import { success, sat, sleep } from "$lib/utils"; -import { PUBLIC_SOCKET } from "$env/static/public"; -import { invalidate } from "$app/navigation"; -import { browser } from "$app/environment"; - -let socket, token; - -export const auth = () => token && send("login", token); - -export const send = (type, data) => { - socket?.readyState === 1 && socket.send(JSON.stringify({ type, data })); - return true; -}; - -export const messages = (data) => ({ - id() { - last.set(Date.now()); - }, - invoice() { - invoice.set(data); - }, - event() { - event.set(data); - }, - - request() { - request.set(data); - invalidate("app:invoice"); - }, - - async payment() { - let { amount, confirmed } = data; - - invalidate("app:user"); - invalidate("app:invoice"); - invalidate("app:payments"); - - if (amount > 0) { - success(`${confirmed ? "Received" : "Detected"} ${sat(amount)}!`); - } - }, - - connected: auth, -}); - -const initialReconnectDelay = 1000; -const maxReconnectDelay = 16000; - -let currentReconnectDelay = initialReconnectDelay; - -export function connect(t) { - token = t; - - if (socket) return auth(); - - socket = new WebSocket(PUBLIC_SOCKET); - socket.addEventListener("open", onWebsocketOpen); - socket.addEventListener("close", onWebsocketClose); - socket.addEventListener("message", onWebsocketMessage); -} - -export function close() { - if (socket) socket.close(); -} - -async function onWebsocketMessage(msg) { - let { type, data } = JSON.parse(msg.data); - if (get(navigating)) await sleep(2000); - - messages(data)[type] && messages(data)[type](); -} - -function onWebsocketOpen() { - currentReconnectDelay = initialReconnectDelay; -} - -function onWebsocketClose() { - socket = null; - setTimeout(() => { - reconnectToWebsocket(); - }, currentReconnectDelay + Math.floor(Math.random() * 3000)); -} - -function reconnectToWebsocket() { - if (currentReconnectDelay < maxReconnectDelay) { - currentReconnectDelay *= 2; - } - connect(token); -} diff --git a/src/lib/socket.ts b/src/lib/socket.ts new file mode 100644 index 00000000..98d42ead --- /dev/null +++ b/src/lib/socket.ts @@ -0,0 +1,92 @@ +import { navigating } from "$app/stores"; +import { get } from "svelte/store"; +import { event, invoice, request, newPayment, last } from "$lib/store"; +import { success, sat, sleep } from "$lib/utils"; +import { PUBLIC_SOCKET } from "$env/static/public"; +import { invalidate } from "$app/navigation"; +import { browser } from "$app/environment"; + +let socket, token; + +export const auth = () => token && send("login", token); + +export const send = (type, data) => { + socket?.readyState === 1 && socket.send(JSON.stringify({ type, data })); + return true; +}; + +export const messages = (data) => ({ + id() { + last.set(Date.now()); + }, + invoice() { + invoice.set(data); + }, + event() { + event.set(data); + }, + + request() { + request.set(data); + invalidate("app:invoice"); + }, + + async payment() { + let { amount, confirmed } = data; + + invalidate("app:user"); + invalidate("app:invoice"); + invalidate("app:payments"); + + if (amount > 0) { + success(`${confirmed ? "Received" : "Detected"} ${sat(amount)}!`); + } + }, + + connected: auth, +}); + +const initialReconnectDelay = 1000; +const maxReconnectDelay = 16000; + +let currentReconnectDelay = initialReconnectDelay; + +export function connect(t) { + token = t; + + if (socket) return auth(); + + socket = new WebSocket(PUBLIC_SOCKET); + socket.addEventListener("open", onWebsocketOpen); + socket.addEventListener("close", onWebsocketClose); + socket.addEventListener("message", onWebsocketMessage); +} + +export function close() { + if (socket) socket.close(); +} + +async function onWebsocketMessage(msg) { + let { type, data } = JSON.parse(msg.data); + if (get(navigating)) await sleep(2000); + + messages(data)[type] && messages(data)[type](); +} + +function onWebsocketOpen() { + currentReconnectDelay = initialReconnectDelay; +} + +function onWebsocketClose() { + socket = null; + setTimeout(() => { + reconnectToWebsocket(); + }, currentReconnectDelay + Math.floor(Math.random() * 3000)); +} + +function reconnectToWebsocket() { + if (currentReconnectDelay < maxReconnectDelay) { + currentReconnectDelay *= 2; + } + connect(token); +} diff --git a/src/lib/store.js b/src/lib/store.js deleted file mode 100644 index 71d4aa40..00000000 --- a/src/lib/store.js +++ /dev/null @@ -1,59 +0,0 @@ -import { get, writable } from "svelte/store"; -import { browser } from "$app/environment"; - -let persistSession = (key, defaultValue) => { - let s = writable( - browser && - sessionStorage.getItem(key) && - sessionStorage.getItem(key) !== "undefined" - ? JSON.parse(sessionStorage.getItem(key)) - : defaultValue - ); - - s.subscribe((v) => { - browser && sessionStorage.setItem(key, JSON.stringify(v)); - }); - - return s; -}; - -let persistLocal = (key, defaultValue) => { - let s = writable( - browser && - localStorage.getItem(key) && - localStorage.getItem(key) !== "undefined" - ? JSON.parse(localStorage.getItem(key)) - : defaultValue - ); - - s.subscribe((v) => { - try { - browser && localStorage.setItem(key, JSON.stringify(v)); - } catch (e) { - console.log("problem setting key", v); - console.log(e); - } - }); - - return s; -}; - -export let avatar = writable(); -export let banner = writable(); -export let event = writable(); -export let events = writable({}); -export let installPrompt = writable(); -export let invoice = writable(); -export let last = writable(); -export let loginRedirect = writable(); -export let decrypted = persistLocal("decrypted", {}); -export let newPayment = persistLocal("newPayment"); -export let password = writable(); -export let passwordPrompt = writable(); -export let pin = persistLocal("pin"); -export let rate = writable(); -export let request = writable(); -export let requestRedirect = writable(); -export let token = persistSession("token"); -export let ndef = writable(); -export let showQr = persistLocal("showQr", true); diff --git a/src/lib/store.ts b/src/lib/store.ts new file mode 100644 index 00000000..71d4aa40 --- /dev/null +++ b/src/lib/store.ts @@ -0,0 +1,59 @@ +import { get, writable } from "svelte/store"; +import { browser } from "$app/environment"; + +let persistSession = (key, defaultValue) => { + let s = writable( + browser && + sessionStorage.getItem(key) && + sessionStorage.getItem(key) !== "undefined" + ? JSON.parse(sessionStorage.getItem(key)) + : defaultValue + ); + + s.subscribe((v) => { + browser && sessionStorage.setItem(key, JSON.stringify(v)); + }); + + return s; +}; + +let persistLocal = (key, defaultValue) => { + let s = writable( + browser && + localStorage.getItem(key) && + localStorage.getItem(key) !== "undefined" + ? JSON.parse(localStorage.getItem(key)) + : defaultValue + ); + + s.subscribe((v) => { + try { + browser && localStorage.setItem(key, JSON.stringify(v)); + } catch (e) { + console.log("problem setting key", v); + console.log(e); + } + }); + + return s; +}; + +export let avatar = writable(); +export let banner = writable(); +export let event = writable(); +export let events = writable({}); +export let installPrompt = writable(); +export let invoice = writable(); +export let last = writable(); +export let loginRedirect = writable(); +export let decrypted = persistLocal("decrypted", {}); +export let newPayment = persistLocal("newPayment"); +export let password = writable(); +export let passwordPrompt = writable(); +export let pin = persistLocal("pin"); +export let rate = writable(); +export let request = writable(); +export let requestRedirect = writable(); +export let token = persistSession("token"); +export let ndef = writable(); +export let showQr = persistLocal("showQr", true); diff --git a/src/lib/ticket.js b/src/lib/ticket.js deleted file mode 100644 index 73ef7716..00000000 --- a/src/lib/ticket.js +++ /dev/null @@ -1,31 +0,0 @@ -import { auth, get, post } from "$lib/utils"; -import { env } from "$env/dynamic/private"; -import tickets from "$lib/tickets"; - -export const createTicket = async (cookies, username) => { - let { ticket } = await get("/ticket"); - - let { address } = await post( - `/${username}/invoice`, - { invoice: { network: "liquid" }, user: { username } }, - auth(cookies) - ); - - let { asset } = await post( - "/assets", - { - address, - name: `Launch Party Ticket ${ticket}`, - ticker: "LPT", - precision: 0, - asset_amount: "1", - token_amount: 0, - domain: "coinos.io", - filename: tickets[ticket], - }, - { authorization: `Bearer ${env.LAUNCH}` } - ); - - await post("/ticket", { asset }, { authorization: `Bearer ${env.LAUNCH}` }); - return asset; -}; diff --git a/src/lib/ticket.ts b/src/lib/ticket.ts new file mode 100644 index 00000000..73ef7716 --- /dev/null +++ b/src/lib/ticket.ts @@ -0,0 +1,31 @@ +import { auth, get, post } from "$lib/utils"; +import { env } from "$env/dynamic/private"; +import tickets from "$lib/tickets"; + +export const createTicket = async (cookies, username) => { + let { ticket } = await get("/ticket"); + + let { address } = await post( + `/${username}/invoice`, + { invoice: { network: "liquid" }, user: { username } }, + auth(cookies) + ); + + let { asset } = await post( + "/assets", + { + address, + name: `Launch Party Ticket ${ticket}`, + ticker: "LPT", + precision: 0, + asset_amount: "1", + token_amount: 0, + domain: "coinos.io", + filename: tickets[ticket], + }, + { authorization: `Bearer ${env.LAUNCH}` } + ); + + await post("/ticket", { asset }, { authorization: `Bearer ${env.LAUNCH}` }); + return asset; +}; diff --git a/src/lib/tickets.js b/src/lib/tickets.js deleted file mode 100644 index 1f8cbdac..00000000 --- a/src/lib/tickets.js +++ /dev/null @@ -1,52 +0,0 @@ -export default [ - "QmPbFkiXNuaQyfwD4W9GcXP7qWaNd6wFd9KCnJir5mes1J", - "QmPVjvbaMxSJRpDxMLYTdUWQbknej1vYLckBQ2pAgxZgJN", - "QmVasycSFzCYhyXrcvTE7mN3d6W78RFnrhzg5cRF6Dp6Zq", - "QmTmnhjpTBjZdeHwXgT9Dftc3uWMW73qsZpZ5ECrTyiKKZ", - "QmWDBiyVPyFkzUrEdvy7DSJe1rBQpene1m6quKAtyjBP6a", - "QmcxxzQZwgG7SE9QbHNvoTiCi6Dhs9rrz9roqvxm2JQA88", - "Qmd9ThEpXLLHimEzRUWEFrAGLSw5PAHzn2SmwfCnjNLwWt", - "Qmc7pWw1yxc2ARBWitDMYiyPkWK61NsXXU8oYAQwNAvcx1", - "QmX9Hgw1rMFUgBBuq8QfZZDzLjN5xCED19fwFdDeDDqwmr", - "QmconCAyNyaagqKvvfKCbG7Eu8c6vCtkv2ivvxMoFN9YwA", - "QmWbFmvViy5gx4JdD5sw5YJETet4ZQcXtYgijYnrsnSZ3a", - "QmP6QiiJwoqkduZMqdd5e5htHZ4aYHCsvEu7WEEUknKYa5", - "QmefHk8hvBUHsuKugntok5u75Q8i886cnPwsj4LZZB6uWg", - "QmdrSDK5ByYHxc88hfDu8hQgK5XYFpXSfPorUXdyTbE437", - "QmZ6ZycjRzYpsjnLm1Lfgk1fXXDdhcYRkyfmqYJZVGwADy", - "QmSkBxS5yLPjB2VPs89oQRZANsoyodK6s8s52E8GKXr2zt", - "QmSn8TCPwq3UZ1Z4eyko76CvQo2H2Hyef1NGboDQN22m5i", - "QmP6CTH5zrKMzZwtjy7VaK9NXiq4Gw53kmuRjUbJjeovoe", - "QmdwT4yvz9Xf8g3t6irKRoh3Wa7MwRQrcUJckQxyQe1Bc5", - "QmcwuHH3bD5JExqjDvKqRQ3V5xEVGqs94qPNVDzaCqJa5a", - "QmRfVduHwn8sXwSoyfgZpxSi8L7EjP4LMp6fmijo9VApDp", - "Qmc4TGj1Ahbg9HJ9WDXDm2bXsNkT4zRDp8Wdw9wqqdEwuH", - "QmY8uQiHMWA8ztf2wAurNFW7eiTHQEUiLTQ2vGceMwVqz3", - "QmXiXbaD12F4mkbUSQcKhWshkPU4oi29cUawZGnPk86VVU", - "QmZaiAGjvBZBw4suz33s9JQNzY2Kshean2mQQPCa6gKMQe", - "Qme8bDSdzX7tanPYf672xXW8vPdkLkeSLqLzHJqidRXsYJ", - "QmRJirjuUKgh2AMyBF4jNquaXHFPBtDJf3gKFC614hX7qu", - "QmdRoSKSgabcrpekNBPB6T47RBtJnCETYE8ry2a3P37MUe", - "QmXoqArruHSghrUGW35vVQHPknBG5Cj939iWWHHXU3B616", - "QmYCxtDuoHLMAFhNpifUsLU9ptAeFKwyxSiSEJhDQLMZtN", - "QmQZQBw8wgzUsrmVDEejdePK23AEJbk9aUracvxLPyHz2x", - "QmSsbu7U3i62AQKuYqfisRo5E6nqdMZfHRKWYJgouaXDxD", - "QmaP4adVQuWyqtN4QCXeYXj4nr19Je4EqsaTG1zM9ywqFS", - "QmPPsvgfXsiN3wNqdAwHAhQVpw6SZWNpry9Na6R2Xb7zXY", - "QmR7z6wQmcfZUvRsVK83GRRboyvwZEDQujLwumMY33nAit", - "QmQXgkgorDLPUyQpFbW8aLUW6jioQjUKamtXw5UuNCttDg", - "QmcwYBeXt1BPfdSrtSrXFpWctRZ7RDHvmKTttC5hPPTSzG", - "QmTUexZnw3xPy3YVdUsqJALwTvy2qFax5b3QpJVMvTCJQb", - "QmNLkYXFUvctpfeeDTZxruZE2f834EUnYMM6JJUeTcUB4J", - "QmT7544UaTPgKFYMCpPE4unXphNGX71BLZBPKLkxAijSmj", - "QmTpVR4dqX1QV4fae5pZ1ACtRcANHwEWCLwpMXFmwE95Sm", - "Qmdfyps5fW8d8wstXMfpvpei2DTmaADBWgmxLT7e7uan4P", - "QmUSK8byipYoG3H97QpmPrHw9vYrvHygyhkiM81XmaKyxS", - "QmQUGRvp96LTw5i8Ly9f5LoMvUpeQHCLGNqC88KV74wEHK", - "Qma693TFLh9Z1MeBFzhPHi6Yk4tmTcZY2jogwJ8cPkU2B4", - "QmNu8FyMpmkFdbCXGRVG8mKJtMvvCoLP8LNzFsxBQwxQeS", - "QmWZHE87PKujL1MGLuFgP3D12o5GQxYbvbeTRgr12f1XMu", - "QmcZJn8gPGd3poS9yuiNJh6iP4cn9uy5fnypky71r4sSSw", - "QmTwrAF4E9ucpdnrUZFj6EfrQamGv7Qyn7ceSx1DUQYceC", - "QmexssxU5iTXypgNqrmrQwMDJnTNxyZUxor5wDLnwb5TZp", -]; diff --git a/src/lib/tickets.ts b/src/lib/tickets.ts new file mode 100644 index 00000000..1f8cbdac --- /dev/null +++ b/src/lib/tickets.ts @@ -0,0 +1,52 @@ +export default [ + "QmPbFkiXNuaQyfwD4W9GcXP7qWaNd6wFd9KCnJir5mes1J", + "QmPVjvbaMxSJRpDxMLYTdUWQbknej1vYLckBQ2pAgxZgJN", + "QmVasycSFzCYhyXrcvTE7mN3d6W78RFnrhzg5cRF6Dp6Zq", + "QmTmnhjpTBjZdeHwXgT9Dftc3uWMW73qsZpZ5ECrTyiKKZ", + "QmWDBiyVPyFkzUrEdvy7DSJe1rBQpene1m6quKAtyjBP6a", + "QmcxxzQZwgG7SE9QbHNvoTiCi6Dhs9rrz9roqvxm2JQA88", + "Qmd9ThEpXLLHimEzRUWEFrAGLSw5PAHzn2SmwfCnjNLwWt", + "Qmc7pWw1yxc2ARBWitDMYiyPkWK61NsXXU8oYAQwNAvcx1", + "QmX9Hgw1rMFUgBBuq8QfZZDzLjN5xCED19fwFdDeDDqwmr", + "QmconCAyNyaagqKvvfKCbG7Eu8c6vCtkv2ivvxMoFN9YwA", + "QmWbFmvViy5gx4JdD5sw5YJETet4ZQcXtYgijYnrsnSZ3a", + "QmP6QiiJwoqkduZMqdd5e5htHZ4aYHCsvEu7WEEUknKYa5", + "QmefHk8hvBUHsuKugntok5u75Q8i886cnPwsj4LZZB6uWg", + "QmdrSDK5ByYHxc88hfDu8hQgK5XYFpXSfPorUXdyTbE437", + "QmZ6ZycjRzYpsjnLm1Lfgk1fXXDdhcYRkyfmqYJZVGwADy", + "QmSkBxS5yLPjB2VPs89oQRZANsoyodK6s8s52E8GKXr2zt", + "QmSn8TCPwq3UZ1Z4eyko76CvQo2H2Hyef1NGboDQN22m5i", + "QmP6CTH5zrKMzZwtjy7VaK9NXiq4Gw53kmuRjUbJjeovoe", + "QmdwT4yvz9Xf8g3t6irKRoh3Wa7MwRQrcUJckQxyQe1Bc5", + "QmcwuHH3bD5JExqjDvKqRQ3V5xEVGqs94qPNVDzaCqJa5a", + "QmRfVduHwn8sXwSoyfgZpxSi8L7EjP4LMp6fmijo9VApDp", + "Qmc4TGj1Ahbg9HJ9WDXDm2bXsNkT4zRDp8Wdw9wqqdEwuH", + "QmY8uQiHMWA8ztf2wAurNFW7eiTHQEUiLTQ2vGceMwVqz3", + "QmXiXbaD12F4mkbUSQcKhWshkPU4oi29cUawZGnPk86VVU", + "QmZaiAGjvBZBw4suz33s9JQNzY2Kshean2mQQPCa6gKMQe", + "Qme8bDSdzX7tanPYf672xXW8vPdkLkeSLqLzHJqidRXsYJ", + "QmRJirjuUKgh2AMyBF4jNquaXHFPBtDJf3gKFC614hX7qu", + "QmdRoSKSgabcrpekNBPB6T47RBtJnCETYE8ry2a3P37MUe", + "QmXoqArruHSghrUGW35vVQHPknBG5Cj939iWWHHXU3B616", + "QmYCxtDuoHLMAFhNpifUsLU9ptAeFKwyxSiSEJhDQLMZtN", + "QmQZQBw8wgzUsrmVDEejdePK23AEJbk9aUracvxLPyHz2x", + "QmSsbu7U3i62AQKuYqfisRo5E6nqdMZfHRKWYJgouaXDxD", + "QmaP4adVQuWyqtN4QCXeYXj4nr19Je4EqsaTG1zM9ywqFS", + "QmPPsvgfXsiN3wNqdAwHAhQVpw6SZWNpry9Na6R2Xb7zXY", + "QmR7z6wQmcfZUvRsVK83GRRboyvwZEDQujLwumMY33nAit", + "QmQXgkgorDLPUyQpFbW8aLUW6jioQjUKamtXw5UuNCttDg", + "QmcwYBeXt1BPfdSrtSrXFpWctRZ7RDHvmKTttC5hPPTSzG", + "QmTUexZnw3xPy3YVdUsqJALwTvy2qFax5b3QpJVMvTCJQb", + "QmNLkYXFUvctpfeeDTZxruZE2f834EUnYMM6JJUeTcUB4J", + "QmT7544UaTPgKFYMCpPE4unXphNGX71BLZBPKLkxAijSmj", + "QmTpVR4dqX1QV4fae5pZ1ACtRcANHwEWCLwpMXFmwE95Sm", + "Qmdfyps5fW8d8wstXMfpvpei2DTmaADBWgmxLT7e7uan4P", + "QmUSK8byipYoG3H97QpmPrHw9vYrvHygyhkiM81XmaKyxS", + "QmQUGRvp96LTw5i8Ly9f5LoMvUpeQHCLGNqC88KV74wEHK", + "Qma693TFLh9Z1MeBFzhPHi6Yk4tmTcZY2jogwJ8cPkU2B4", + "QmNu8FyMpmkFdbCXGRVG8mKJtMvvCoLP8LNzFsxBQwxQeS", + "QmWZHE87PKujL1MGLuFgP3D12o5GQxYbvbeTRgr12f1XMu", + "QmcZJn8gPGd3poS9yuiNJh6iP4cn9uy5fnypky71r4sSSw", + "QmTwrAF4E9ucpdnrUZFj6EfrQamGv7Qyn7ceSx1DUQYceC", + "QmexssxU5iTXypgNqrmrQwMDJnTNxyZUxor5wDLnwb5TZp", +]; diff --git a/src/lib/upload.js b/src/lib/upload.js deleted file mode 100644 index 31c235c6..00000000 --- a/src/lib/upload.js +++ /dev/null @@ -1,18 +0,0 @@ -export const upload = async (file, type, progress) => { - let url = `/api/upload/${type}`; - let formData = new FormData(); - formData.append("file", file); - - return new Promise((resolve, reject) => { - let ajax = new XMLHttpRequest(); - ajax.addEventListener("load", () => { - if (ajax.readyState === ajax.DONE) { - if (ajax.status === 200) resolve(ajax.response); - else reject(new Error(`Upload failed: ${ajax.response}`)); - } - }); - ajax.upload.addEventListener("progress", progress, false); - ajax.open("POST", url); - ajax.send(formData); - }); -}; diff --git a/src/lib/upload.ts b/src/lib/upload.ts new file mode 100644 index 00000000..31c235c6 --- /dev/null +++ b/src/lib/upload.ts @@ -0,0 +1,18 @@ +export const upload = async (file, type, progress) => { + let url = `/api/upload/${type}`; + let formData = new FormData(); + formData.append("file", file); + + return new Promise((resolve, reject) => { + let ajax = new XMLHttpRequest(); + ajax.addEventListener("load", () => { + if (ajax.readyState === ajax.DONE) { + if (ajax.status === 200) resolve(ajax.response); + else reject(new Error(`Upload failed: ${ajax.response}`)); + } + }); + ajax.upload.addEventListener("progress", progress, false); + ajax.open("POST", url); + ajax.send(formData); + }); +}; diff --git a/src/lib/utils.js b/src/lib/utils.js deleted file mode 100644 index d6238842..00000000 --- a/src/lib/utils.js +++ /dev/null @@ -1,339 +0,0 @@ -import { browser } from "$app/environment"; -import { toast } from "@zerodevx/svelte-toast"; -import { goto } from "$app/navigation"; -import { PUBLIC_COINOS_URL } from "$env/static/public"; -import { page } from "$app/stores"; -import { get as getStore } from "svelte/store"; - -export function scroll(section) { - if (getStore(page).url.pathname !== "/") goto("/"); - setTimeout(() => section.scrollIntoView({ behavior: "smooth" }), 500); -} - -let base = browser ? "" : PUBLIC_COINOS_URL; - -export let punk = (k) => - Math.floor((parseInt(k.slice(-2), 16) / 256) * 64) + 1 + ".webp"; - -export let g = (url, fetch, headers) => - fetch(base + url, { headers }) - .then((r) => r.text()) - .then((body) => { - try { - return JSON.parse(body); - } catch (e) { - throw new Error(body); - } - }); - -export let get = (url, headers = {}) => { - return fetch(base + url, { headers }) - .then(async (r) => { - if (r.ok) return r.text(); - throw new Error(await r.text()); - }) - .then((body) => { - try { - return JSON.parse(body); - } catch (e) { - return body; - } - }); -}; - -export let post = async (url, body, headers) => { - headers = { - "content-type": "application/json", - accept: "application/json", - ...headers, - }; - - let response = await fetch(base + url, { - method: "POST", - body: JSON.stringify(body), - headers, - }) - .then(async (r) => { - if (r.ok) return r.text(); - let text = await r.text(); - - let message; - try { - ({ message } = JSON.parse(text)); - } catch (e) {} - - if (message) throw new Error(message); - throw new Error(text); - }) - .then((body) => { - try { - body = JSON.parse(body); - } catch (e) { - throw new Error(body); - } - - if (body.error instanceof Error) throw body.error; - if (body instanceof Error) throw body; - if (body.name === "Error") throw new Error(body.message); - - return body; - }); - - return response; -}; - -export let copy = (text) => { - navigator.clipboard.writeText(text); - success("Copied!"); -}; - -export let copyNoNewlines = (text) => { - let stripped = text.replace(/\n/g, " ").replace(/\s+/g, " "); - navigator.clipboard.writeText(stripped); - success("Copied!"); -}; - -export function reverseFormat(val, locale) { - let parts = new Intl.NumberFormat(locale).formatToParts(1111.1); - let group = parts.find((part) => part.type === "group").value; - let decimal = parts.find((part) => part.type === "decimal").value; - let reversedVal = val.replace(new RegExp("\\" + group, "g"), ""); - reversedVal = reversedVal.replace(new RegExp("\\" + decimal, "g"), "."); - return Number.isNaN(reversedVal) ? 0 : +reversedVal; -} - -export let protectedRoutes = [/customers/, /settings/, /payments/]; - -let recent = []; -export let success = (m, clear = true) => { - if (recent.includes(m)) return; - recent.push(m); - setTimeout(() => (recent = []), 5000); - if (clear) toast.pop(); - toast.push(m, { - theme: { - "--toastBarBackground": "#F5F7FA", - }, - }); -}; - -export let warning = (m, clear = true) => { - if (clear) toast.pop(); - toast.push(m, { - theme: { - "--toastBarBackground": "#FFCE22", - }, - }); -}; -export let fail = (m, clear = true) => { - if (clear) toast.pop(); - toast.push(m, { - theme: { - "--toastBarBackground": "#E93535", - }, - }); -}; -export let info = (m) => { - toast.pop(); - toast.push(m, { - theme: { - "--toastBarBackground": "white", - }, - }); -}; - -export let login = async (user, cookies, ip) => { - let maxAge = 380 * 24 * 60 * 60; - - let res = await fetch(base + "/login", { - method: "POST", - body: JSON.stringify(user), - headers: { - "content-type": "application/json", - accept: "application/json", - "cf-connecting-ip": ip, - }, - }); - if (res.status === 401) { - let text = await res.text(); - if (text.startsWith("2fa")) throw new Error("2fa"); - } - - let { user: u, token } = await res.json(); - if (!token) throw new Error("Login failed"); - - let expires = new Date(); - expires.setSeconds(expires.getSeconds() + maxAge); - - let opts = { path: "/", expires }; - if (u.language) cookies.set("lang", u.language, opts); - cookies.set("username", user.username, opts); - cookies.set("token", token, opts); -}; - -export let auth = (cookies) => ({ - authorization: `Bearer ${cookies.get("token")}`, -}); - -export let btc = (fiat, rate) => Math.round((fiat * sats) / rate); -export let fiat = (amount, rate) => (amount * rate) / sats; -export let fd = async (req) => { - let obj = Object.fromEntries(await req.formData()); - for (let k in obj) - (obj[k] === "undefined" && (obj[k] = undefined)) || - (obj[k] === "false" && (obj[k] = false)); - return obj; -}; - -export let f = (s, currency) => { - try { - return new Intl.NumberFormat("en-US", { - style: "currency", - currency, - }) - .format(s) - .replace("CA", ""); - } catch (e) { - return ""; - } -}; - -export let s = (s) => - new Intl.NumberFormat("en-US", { maximumFractionDigits: 0 }).format(s); - -export let sat = (s) => { - s = Math.abs(s); - let p = Math.floor(Math.log(s) / Math.LN10 + 0.000000001); - let d = Math.floor((p + 1) / 3); - - return ( - "⚡️" + - (parseInt(s) > 0 - ? new Intl.NumberFormat("en-US", { maximumFractionDigits: 2 }).format( - s / Math.pow(1000, d) - ) + ["", "K", "M", "G", "T", "P", "E", "Z"][d] - : 0 - ).toString() - ); -}; - -export let sats = 100000000; - -export let back = () => - browser && (history.length ? history.go(-1) : goto("/")); - -export let focus = (el) => - browser && screen.width > 1280 && setTimeout(() => el.focus(), 1); - -export let select = (el) => - browser && screen.width > 1280 && setTimeout(() => el.select(), 1); - -export let sleep = (n) => new Promise((r) => setTimeout(r, n)); -export let wait = async (f, n = 100, s = 300) => { - let i = 0; - while (!(await f()) && i < s) (await sleep(n)) && i++; - if (i >= s) throw new Error("timeout"); - return f(); -}; - -export let stretch = async (password, salt) => - crypto.subtle.deriveKey( - { - name: "PBKDF2", - salt, - iterations: 100000, - hash: "SHA-256", - }, - await crypto.subtle.importKey( - "raw", - new TextEncoder().encode(password), - { name: "PBKDF2" }, - false, - ["deriveBits", "deriveKey"] - ), - { name: "AES-GCM", length: 256 }, - true, - ["encrypt", "decrypt"] - ); - -function get_bigrams(string) { - var s = string.toLowerCase(); - var v = s.split(""); - for (var i = 0; i < v.length; i++) { - v[i] = s.slice(i, i + 2); - } - return v; -} - -export function ss(str1, str2) { - if (str1.length > 0 && str2.length > 0) { - var pairs1 = get_bigrams(str1); - var pairs2 = get_bigrams(str2); - var union = pairs1.length + pairs2.length; - var hits = 0; - for (var x = 0; x < pairs1.length; x++) { - for (var y = 0; y < pairs2.length; y++) { - if (pairs1[x] == pairs2[y]) hit_count++; - } - } - if (hits > 0) return (2.0 * hits) / union; - } - - return 0.0; -} - -export let types = { - bitcoin: "bitcoin", - liquid: "liquid", - lightning: "lightning", - internal: "internal", - fund: "fund", - ecash: "ecash", -}; - -export let ease = (t) => - t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t; - -export function shuffleArray(array) { - for (let i = array.length - 1; i > 0; i--) { - const j = Math.floor(Math.random() * (i + 1)); - [array[i], array[j]] = [array[j], array[i]]; - } -} - -export let closest = (a, n) => - a.reduce((prev, curr) => - Math.abs(curr - n) < Math.abs(prev - n) ? curr : prev - ); - -export let isLiquid = (text) => - text.startsWith("Az") || - text.startsWith("lq1") || - text.startsWith("VJL") || - text.startsWith("VT") || - text.startsWith("XR") || - text.startsWith("XC") || - ((text.startsWith("H") || text.startsWith("G") || text.startsWith("Q")) && - text.length === 34) || - (text.startsWith("ert1q") && text.length === 43) || - (text.startsWith("ex1q") && text.length === 42) || - text.startsWith("el1qq") || - text.startsWith("lq1qq"); - -export function getCookie(name) { - let nameEQ = name + "="; - let ca = document.cookie.split(";"); - for (let i = 0; i < ca.length; i++) { - let c = ca[i]; - while (c.charAt(0) === " ") c = c.substring(1); - if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length); - } - return null; -} - -export function setCookie(name, value, seconds) { - const now = new Date(); - now.setTime(now.getTime() + seconds * 1000); - const expires = "expires=" + now.toUTCString(); - document.cookie = name + "=" + value + ";" + expires + ";path=/"; -} diff --git a/src/lib/utils.ts b/src/lib/utils.ts new file mode 100644 index 00000000..d6238842 --- /dev/null +++ b/src/lib/utils.ts @@ -0,0 +1,339 @@ +import { browser } from "$app/environment"; +import { toast } from "@zerodevx/svelte-toast"; +import { goto } from "$app/navigation"; +import { PUBLIC_COINOS_URL } from "$env/static/public"; +import { page } from "$app/stores"; +import { get as getStore } from "svelte/store"; + +export function scroll(section) { + if (getStore(page).url.pathname !== "/") goto("/"); + setTimeout(() => section.scrollIntoView({ behavior: "smooth" }), 500); +} + +let base = browser ? "" : PUBLIC_COINOS_URL; + +export let punk = (k) => + Math.floor((parseInt(k.slice(-2), 16) / 256) * 64) + 1 + ".webp"; + +export let g = (url, fetch, headers) => + fetch(base + url, { headers }) + .then((r) => r.text()) + .then((body) => { + try { + return JSON.parse(body); + } catch (e) { + throw new Error(body); + } + }); + +export let get = (url, headers = {}) => { + return fetch(base + url, { headers }) + .then(async (r) => { + if (r.ok) return r.text(); + throw new Error(await r.text()); + }) + .then((body) => { + try { + return JSON.parse(body); + } catch (e) { + return body; + } + }); +}; + +export let post = async (url, body, headers) => { + headers = { + "content-type": "application/json", + accept: "application/json", + ...headers, + }; + + let response = await fetch(base + url, { + method: "POST", + body: JSON.stringify(body), + headers, + }) + .then(async (r) => { + if (r.ok) return r.text(); + let text = await r.text(); + + let message; + try { + ({ message } = JSON.parse(text)); + } catch (e) {} + + if (message) throw new Error(message); + throw new Error(text); + }) + .then((body) => { + try { + body = JSON.parse(body); + } catch (e) { + throw new Error(body); + } + + if (body.error instanceof Error) throw body.error; + if (body instanceof Error) throw body; + if (body.name === "Error") throw new Error(body.message); + + return body; + }); + + return response; +}; + +export let copy = (text) => { + navigator.clipboard.writeText(text); + success("Copied!"); +}; + +export let copyNoNewlines = (text) => { + let stripped = text.replace(/\n/g, " ").replace(/\s+/g, " "); + navigator.clipboard.writeText(stripped); + success("Copied!"); +}; + +export function reverseFormat(val, locale) { + let parts = new Intl.NumberFormat(locale).formatToParts(1111.1); + let group = parts.find((part) => part.type === "group").value; + let decimal = parts.find((part) => part.type === "decimal").value; + let reversedVal = val.replace(new RegExp("\\" + group, "g"), ""); + reversedVal = reversedVal.replace(new RegExp("\\" + decimal, "g"), "."); + return Number.isNaN(reversedVal) ? 0 : +reversedVal; +} + +export let protectedRoutes = [/customers/, /settings/, /payments/]; + +let recent = []; +export let success = (m, clear = true) => { + if (recent.includes(m)) return; + recent.push(m); + setTimeout(() => (recent = []), 5000); + if (clear) toast.pop(); + toast.push(m, { + theme: { + "--toastBarBackground": "#F5F7FA", + }, + }); +}; + +export let warning = (m, clear = true) => { + if (clear) toast.pop(); + toast.push(m, { + theme: { + "--toastBarBackground": "#FFCE22", + }, + }); +}; +export let fail = (m, clear = true) => { + if (clear) toast.pop(); + toast.push(m, { + theme: { + "--toastBarBackground": "#E93535", + }, + }); +}; +export let info = (m) => { + toast.pop(); + toast.push(m, { + theme: { + "--toastBarBackground": "white", + }, + }); +}; + +export let login = async (user, cookies, ip) => { + let maxAge = 380 * 24 * 60 * 60; + + let res = await fetch(base + "/login", { + method: "POST", + body: JSON.stringify(user), + headers: { + "content-type": "application/json", + accept: "application/json", + "cf-connecting-ip": ip, + }, + }); + if (res.status === 401) { + let text = await res.text(); + if (text.startsWith("2fa")) throw new Error("2fa"); + } + + let { user: u, token } = await res.json(); + if (!token) throw new Error("Login failed"); + + let expires = new Date(); + expires.setSeconds(expires.getSeconds() + maxAge); + + let opts = { path: "/", expires }; + if (u.language) cookies.set("lang", u.language, opts); + cookies.set("username", user.username, opts); + cookies.set("token", token, opts); +}; + +export let auth = (cookies) => ({ + authorization: `Bearer ${cookies.get("token")}`, +}); + +export let btc = (fiat, rate) => Math.round((fiat * sats) / rate); +export let fiat = (amount, rate) => (amount * rate) / sats; +export let fd = async (req) => { + let obj = Object.fromEntries(await req.formData()); + for (let k in obj) + (obj[k] === "undefined" && (obj[k] = undefined)) || + (obj[k] === "false" && (obj[k] = false)); + return obj; +}; + +export let f = (s, currency) => { + try { + return new Intl.NumberFormat("en-US", { + style: "currency", + currency, + }) + .format(s) + .replace("CA", ""); + } catch (e) { + return ""; + } +}; + +export let s = (s) => + new Intl.NumberFormat("en-US", { maximumFractionDigits: 0 }).format(s); + +export let sat = (s) => { + s = Math.abs(s); + let p = Math.floor(Math.log(s) / Math.LN10 + 0.000000001); + let d = Math.floor((p + 1) / 3); + + return ( + "⚡️" + + (parseInt(s) > 0 + ? new Intl.NumberFormat("en-US", { maximumFractionDigits: 2 }).format( + s / Math.pow(1000, d) + ) + ["", "K", "M", "G", "T", "P", "E", "Z"][d] + : 0 + ).toString() + ); +}; + +export let sats = 100000000; + +export let back = () => + browser && (history.length ? history.go(-1) : goto("/")); + +export let focus = (el) => + browser && screen.width > 1280 && setTimeout(() => el.focus(), 1); + +export let select = (el) => + browser && screen.width > 1280 && setTimeout(() => el.select(), 1); + +export let sleep = (n) => new Promise((r) => setTimeout(r, n)); +export let wait = async (f, n = 100, s = 300) => { + let i = 0; + while (!(await f()) && i < s) (await sleep(n)) && i++; + if (i >= s) throw new Error("timeout"); + return f(); +}; + +export let stretch = async (password, salt) => + crypto.subtle.deriveKey( + { + name: "PBKDF2", + salt, + iterations: 100000, + hash: "SHA-256", + }, + await crypto.subtle.importKey( + "raw", + new TextEncoder().encode(password), + { name: "PBKDF2" }, + false, + ["deriveBits", "deriveKey"] + ), + { name: "AES-GCM", length: 256 }, + true, + ["encrypt", "decrypt"] + ); + +function get_bigrams(string) { + var s = string.toLowerCase(); + var v = s.split(""); + for (var i = 0; i < v.length; i++) { + v[i] = s.slice(i, i + 2); + } + return v; +} + +export function ss(str1, str2) { + if (str1.length > 0 && str2.length > 0) { + var pairs1 = get_bigrams(str1); + var pairs2 = get_bigrams(str2); + var union = pairs1.length + pairs2.length; + var hits = 0; + for (var x = 0; x < pairs1.length; x++) { + for (var y = 0; y < pairs2.length; y++) { + if (pairs1[x] == pairs2[y]) hit_count++; + } + } + if (hits > 0) return (2.0 * hits) / union; + } + + return 0.0; +} + +export let types = { + bitcoin: "bitcoin", + liquid: "liquid", + lightning: "lightning", + internal: "internal", + fund: "fund", + ecash: "ecash", +}; + +export let ease = (t) => + t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t; + +export function shuffleArray(array) { + for (let i = array.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [array[i], array[j]] = [array[j], array[i]]; + } +} + +export let closest = (a, n) => + a.reduce((prev, curr) => + Math.abs(curr - n) < Math.abs(prev - n) ? curr : prev + ); + +export let isLiquid = (text) => + text.startsWith("Az") || + text.startsWith("lq1") || + text.startsWith("VJL") || + text.startsWith("VT") || + text.startsWith("XR") || + text.startsWith("XC") || + ((text.startsWith("H") || text.startsWith("G") || text.startsWith("Q")) && + text.length === 34) || + (text.startsWith("ert1q") && text.length === 43) || + (text.startsWith("ex1q") && text.length === 42) || + text.startsWith("el1qq") || + text.startsWith("lq1qq"); + +export function getCookie(name) { + let nameEQ = name + "="; + let ca = document.cookie.split(";"); + for (let i = 0; i < ca.length; i++) { + let c = ca[i]; + while (c.charAt(0) === " ") c = c.substring(1); + if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length); + } + return null; +} + +export function setCookie(name, value, seconds) { + const now = new Date(); + now.setTime(now.getTime() + seconds * 1000); + const expires = "expires=" + now.toUTCString(); + document.cookie = name + "=" + value + ";" + expires + ";path=/"; +} -- cgit v1.2.3