skip to content
Video cover art for Registering a Data Contract for Dash Incubator - 4a
Video

Registering a Data Contract for Dash Incubator - 4a

Anthony returns to Dash streaming after a brief break to tackle data contracts, but ends up debugging his entire setup from scratch with help from ChatGPT.

Open .md

Episode Description

Anthony returns to Dash streaming after a brief break to tackle data contracts, but ends up debugging his entire setup from scratch with help from ChatGPT.

Episode Summary

Anthony kicks off episode 4 of his Dash Incubator streaming series intending to learn about registering a data contract on the Dash platform. He opens by reflecting on his progress so far, the role ChatGPT has played in generating frontend components across multiple frameworks, and his initial assumption that Dash data contracts function more like database schemas than Ethereum-style smart contracts. However, the planned lesson quickly takes a back seat when his existing scripts begin throwing errors, forcing him to walk through the entire setup process from the beginning. He rebuilds his workflow step by step in a public gist, regenerating wallets, creating identities, topping up testnet funds, and registering names on DPNS, while updating his README documentation along the way. Persistent errors with null results and aborted connections eventually push him to consult ChatGPT, which correctly diagnoses missing null checks and suggests handling client disconnection more gracefully. By the end of the stream, his Express server is running again and resolving identity names successfully, though he never actually reaches the data contract registration he originally planned to cover.

Speakers

  • Anthony Campolo

Chapters

00:00:00 - Welcome Back and AI Reflections

Anthony opens the stream by greeting viewers and explaining his shift to weekend streaming, noting that decentralized crypto projects don't require a Monday-through-Friday schedule. He recaps that this is episode 4 of the series and expresses surprise at how much ground has been covered in just three previous episodes, crediting ChatGPT with writing much of the frontend code for the example apps.

He launches into an extended reflection on the history of artificial intelligence, walking through decades of skepticism about whether machines could match human cognition. He traces the moving goalposts from chess to Go to natural language generation, arguing that ChatGPT represents a genuine leap forward and has been genuinely useful for converting React components into Vue, Svelte, Angular, vanilla JS, Preact, and Solid versions of the same example app.

00:03:31 - Sharing Resources and Repo Tour

Anthony shares the Dash Incubator YouTube channel and his personal GitHub repo where the example code lives. He explains his preference for a single clean monorepo containing all examples, Node scripts, and workflows for interacting with the Dash platform, noting this may eventually move to an official Dash repo but will stay on his account for the foreseeable future.

He recaps what was accomplished in earlier episodes, walking through how he used the Dash documentation to build Node scripts for creating an identity, generating a wallet with a mnemonic, and registering a name like ajcwebdevtest.dash on the blockchain. He sets up the goal for this episode: tackling data contracts, while acknowledging he'll need to verify his assumptions with Ryan later.

00:09:19 - Understanding Data Contracts

Anthony pulls up the Dash documentation and explores the concept of data contracts, noting his initial frame of reference is Ethereum smart contracts. After reading the explanation that data contracts define the schema of stored data, he concludes this is fundamentally different from Ethereum's programmable contracts and is closer to a database schema or object structure with keys and values.

He praises the Dash documentation structure for closely following the Divio documentation framework with its tutorials, explanations, and references sections. He admits that the visual database diagrams in the docs don't click for him at first glance, and that he needs to actually start writing code before the concepts will solidify in his understanding.

00:12:28 - Initial Setup Problems Begin

Anthony walks through his existing Express server setup, which uses the Dash SDK to initialize a client with environment variables for the network and wallet mnemonic. He decides to make the .env.example file the default to make the project more accessible to anyone copying the repo, then attempts to run the create wallet command to verify everything works out of the box.

The command immediately fails, prompting him to investigate. He discovers that the script is expecting a mnemonic value but something about how null is being passed through process.env is tripping up the SDK. He pulls up his original blog draft tutorial to compare against his current code and try to identify what changed since he last got things working.

00:16:14 - Rebuilding from the Beginning

Anthony decides to start fresh by rebuilding the project from scratch, using his draft tutorial as a guide. He hardcodes the network value to testnet rather than relying on environment variables, then encounters another puzzling error where setting mnemonic to null through process.env still doesn't behave as expected.

He moves the work into a public gist so it will be saveable and trackable online, then walks through creating a fresh package.json, installing the dash and dotenv dependencies, and setting up the gitignore file with appropriate exclusions for node_modules, .env files, and deployment artifacts for Netlify and Vercel.

00:30:35 - Documentation Reorganization

While rebuilding, Anthony realizes his README is missing a proper outline and pauses to add one. He acknowledges that the document has grown unwieldy and will eventually need to be broken into multiple pieces rather than a single article walking through every aspect of the Dash docs.

He converts the outline entries into anchor links and notes that the final sections covering Vercel API routes and Netlify functions are still broken and shouldn't be relied upon. He reorganizes the structure so future readers can navigate to specific sections, then returns to executing the rebuild step by step from the scripts folder creation onward.

00:36:39 - Wallet and Identity Creation

Anthony successfully runs the block hash and block height retrieval scripts, confirming the basic blockchain reading functionality works. He moves on to creating a fresh wallet, which generates a new mnemonic and address that he saves into his environment variables for use in subsequent scripts.

He experiments with the skipSynchronizationBeforeHeight option, expressing discomfort with using anything labeled "unsafe" but discovering through trial and error that he may actually need it to avoid orphan chunk errors. He also runs into a "not enough balance" error and remembers he needs to fund his testnet wallet, briefly stepping away to grab testnet Dash from a faucet.

00:42:06 - Testnet Troubles and ChatGPT Rescue

After funding his wallet, Anthony attempts to create an identity but runs into a series of cryptic errors he hasn't seen before. He suspects testnet itself might be having problems rather than his code, and after trying several variations of his configuration without success, he turns to ChatGPT for help diagnosing the issue.

ChatGPT confirms his code looks correct and suggests the issue is likely a temporary testnet failure. After a brief wait, the identity creation succeeds and Anthony retrieves his identity ID, saves it to the environment file, and proceeds to top up the identity with credits. He notes that he still doesn't fully understand what credits are beyond being smaller increments of Dash.

00:50:23 - Registering a Name on DPNS

With his identity created, Anthony moves on to registering a name on the Dash Platform Name Service. He spots a hardcoded value in his script and refactors it to read from an environment variable called label, matching the terminology used in the actual response object from the Dash SDK.

He registers the name ajcwebdevtest4 to match the episode number, while reflecting that he should probably establish a more consistent naming convention across episodes. He muses about eventually wanting to claim a proper ajcwebdev name but keeping it secret to prevent others from messing with his identity, then commits the fixes back upstream to keep his repo aligned with the gist.

00:55:02 - Server Setup Simplification

Anthony returns to the Express server section and decides to simplify his original npm-run-all setup. Previously he had a single command running both the API server and the React frontend simultaneously, but he's concluded this hides too much complexity and forces a coupling that doesn't make sense given the multiple frontend examples now in the repo.

He strips out the npm-run-all dependency and the combined script, leaving just a single serve command that runs the API server independently. He explains that thinking of the backend and frontend as two separate processes is conceptually cleaner and will be easier for users to understand in the long run, even if it means running two terminal commands instead of one.

01:01:18 - Final Debugging with ChatGPT

Anthony attempts to curl the newly registered name through his Express server and immediately hits a "cannot read property toJSON of null" error. ChatGPT correctly diagnoses that the resolve method is returning null and suggests adding a null check that responds with a 404 status when no identity is found, which Anthony implements.

A subsequent error about an aborted operation prompts ChatGPT to suggest handling client disconnection more gracefully using process.on SIGINT, ensuring the connection isn't closed prematurely between requests. After applying both fixes, Anthony's curl command finally returns successfully, and he wraps up the stream noting that fifty minutes in, everything he had previously written is once again working as expected, even if he never quite got to the data contract registration he originally planned to cover.

Transcript

00:00:10 - Anthony Campolo

Hello, hello everyone. Sorry, at that last moment I realized I hadn't set the correct sound input yet. But yeah, hey, happy Sunday for anyone who's going to be here hanging out with me. I'm going to be getting back into some Dash streaming. I took a week or two off. For things, life, you know how it is. But, um, back now. And, um, yeah, I checked with Ryan. I'm like, can I do this on the weekend? Like, you know, it's a decentralized crypto project, doesn't really seem like it needs to run on a Monday through Friday. And he confirmed that was correct. So yeah, I think I might do more of these on the weekend. You know, my Saturdays and Sundays are usually— I try and keep them pretty open and pretty chill. So I think it'd be a good chance to get an hour or two of some Dash streaming in while I do it. For people who've been following along, this is episode 4. We've covered a lot of ground in just 3 episodes. I was actually pretty shocked with how much I was able to get done. Part of that was due to the magic of ChatGPT writing a lot of the code for me. And we actually met up Monday before last to kind of discuss that. So if you check out the the Dash Incubator channel on YouTube.

00:01:25 - Anthony Campolo

Go ahead and pop a link to that, actually.

00:01:29 - Anthony Campolo

Then you can see that discussion we had. It was really fun. I was super excited to chat about it because I've been, you know, really excited about the world of AI for a long time. And these days, now that it's actually going pretty well finally, because you're like, AI was a joke for 70 years. And then for a long time, it was always like, this is impossible. Human brains are way too complicated. Computers will never be able to do what we do. And then there would be like just these couple nerdy scientists off the bat being like, nah, we can build a thing smarter than us. There's no reason why we couldn't. And they chipped away at, chipped away at, chipped away at it. And had some little wins along the way, you know, winning chess, considered this great intellectual achievement at the time. And then, you know, they built a computer that could beat any humans, like, oh, well, that's because chess didn't actually require intelligence. And then they picked another one, they're like, okay, well, what about Go? Go isn't just intelligence, it requires intuition actually as well. And then they beat that, and they're like, oh, well, you know, that was just a game, I guess. And then they're like, okay, well, what if we could make a computer that could speak English, write novels, write poetry, write a full movie script beginning to end, answer any scientific question you could ask it, and argue morals and ethics? And then that still isn't intelligent, I guess. I don't know. I'm on a rant here, but the point is, I think ChatGPT is pretty cool and pretty useful. And I used it to write most of the front ends for these example apps that we were creating because I wrote a React front end and then had ChatGPT turn that into a Vue component, Svelte component, Angular component, vanilla JS component, and Preact and Solid.

00:03:31 - Anthony Campolo

Yeah, that was all of them. And so first things first, I was going to share this.

00:03:38 - Anthony Campolo

So, this is where you can check out previous episodes of this show along with that ChatGPT conversation. And then let me drop the repo. And all of the fun stuff that I'm building right now is just going on to my GitHub repo— GitHub account right now. This dash.examples. This may end up in an official Dash repo. At some point in time. Not really sure. But for now, this is where they're gonna live and probably will for the foreseeable future. I like having just kind of one clean monorepo with all the examples I'm building along with kind of Node scripts and some workflows of how you can interact with the Dash platform. And yeah, so the first episode I just kind of went through the docs and figured out some Node scripts that I could run in my terminal that would allow me to create an identity. And basically that creates you a wallet with a mnemonic and then use that to create a name, an actual like, you know, and it was ajcwebdevtest.dash. Then that was a name on the blockchain. And this next one, now we're going to start getting into something called a data contract. So I am assuming that this will work kind of like a contract in the sense of how I've always heard this used with blockchains, but I don't know if that's actually true. This may be completely different than an Ethereum contract. We're going to kind of learn as we go, and at some point I'll talk to Ryan and be like, were any of my assumptions correct that I formed while doing this? But let's go ahead and—

00:05:27 - Anthony Campolo

ooh, I need to be able to screen share. Boom, cool, great. And let me move— let me actually, before I start doing all that, do a quick sanity check.

00:05:46 - Anthony Campolo

Great, I just popped up an open window, made sure you could hear me and see me. Everything was good. Seems like we're all good because you never know. I've seen people start streams where they were silent. Those streams are awkward.

00:06:04 - Anthony Campolo

Uh, great. Boom, boom, boom. That happened to one of my co-workers once, actually.

00:06:09 - Anthony Campolo

He was accidentally muted and streamed for like a solid 10 minutes or something.

00:06:17 - Anthony Campolo

Okay, cool. So I showed you this.

00:06:20 - Anthony Campolo

This is Dash Incubator. There's me going live right now.

00:06:25 - Anthony Campolo

If we kick it back to—

00:06:27 - Anthony Campolo

most of the stuff we do here is on the live channel.

00:06:31 - Anthony Campolo

See this?

00:06:32 - Anthony Campolo

This is really nice. I like, I like this cover, the ChatGPT-generated Dash code and a little robot hand. Very nice touch.

00:06:41 - Anthony Campolo

And then here is this repo.

00:06:49 - Anthony Campolo

And if you check out the README, and I'm constantly iterating on this. This is not the final state of this in any sense. This is basically right now the first pass of a basic single-component frontend that lets you basically hit an endpoint. That will then display the information for a certain Dash identity. So, if you wanna check that out, you can go kind of look at the previous two streams that I did where I completely built those out from scratch. And now what I wanna do is I wanna go— so, if we check out actually the Dash docs here. So, there's the tutorial section, and that's what I've been basically following along and using to really build out stuff that I've been doing, and then I'd kind of check out the explanations or the references as need be. By the way, this setup is one of the perfect— like, if I had to show someone how to do Divio docs— they changed the name recently, but you can still find the original here. It's almost to the T, uh, what you got. You basically got tutorials, you got explanations, you got reference. So you got tutorials, explanation, reference. And then the how-to guide is something that I don't think there is. But that's okay. Because I think the tutorial and the how-to guide essentially does the same thing because you do problem orientation that lets you learn. You basically— I think that these two can kind of be combined sometimes. If a tutorial does it right and you have a small enough scope of what you want your thing to be able to do in the first place, then this is good. If you have just a general framework that can build 100 different things, then how-to guides become really important because you wanna show how you do this thing with this thing and this thing with this thing. With a blockchain, it's kind of— there's a certain boundedness to what it's capable of doing. And so you can just have the sum total of kind of the, the problems that you need contained within the tutorial. I really like that. The first one, this was this whole identities and names section we went through. We registered an identity, retrieved an identity, did all those, and those have basically been turned into now these scripts here.

00:09:19 - Anthony Campolo

Cool.

00:09:22 - Anthony Campolo

You can see all the stuff that we've done so far if you just read through that README. And then we have this next big section now, which is going to be contracts and documents. And a data contract, as far as I can tell— let's see, let's read the explanation.

00:09:44 - Anthony Campolo

Have application developer, application user, and data contract registration. Let's see, data contract. Data contracts define the schema of the data it stores.

00:10:04 - Anthony Campolo

Okay, so when I hear contract used in the blockchain sense, I think of Ethereum contracts, and that's my frame of reference here. And it does seem like this is different because with an Ethereum contract, it's a computer program. It's like you write— it's like these— just a Node script or like anything that has any sort of logic you possibly think of can get shoved into a contract. You require a whole programming language for it. This is talking about a schema of data. That sounds like just storage to me. Like you're, you're having some sort of like a blob of an object that has, you know, keys, values, or you have a table with relations, you know, or you have a Prisma schema, you know, that then maps to some sort of underlying representation of one or the other of those two. All of those things to me doesn't imply the need for a whole programming language necessarily and intense logic. So that's my first kind of assumption going into this is that I should not think of this like an Ethereum contract at all. I should think of this more like an object in the database, essentially. So hopefully that's all correct. I'll double-check with Ryan on that. But yes, you know, so this looks like something you see in like a database diagram. You know, you got a whole bunch of boxes and lines connected to boxes, and these things are hard for me to parse at first glance. Usually it's not really how my brain works. I know for some people these visual representations are extremely useful. So, I'm glad it's in here. But for me, I gotta just start writing code. Once I start writing some of this code, this stuff will make a lot more sense to me. But I think I have basically the right idea of what's going on. So, let's take a look. If anyone's jumping in midstream and has not seen anything I've done before, let me kind of walk through this just so we're all on the same page. The kind of core way you can work with this without having to spin up any front ends or anything like that is by running an Express server that I have right here. So, this Express server is taking the Dash.

00:12:28 - Anthony Campolo

Okay.

00:12:28 - Anthony Campolo

So, first, we have the client.

00:12:31 - Anthony Campolo

Yeah.

00:12:32 - Anthony Campolo

So, Yeah, so the API has the Dash client, and what this is doing is this is importing the Dash SDK and is initializing a client. And you need to first set an environment variable here for your network, and then you can start with the wallet address null if you want to generate a new wallet. So, let me actually, I should make that the default.env.

00:13:06 - Anthony Campolo

That way if someone wants to just copy this over, then this command should work out of the box. Let me see if that's the case.

00:13:16 - Anthony Campolo

So, this command will copy over our .env.example to a new .env and then you can run— first you got to do this guy, of course. So this is going to install our dependencies, and then you can create a wallet.

00:13:44 - Anthony Campolo

There's—

00:13:52 - Anthony Campolo

Great. Okay.

00:13:56 - Anthony Campolo

So, that did not work.

00:14:01 - Anthony Campolo

Okay.

00:14:02 - Anthony Campolo

So, out of the box, this is assuming there's a mnemonic. Okay.

00:14:07 - Anthony Campolo

So—

00:14:12 - Anthony Campolo

or is the mnemonic supposed to be null? Not wall address. Yes. Okay, let me go back and see how did this work the first time.

00:14:32 - Anthony Campolo

It's been a couple weeks since I've done this, so refreshing my memory here.

00:14:37 - Anthony Campolo

Um, so testnet mnemonic. Wait, no, this is the one. Mnemonic's supposed to be null. Yeah, that's what I thought. Okay. So let's see. Create wallet.

00:15:05 - Anthony Campolo

Okay.

00:15:06 - Anthony Campolo

So, this is expecting to have— Nope, that's all good. Mnemonic network, mnemonic network, mnemonic network. So that should all be good. Maybe it's because I don't have this.

00:15:27 - Anthony Campolo

Let's see.

00:15:43 - Anthony Campolo

Let me go back to my original how-to. Hold on, actually.

00:15:59 - Anthony Campolo

'Cause I've got the full kind of tutorial I have written for this is still behind my private blog drafts repo.

00:16:14 - Anthony Campolo

So, let me just pull that up. On screen. Do want it.

00:16:22 - Anthony Campolo

Okay.

00:16:24 - Anthony Campolo

Whole thing. Looks like there's at least 1 or 2 people out there watching, so say hey if you want to. Thanks for joining me. Okay, so let's get back to here, here. Okay, so this is actual. All right, so let's kind of— this, this walks it through from the very, very beginning. So the first thing we need to have is, yeah, so network will be testnet. And then it's just like that. So let's start like that, 'cause—

00:17:35 - Anthony Campolo

okay, and then you should be able to— I get this over here. Yep.

00:17:52 - Anthony Campolo

And so let's just start with that. Should override this. So now we're just looking at network.testnet. The client should just look like that. Let's see what happens then. And then now we should be able to run this guy. So let's go to this part. Okay, so that's like that. And, okay, actually we'll run this create wallet. This should work. So something was screwy with my process.env. So if that works, should be able to do this, unless I spelled mnemonic wrong or something. Might have been actually something stupid like that. Is that actually spelled right? Mnemonica. One more time. Joys of programming sometimes, all right?

00:19:58 - Anthony Campolo

Okay, so.

00:20:01 - Anthony Campolo

Now I should still be able to create a wallet like that.

00:20:08 - Anthony Campolo

That's interesting. For some reason doesn't like that.

00:20:15 - Anthony Campolo

Does not like the way null is coming in. I don't know why that is. Let's see.

00:20:26 - Anthony Campolo

Okay, I can't account for that, so I'm just gonna move on.

00:20:30 - Anthony Campolo

So let's take this.

00:20:38 - Anthony Campolo

So now we got a new identity.

00:20:42 - Anthony Campolo

I got us a little bit off track, but I think we should be good now. So let's just put this here. Hang on to that. We can save this right here.

00:21:00 - Anthony Campolo

Okay.

00:21:01 - Anthony Campolo

So, now what we want to do is we want to cut this off.

00:21:16 - Anthony Campolo

And now this is using the Express server we created and is going to give us a— we feed it a name, and so that'll be the identity on the, the Dash DPNS, I think it is.

00:21:39 - Anthony Campolo

Let's see, what was it? It's the—

00:21:50 - Anthony Campolo

this one. Dash Platform Name Service, DPNS, yeah.

00:21:54 - Anthony Campolo

So, it has a name on DPNS and then we resolve that and basically give you all its information.

00:22:04 - Anthony Campolo

So, if we now go to—

00:22:06 - Anthony Campolo

oops.

00:22:07 - Anthony Campolo

I can't contain my Windows right now. Okay, so this, this thing's supposed to be like that. Oh, like that.

00:22:18 - Anthony Campolo

There we go.

00:22:19 - Anthony Campolo

And then this one is supposed to be like that.

00:22:23 - Anthony Campolo

There we go.

00:22:24 - Anthony Campolo

Okay, sorry folks, getting back into the swing of streaming is always fun.

00:22:34 - Anthony Campolo

Okay, now I should be able to do this, and it's gonna give me an error.

00:22:44 - Anthony Campolo

Interesting. Can't read property of null. Okay. Go back to my tutorial here. Might be because I messed up these things.

00:23:21 - Anthony Campolo

Yeah.

00:23:22 - Anthony Campolo

So there's the tutorial.

00:23:26 - Anthony Campolo

I don't think fully took into account where these ended up. I should probably fix that right now actually.

00:23:35 - Anthony Campolo

'Cause there's, I broke up the clients into two client folders.

00:23:40 - Anthony Campolo

So, we have this one which is API client.js. And then there's this one which is scripts client.js. That's why this is breaking right now. Scripts.Client.js is this. This holds this, but we want that. Also want API.Client.js, which is actually in this example here. Great, great. So then this should actually work now, I think. Back off again. Okay, I'm still messing this up somehow. Let me— back the way it was.

00:25:14 - Anthony Campolo

This is for a second.

00:25:24 - Anthony Campolo

Let me just do this, from the beginning.

00:25:37 - Anthony Campolo

Always the best way to problem check a thing is just run through from the top to see where it breaks and then fix it and go from there.

00:25:50 - Anthony Campolo

This gist, I haven't looked at this tutorial in a couple weeks anyway, so probably use fresh run through. And let me just do that right now, going to get the README in there. Okay, so now this is what we got here. I'm gonna just grab this thing. I should just put this in the gist right now. One more time. Sorry, folks. I'm always wary of leaking information. Could be a public gist. Okay. So, now this will actually be somewhere shareable and saveable and out in the world, and I can start tracking it a little bit cleaner. Okay, so if anyone does wanna follow along with the actual what's happening right now, here is the gist. Okay, so.

00:28:14 - Anthony Campolo

Cool. Okay. So, what I've done so far is created a new project and initialized a package.json, installed two dependencies, the dash dependency and the .env dependency, created a README, and then a .gitignore with the following things: .ds_store, node_modules, .env, And then if we end up building some sort of static frontend, it'll go into a dist folder. And then .netlify, .vercel for when this inevitably gets deployed to Netlify. And then I grabbed this package.json thing that just fills in a name, description, keywords, author, license. Sets the type to module for ESM.

00:29:09 - Anthony Campolo

Okay, that is an issue right there. This does not have .env in it. Great, great, great, great.

00:29:42 - Anthony Campolo

Okay. Now, after doing that, we're going to make a folder called scripts.

00:29:56 - Anthony Campolo

And we also are going to want a folder called API. So there needs to be the API/client.js.

00:30:28 - Anthony Campolo

After backend.

00:30:30 - Anthony Campolo

I created an outline yet.

00:30:34 - Anthony Campolo

Okay, there's not an outline yet.

00:30:35 - Anthony Campolo

That is why it is hard for me to parse what's going on here. Let me do that right now and you can see the very absurd way I go about doing that. So we've got this README here. And what we're going to want, we're going to want all of these. It's the type of exercise that I know I could get some sort of script to figure out how to do this for me.

00:31:26 - Anthony Campolo

Actually, so the most foolproof way is to just do this.

00:31:31 - Anthony Campolo

Error. Let's see how.

00:31:47 - Anthony Campolo

This thing is already pretty dang lengthy from all the stuff I've done in these couple streams. So, eventually it's gonna make sense to not have this in just one giant README. 'Cause I don't think I'm gonna want a single article that goes through the entirety of the Dash docs.

00:32:07 - Anthony Campolo

I may wanna end up breaking this up into a couple pieces.

00:32:10 - Anthony Campolo

For now, I'm going to keep it all straight in my head. This is all just one giant README file that basically sequentially walks through every single thing I've done in the Dash examples repo up to creating the React and Vue ones.

00:32:28 - Anthony Campolo

The rest of the frontends aren't in this yet 'cause I kind of broke off and just started working on the examples repo and stopped working on trying it in this README. But if we see now, we can get a better sense of the whole, whole shebang. There we go. Introduction. These we can probably just get rid of, honestly, 'cause as Ryan was telling me, this endpoint is eventually going to go away, I think. So, let's get rid of this section. Cool. Okay, then we got to turn them all into links. Oops.

00:34:23 - Anthony Campolo

Okay.

00:34:54 - Anthony Campolo

This part is the most tedious part. The last couple sections here don't actually work.

00:35:41 - Anthony Campolo

The Vercel API route and Netlify function part is still broken.

00:35:48 - Anthony Campolo

Don't go to that section expecting it to work. Killer.

00:35:54 - Anthony Campolo

All right, great.

00:35:57 - Anthony Campolo

Good, good, good. Okay, so let's go back to walking through this. So we were at the section right after we made the scripts folder. Yep, right here.

00:36:39 - Anthony Campolo

Great.

00:36:41 - Anthony Campolo

And then this and the .env. Grab this, plug it in there. These little scripts. These are just reading from the blockchain, so they don't do much fancy stuff, but it should be pretty easy to get working.

00:37:06 - Anthony Campolo

Actually, this—

00:37:28 - Anthony Campolo

So that was get block hash, then this is get block by height.

00:37:41 - Anthony Campolo

Great, great. And get block hash.

00:37:56 - Anthony Campolo

So all three of those work.

00:37:58 - Anthony Campolo

That's good. Then we now have the create wallet section. So at this point, what is changing is we're adding in this part here.

00:38:16 - Anthony Campolo

And for some reason, setting mnemonic to null with process.env was tripping it up.

00:38:25 - Anthony Campolo

I'm not quite sure why that was. Now have this part, create wallet. And that'll spit us out a new wallet address and mnemonic.

00:38:44 - Anthony Campolo

Grab that, put it there.

00:38:49 - Anthony Campolo

And then now we're going to take this, put this here.

00:38:54 - Anthony Campolo

Now we have the mnemonic in there.

00:38:57 - Anthony Campolo

This is for synchronization. I'm going to see what happens if I don't use this at all. Now we want to create an identity.

00:39:17 - Anthony Campolo

Identity.

00:39:27 - Anthony Campolo

Because even if it takes a little bit longer if I leave this part out, I kind of prefer that just because it takes off this, like, it says right here, unsafe option. I don't like having an unsafe option there if I don't really need it, you know. Makes you feel unsafe. No one wants to feel unsafe. Okay, that's interesting. Why is this? Okay, so maybe that means chain contains orphan chunks. Well, boy-oh. So let's put that back in there. Maybe to be safe, I need the unsafe option.

00:40:13 - Anthony Campolo

Wouldn't that be interesting?

00:40:30 - Anthony Campolo

SPV error. Yeah, this is why I need to have Ryan on here to answer some of these questions, because I don't know if I'll be able to figure out exactly what this error means in a particularly timely manner.

00:40:58 - Anthony Campolo

Interesting.

00:40:58 - Anthony Campolo

Something went wrong. Not enough balance. Okay, that makes sense. That is because I did skip the step where I gave myself money on the testnet. So let me do that.

00:41:24 - Anthony Campolo

Yeah, I get this on HTTPS, guys.

00:41:27 - Anthony Campolo

Come on, come on.

00:41:31 - Anthony Campolo

Okay, got my Dash.

00:41:35 - Anthony Campolo

Hopefully it doesn't take too long to propagate.

00:41:47 - Anthony Campolo

The copyright-free version.

00:42:06 - Anthony Campolo

So if this does work the way it should, I am creating an identity. Oh, I might have actually tried to create identity that already exists though, now that I think about it.

00:42:20 - Anthony Campolo

I don't know. So right now it's just a wallet address, a mnemonic. At what point do you give it a name? Register name, that's right. Okay, what's happening here? Hmm. I feel like this is just testnet breaking right now. Oh, something really terrible happened. Huh. Okay. Let's try taking all these in one by one and just setting this stuff straight in there. So, testnet address. That's not even in there.

00:43:37 - Anthony Campolo

Wait a second.

00:43:58 - Anthony Campolo

Hold please.

00:43:59 - Anthony Campolo

What am I doing wrong here? Okay, I don't think I'm doing anything. Obviously wrong here. This is for sure. Yeah, yeah. Okay, let's just try that. Let's see what that does. This is still breaking. It's definitely not Gix. I do not know what the heck to do next.

00:45:08 - Anthony Campolo

Yeah, I'm throwing a Hail Mary to ChatGPT.

00:45:15 - Anthony Campolo

Uh, let me pop off so I can close my ChatGPT chat history before I do this. Good, it was already closed. Sorry folks, this is not going according to plan.

00:45:45 - Anthony Campolo

That is the way of programming. These are some new error messages I haven't seen before. This makes me think it's not necessarily anything happening in my code, but I'm not sure exactly what is even going on in this. It might be version of Node or—

00:46:02 - Anthony Campolo

okay. Let me just make sure I give it all the context it needs here.

00:46:07 - Anthony Campolo

I'm trying to run create identity.

00:46:11 - Anthony Campolo

I have a script called create identity.

00:46:18 - Anthony Campolo

Yes. Here's the code. Look at that. Great. That was just a little bit of a testnet fall-over problem. I actually feel better though. My code is working just fine. More ChatGPT Hail Mary required.

00:46:46 - Anthony Campolo

Let's close this out.

00:46:48 - Anthony Campolo

Okay, so now we got our identity ID.

00:46:57 - Anthony Campolo

I do hope that wasn't because of the process.env stuff.

00:47:00 - Anthony Campolo

I don't wanna necessarily go and test that again though. So let's just forge on.

00:47:08 - Anthony Campolo

See what happens.

00:47:10 - Anthony Campolo

Okay, so we got our identity. We have an identity ID. Identity ID goes in the .env. Now we want to retrieve the identity.

00:47:24 - Anthony Campolo

Retrieve identity and then retrieve identity.

00:47:37 - Anthony Campolo

Identifier expects buffer. Buffer.

00:48:01 - Anthony Campolo

Okay, it is not liking this process.env. Oh, actually, it's because I—

00:48:07 - Anthony Campolo

whoops, probably why that just happened.

00:48:21 - Anthony Campolo

Ah, look at that.

00:48:23 - Anthony Campolo

Okay, things are trying to make sense again.

00:48:27 - Anthony Campolo

Great, great.

00:48:28 - Anthony Campolo

So, that all works. Now we can retrieve the identity ID.

00:48:41 - Anthony Campolo

And that's going to give me back my identity ID. While that's going, let me top up the identity. I feel like modifying this number, the synchronization, skip synchronization before block height. I'm curious how much changing that will change the amount of time it takes to run these kind of commands. I tried setting it to 700,000, I think.

00:49:38 - Anthony Campolo

Let's see.

00:49:47 - Anthony Campolo

Because it should— yeah, I wish it was giving me a time readout, but anyway. Let's keep going.

00:50:03 - Anthony Campolo

Okay.

00:50:04 - Anthony Campolo

So, I already did the top-up identity.

00:50:08 - Anthony Campolo

Let's try that now after this goes through. Okay. So, that didn't feel like a big difference in speed.

00:50:23 - Anthony Campolo

The next one is important, though. Now we're at register name. And I should modify this so it's not hardcoded.

00:50:32 - Anthony Campolo

In here, should make it so you have to set it yourself.

00:50:35 - Anthony Campolo

Otherwise, someone blindly following these commands is gonna get tripped up by that.

00:50:52 - Anthony Campolo

This should have another— Ah, and I had done this at one point and I must not have gotten the changes into here.

00:51:03 - Anthony Campolo

'Cause I think this is label is what I ended up calling this. Because if we look at what comes out here, we have label here. So that's why that felt like it made the most sense to me to make this an environment variable called label.

00:51:25 - Anthony Campolo

Where was I?

00:51:43 - Anthony Campolo

Right here. Yeah, register name, label, label. Label, label.

00:51:56 - Anthony Campolo

That should do it. That should do it. Do it to it. All right, there's our identity credit balance.

00:52:04 - Anthony Campolo

Look at that.

00:52:05 - Anthony Campolo

Look at that. I still don't really know what credit is.

00:52:10 - Anthony Campolo

It's Dash in smaller increments, I've been told. Okay, let's make this—

00:52:18 - Anthony Campolo

It's the 4th episode. So, let's give us a new label. Now I should be able to— register name.

00:52:28 - Anthony Campolo

That's the one. Let's see what happens.

00:52:42 - Anthony Campolo

And I got to make sure to upstream it back in.

00:52:45 - Anthony Campolo

Once I verify this code works.

00:52:49 - Anthony Campolo

So, this is now we're registering the name by feeding in a label, which is AJC Web Dev Test 4. I used Dash Stream Test in a previous one. So, not a lot of consistency in naming across what I'm throwing in for these different episodes. In the future, I think I'm gonna try— if I do this from scratch, let's call it whatever the episode is. Eventually I'll want just an AJC Web Dev proper, but that needs to be secret so you hackers can't mess with my identity.

00:53:38 - Anthony Campolo

Great.

00:53:38 - Anthony Campolo

That appears to have worked. And I had already done that. So, that also needs to be fixed. This should be label, not dash name. This is now clean. Okay. Let's get this back in here. Add label as environment variable and give yourself a name on DPNS, and I'll eventually link back to that in the proper place if it wasn't already done earlier.

00:54:52 - Anthony Campolo

Not too concerned with that.

00:54:54 - Anthony Campolo

Right now.

00:54:58 - Anthony Campolo

Okay, that's pretty good. Cool.

00:55:02 - Anthony Campolo

Yeah, this is where stuff gets a little confusing, so you start having multiple moving parts. So now we have a wallet with an address and an identity and a name. So I think a wallet can have multiple identities and thus names.

00:55:25 - Anthony Campolo

Not gonna worry about that right now though. Then fix that, this is in a couple places. Okay, that's, okay, so I broke this already. So let me fix that right now.

00:55:53 - Anthony Campolo

Great, great.

00:55:54 - Anthony Campolo

That should fix that up.

00:55:57 - Anthony Campolo

So now we're going to—

00:56:01 - Anthony Campolo

ooh, ooh, eew. Okay. So I had already figured it out over here.

00:56:10 - Anthony Campolo

Doesn't matter.

00:56:12 - Anthony Campolo

Let me remove that. This is the one thing that is kind of obnoxious about having to do this in a gist, because it's not as easy to navigate around, but this will guarantee I'm not doing things in an editor and then never upstreaming it. This makes actually at least a record of what I'm doing online.

00:56:40 - Anthony Campolo

Okay.

00:56:42 - Anthony Campolo

Great, great, great. So, now let's—

00:56:44 - Anthony Campolo

so, we registered the name.

00:56:46 - Anthony Campolo

That's good. That's good. And then now—

00:56:54 - Anthony Campolo

ah, okay. So, I did—

00:56:56 - Anthony Campolo

no. No, that's all good. Yeah. No, that's all good. Okay. So, now we're gonna retrieve name. Here, and hopefully this will not be broken. Okay, it's giving back null. See if that changes anything. Nope, still null. Interesting. Okay. What I really want is I just want to get this freaking server running. Okay, this is good though. This is making me rework all the stuff I already did.

00:58:50 - Anthony Campolo

Supposedly I've already done all this and this should work, so, but anyone who's done this before knows how it is. It's been a couple weeks. It's been probably a month since I wrote this and already I'm like, what's happening with all this code I wrote?

00:59:10 - Anthony Campolo

Okay.

00:59:14 - Anthony Campolo

So, now what I did is I added these dependencies, which includes Express, CORS, npm run all. Then we're gonna make API folder and then a file called server.js inside the API folder. Now, this is where some weird stuff is gonna happen 'cause I don't actually want any of that.

00:59:37 - Anthony Campolo

I just want the serve command, which it looks like—

00:59:44 - Anthony Campolo

I can actually include here. What the serve command does though is it just runs this API server.

00:59:53 - Anthony Campolo

So, let me fix this.

01:00:00 - Anthony Campolo

Because at one point I was using npm run all to run both the server and the React frontend at the same time. And then I kind of decided just too much complexity and there's all these other frontends anyway. So, we might as well just like make people have to run both of them separately. I think it's actually probably better to think of them as two separate things instead of just running a single command and hiding that complexity. That's gonna just confuse you more in the long run.

01:00:28 - Anthony Campolo

So we get rid of all that crap and this crap, and this is just gonna be a single serve command. Trailing comma. Don't do that. Okay, cool, cool, cool, cool. Great. Now, we should be able to run this. Let's see what happens.

01:01:16 - Anthony Campolo

Oh, God.

01:01:17 - Anthony Campolo

Okay.

01:01:18 - Anthony Campolo

Good.

01:01:18 - Anthony Campolo

That's good.

01:01:23 - Anthony Campolo

And then, we want to be able to curl the name we just created.

01:01:31 - Anthony Campolo

This, but with a 4. Moment of truth right here. Sad face. Hmm, okay. That's interesting. Hmm.

01:02:14 - Anthony Campolo

Okay. Something's breaking for reasons that it's not going to be particularly easy to debug. Something went wrong. Response error. This operation was aborted.

01:02:30 - Anthony Campolo

Houston, we have a problem. Okay.

01:02:37 - Anthony Campolo

Well then.

01:02:41 - Anthony Campolo

Crap.

01:02:42 - Anthony Campolo

Okay.

01:02:42 - Anthony Campolo

So, that's gonna require me rethinking some things. Either in the error handling or just the sequence of steps that led me here. I'm not quite sure what's going on or why it's broken. And that's not good.

01:03:10 - Anthony Campolo

Luckily, I originally did this on stream. So, worst case scenario, I go back and rewatch what I did and see what I'm changing.

01:03:18 - Anthony Campolo

But doesn't—

01:03:19 - Anthony Campolo

I don't see anything obvious right now that should be broken and to cause that. So it may just be another error with testnet, like testnet's taking a crap and then just throwing an error, and that's why it's getting aborted. That was happening early, like it looked like testnet broke earlier on stream, so it's not entirely impossible. At the same time— oh, different error. Okay, that's good. So now it looks like this is testnet crapping out. This is the actual error I'm getting here, which makes sense. This is the error I was getting before.

01:03:55 - Anthony Campolo

So that's a me issue because cannot read property of null reading to JSON. Okay. This might be the moment for ChatGPT. Right now, as I'm giving ChatGPT my server code, I'm saying, here is my Express server with the following code. I'm running this curl command and getting an error. And then it should be able to say, why I'm being dumb. Okay. And then, let me give it this also. It is importing. Oh. Still need to understand what's happening.

01:05:32 - Anthony Campolo

See how that goes.

01:05:46 - Anthony Campolo

Oh, look at that! Okay, it's pretty good. This is pretty good. This is promising. All right, the error message you're seeing is indicating that the object result is null when you're trying to call result.toJSON. I did understand that. This implies that the resolve method is not returning anything for the given identity name.

01:06:05 - Anthony Campolo

Yep.

01:06:06 - Anthony Campolo

So, the resolve method of dash platform names returns a document object so name could be resolved. So, that's, I was like, how does it know that?

01:06:14 - Anthony Campolo

Is that actually true? We'll see.

01:06:16 - Anthony Campolo

Otherwise, it returns null. That's why you're seeing TypeError because result is null. Let's update your Express route to check for null before trying to convert the result to JSON. Now it'll respond with a 404 status code and a helpful error message when no identity is found for a given name.

01:06:33 - Anthony Campolo

That's nice.

01:06:35 - Anthony Campolo

Also, I want to point out that calling client.disconnect in the finally block will close the connection after each request. If you're making frequent requests, you might want to reconsider.

01:06:44 - Anthony Campolo

Um, no, I think I want to That disconnects when your server is shutting down. You know, I need— okay, I'm not sure about that.

01:06:56 - Anthony Campolo

So let's try this now. Okay, change.

01:07:10 - Anthony Campolo

I now get— What do you say, computer person?

01:07:21 - Anthony Campolo

Network-related issues here. Dash— make sure the Dash network you're connecting to, testnet, is available and that you have a proper internet connection.

01:07:30 - Anthony Campolo

Okay, so that makes sense.

01:07:34 - Anthony Campolo

I mentioned this in the previous one. Wow, that's funny. ChatGPT getting a little snarky here. It's possible the client's being disconnected before the response can be properly sent or processed.

01:07:53 - Anthony Campolo

Okay, so here's how your code should look. Let's now try this.

01:08:03 - Anthony Campolo

Now we're adding process.on SIGINT.

01:08:12 - Anthony Campolo

It's also telling me to do something with my catch. Okay, why don't you just give me both of those at once?

01:08:21 - Anthony Campolo

All right.

01:08:23 - Anthony Campolo

This. And let's do— this. So they want me to do that to here. Do this actually. Pulling out of here, ChatGPT. What are you doing?

01:09:09 - Anthony Campolo

Okay, okay, huh, that's interesting. It's strange, there should be an identity found with that name. I for sure created an identity with that name.

01:09:24 - Anthony Campolo

Huh.

01:09:24 - Anthony Campolo

Okay. And now, AJC Web Dev 4 is working.

01:09:29 - Anthony Campolo

I don't know what's happening or why, but it works.

01:09:36 - Anthony Campolo

That was a very confusing sequence of events that I'm not entirely sure what was my error and what was not.

01:09:48 - Anthony Campolo

So, we're gonna pretend like everything's fine and move on with our lives. Now let's go here and see what happens. All right.

01:09:58 - Anthony Campolo

New code. 50 minutes into the stream and everything I previously wrote now works again.

On this pageJump to section