@peerbit/server 3.0.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/lib/esm/aws.browser.d.ts +0 -0
  2. package/lib/esm/aws.browser.js +3 -0
  3. package/lib/esm/aws.browser.js.map +1 -0
  4. package/lib/esm/aws.d.ts +19 -0
  5. package/lib/esm/aws.js +185 -1
  6. package/lib/esm/aws.js.map +1 -1
  7. package/lib/esm/cli.js +592 -324
  8. package/lib/esm/cli.js.map +1 -1
  9. package/lib/esm/client.d.ts +11 -5
  10. package/lib/esm/client.js +64 -11
  11. package/lib/esm/client.js.map +1 -1
  12. package/lib/esm/docker.browser.d.ts +0 -0
  13. package/lib/esm/docker.browser.js +3 -0
  14. package/lib/esm/docker.browser.js.map +1 -0
  15. package/lib/esm/domain.js +1 -1
  16. package/lib/esm/domain.js.map +1 -1
  17. package/lib/esm/peerbit.d.ts +1 -1
  18. package/lib/esm/remotes.d.ts +15 -2
  19. package/lib/esm/remotes.js +8 -8
  20. package/lib/esm/remotes.js.map +1 -1
  21. package/lib/esm/routes.d.ts +3 -2
  22. package/lib/esm/routes.js +5 -4
  23. package/lib/esm/routes.js.map +1 -1
  24. package/lib/esm/server.d.ts +3 -1
  25. package/lib/esm/server.js +32 -19
  26. package/lib/esm/server.js.map +1 -1
  27. package/lib/esm/trust.d.ts +1 -1
  28. package/lib/esm/trust.js.map +1 -1
  29. package/lib/ui/assets/aws.browser-4ed993c7.js +1 -0
  30. package/lib/ui/assets/index-5ed0229d.js +77 -0
  31. package/lib/ui/index.html +1 -1
  32. package/package.json +13 -7
  33. package/src/aws.browser.ts +1 -0
  34. package/src/aws.ts +250 -1
  35. package/src/cli.ts +676 -354
  36. package/src/client.ts +76 -11
  37. package/src/docker.browser.ts +1 -0
  38. package/src/domain.ts +1 -1
  39. package/src/peerbit.ts +1 -1
  40. package/src/remotes.ts +24 -10
  41. package/src/routes.ts +5 -4
  42. package/src/server.ts +43 -23
  43. package/src/trust.ts +1 -1
  44. package/lib/ui/assets/index-cac7195d.js +0 -77
package/lib/ui/index.html CHANGED
@@ -23,7 +23,7 @@
23
23
  Learn how to configure a non-root public URL by running `npm run build`.
24
24
  -->
25
25
  <title>Peerbit</title>
26
- <script type="module" crossorigin src="/assets/index-cac7195d.js"></script>
26
+ <script type="module" crossorigin src="/assets/index-5ed0229d.js"></script>
27
27
  <link rel="stylesheet" href="/assets/index-5265c558.css">
28
28
  </head>
29
29
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peerbit/server",
3
- "version": "3.0.0",
3
+ "version": "4.0.0",
4
4
  "author": "dao.xyz",
5
5
  "repository": {
6
6
  "type": "git",
@@ -23,7 +23,10 @@
23
23
  "./lib/esm/config.js": "./lib/esm/config.browser.js",
24
24
  "./config.js": "./lib/esm/config.browser.js",
25
25
  "./lib/esm/remotes.js": "./lib/esm/remotes.browser.js",
26
- "./remotes.js": "./lib/esm/remotes.browser.js"
26
+ "./remotes.js": "./lib/esm/remotes.browser.js",
27
+ "./lib/esm/docker.js": "./lib/esm/docker.browser.js",
28
+ "./docker.js": "./lib/esm/docker.browser.js",
29
+ "./lib/esm/aws.js": "./lib/esm/aws.browser.js"
27
30
  },
28
31
  "files": [
29
32
  "lib",
@@ -52,22 +55,25 @@
52
55
  },
53
56
  "devDependencies": {
54
57
  "@peerbit/test-lib": "^0.0.1",
55
- "@peerbit/test-utils": "1.0.17",
58
+ "@peerbit/test-utils": "1.0.18",
56
59
  "@types/tmp": "^0.2.3",
57
60
  "@types/yargs": "^17.0.24",
58
61
  "aws-sdk": "^2.1259.0",
59
62
  "dotenv": "^16.1.4"
60
63
  },
61
64
  "dependencies": {
62
- "@aws-sdk/client-route-53": "^3.345.0",
63
- "@dao-xyz/libp2p-noise": "^12.0.1",
65
+ "@dao-xyz/libp2p-noise": "^13.0.1",
64
66
  "axios": "^1.4.0",
65
67
  "chalk": "^5.3.0",
66
- "peerbit": "1.3.1",
68
+ "peerbit": "2.0.0",
67
69
  "tar-stream": "^3.1.6",
68
70
  "tmp": "^0.2.1",
69
71
  "yargs": "^17.7.2",
70
72
  "zlib": "^1.0.5"
71
73
  },
72
- "gitHead": "06d341c4ea81b70c76018899b029f4419c311500"
74
+ "optionalDependencies": {
75
+ "@aws-sdk/client-ec2": "^3.390.0",
76
+ "@aws-sdk/client-route-53": "^3.391.0"
77
+ },
78
+ "gitHead": "2efb4d5dc542ac84cfd79bb576506ba0ca392a72"
73
79
  }
@@ -0,0 +1 @@
1
+ // Unsupported
package/src/aws.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { getMyIp } from "./domain.js";
1
+ import { delay } from "@peerbit/time";
2
+ import { type PeerId } from "@libp2p/interface/peer-id";
2
3
 
3
4
  export const createRecord = async (options: {
4
5
  domain: string;
@@ -10,6 +11,7 @@ export const createRecord = async (options: {
10
11
  "@aws-sdk/client-route-53"
11
12
  );
12
13
  const { isIPv4, isIPv6 } = await import("net");
14
+ const { getMyIp } = await import("./domain.js");
13
15
 
14
16
  const myIp = await getMyIp();
15
17
  const v4 = isIPv4(myIp);
@@ -46,3 +48,250 @@ export const createRecord = async (options: {
46
48
  });
47
49
  await client.send(cmd);
48
50
  };
51
+
52
+ const setupUserData = (email: string, grantAccess: PeerId[] = []) => {
53
+ const peerIdStrings = grantAccess.map((x) => x.toString());
54
+ return `#!/bin/bash
55
+ cd /home/ubuntu
56
+ curl -fsSL https://deb.nodesource.com/setup_19.x | sudo -E bash - &&\
57
+ sudo apt-get install -y nodejs
58
+ npm install -g @peerbit/server
59
+ sudo peerbit domain test --email ${email}
60
+ peerbit start ${peerIdStrings.map((key) => `--ga ${key}`)} > log.txt 2>&1 &
61
+ `;
62
+ };
63
+ const PURPOSE_TAG_NAME = "Purpose";
64
+ const PURPOSE_TAG_VALUE = "Peerbit";
65
+
66
+ export const AWS_LINUX_ARM_AMIs: Record<string, string> = {
67
+ /* "af-south-1" */
68
+ "ap-northeast-1": "ami-0342c9aa06b2a6488",
69
+ "ap-northeast-2": "ami-00fdfe418c69b624a",
70
+ "ap-northeast-3": "ami-0d053887907187d0a",
71
+ "ap-south-1": "ami-0df6182e39efe7c4d",
72
+ /* "ap-south-2",
73
+ "ap-southeast-1", */
74
+ "ap-southeast-2": "ami-0641fc20c25fdd380",
75
+ /* "ap-southeast-3",
76
+ "ap-southeast-4", */
77
+ "ca-central-1": "ami-0dfbb7075b12dcc91",
78
+ /* "cn-north-1",
79
+ "cn-northwest-1", */
80
+ "eu-central-1": "ami-0d85ad3aa712d96af",
81
+ /* "eu-central-2", */
82
+ "eu-north-1": "ami-0ff124a3d7381bfec",
83
+ /* "eu-south-1",
84
+ "eu-south-2", */
85
+ "eu-west-1": "ami-09c59b011574e4c96",
86
+ "eu-west-2": "ami-0e3f80b3d2a794117",
87
+ "eu-west-3": "ami-0d031bec3dde37593",
88
+ /* "il-central-1",
89
+ "me-central-1",
90
+ "me-south-1", */
91
+ "sa-east-1": "ami-0aba9f6e2597c6993",
92
+ "us-east-1": "ami-0a0c8eebcdd6dcbd0",
93
+ "us-east-2": "ami-08fdd91d87f63bb09",
94
+ /* "us-gov-east-1",
95
+ "us-gov-west-1", */
96
+ "us-west-2": "ami-0c79a55dda52434da",
97
+ "us-west-1": "ami-07655b4bbf3eb3bd0",
98
+ };
99
+ export const launchNodes = async (properties: {
100
+ region?: string;
101
+ email: string;
102
+ count?: number;
103
+ size?: "micro" | "small" | "medium" | "large" | "xlarge" | "2xlarge";
104
+ namePrefix?: string;
105
+ grantAccess?: PeerId[];
106
+ }): Promise<
107
+ { instanceId: string; publicIp: string; name: string; region: string }[]
108
+ > => {
109
+ if (properties.count && properties.count > 10) {
110
+ throw new Error(
111
+ "Unexpected node launch count: " +
112
+ properties.count +
113
+ ". To prevent unwanted behaviour you can also launch 10 nodes at once"
114
+ );
115
+ }
116
+ const count = properties.count || 1;
117
+
118
+ const {
119
+ EC2Client,
120
+ CreateTagsCommand,
121
+ RunInstancesCommand,
122
+ DescribeSecurityGroupsCommand,
123
+ CreateSecurityGroupCommand,
124
+ AuthorizeSecurityGroupIngressCommand,
125
+ DescribeInstancesCommand,
126
+ } = await import("@aws-sdk/client-ec2");
127
+ const client = new EC2Client({ region: properties.region });
128
+ const regionString = await client.config.region();
129
+
130
+ // Ubuntu Server 22.04 LTS (HVM), SSD Volume Type, ARM
131
+ let securityGroupOut = (
132
+ await client.send(
133
+ new DescribeSecurityGroupsCommand({
134
+ Filters: [
135
+ { Name: "tag:" + PURPOSE_TAG_NAME, Values: [PURPOSE_TAG_VALUE] },
136
+ ],
137
+ })
138
+ )
139
+ )?.SecurityGroups?.[0];
140
+ if (!securityGroupOut) {
141
+ securityGroupOut = await client.send(
142
+ new CreateSecurityGroupCommand({
143
+ GroupName: "peerbit-node",
144
+ Description: "Security group for running Peerbit nodes",
145
+ })
146
+ );
147
+ await client.send(
148
+ new CreateTagsCommand({
149
+ Resources: [securityGroupOut.GroupId!],
150
+ Tags: [{ Key: PURPOSE_TAG_NAME, Value: PURPOSE_TAG_VALUE }],
151
+ })
152
+ );
153
+ await client.send(
154
+ new AuthorizeSecurityGroupIngressCommand({
155
+ GroupId: securityGroupOut.GroupId,
156
+ IpPermissions: [
157
+ {
158
+ IpRanges: [{ CidrIp: "0.0.0.0/0" }],
159
+ IpProtocol: "tcp",
160
+ FromPort: 80,
161
+ ToPort: 80,
162
+ }, // Frontend
163
+ {
164
+ IpRanges: [{ CidrIp: "0.0.0.0/0" }],
165
+ IpProtocol: "tcp",
166
+ FromPort: 443,
167
+ ToPort: 443,
168
+ }, // Frontend SSL
169
+ {
170
+ IpRanges: [{ CidrIp: "0.0.0.0/0" }],
171
+ IpProtocol: "tcp",
172
+ FromPort: 9002,
173
+ ToPort: 9002,
174
+ }, // HTTPS api
175
+ {
176
+ IpRanges: [{ CidrIp: "0.0.0.0/0" }],
177
+ IpProtocol: "tcp",
178
+ FromPort: 8082,
179
+ ToPort: 8082,
180
+ }, // HTTP api
181
+ {
182
+ IpRanges: [{ CidrIp: "0.0.0.0/0" }],
183
+ IpProtocol: "tcp",
184
+ FromPort: 4002,
185
+ ToPort: 4005,
186
+ }, // libp2p
187
+ {
188
+ IpRanges: [{ CidrIp: "0.0.0.0/0" }],
189
+ IpProtocol: "tcp",
190
+ FromPort: 22,
191
+ ToPort: 22,
192
+ }, // SSH
193
+ ],
194
+ })
195
+ );
196
+ }
197
+ const instanceTag =
198
+ "Peerbit" + (properties.namePrefix ? "-" + properties.namePrefix : "");
199
+ let existingCounter =
200
+ (
201
+ await client.send(
202
+ new DescribeInstancesCommand({
203
+ Filters: [{ Name: "tag:Purpose", Values: [instanceTag] }],
204
+ })
205
+ )
206
+ ).Reservations?.length || 0;
207
+
208
+ console.log(regionString, AWS_LINUX_ARM_AMIs[regionString]);
209
+ const instanceOut = await client.send(
210
+ new RunInstancesCommand({
211
+ ImageId: AWS_LINUX_ARM_AMIs[regionString],
212
+ SecurityGroupIds: [securityGroupOut.GroupId!],
213
+ InstanceType: "t4g." + (properties.size || "micro"),
214
+ UserData: Buffer.from(
215
+ setupUserData(properties.email, properties.grantAccess)
216
+ ).toString("base64"),
217
+ MinCount: count,
218
+ MaxCount: count,
219
+ // InstanceInitiatedShutdownBehavior: 'terminate' // to enable termination when node shutting itself down
220
+ })
221
+ );
222
+
223
+ if (!instanceOut.Instances || instanceOut.Instances.length === 0) {
224
+ throw new Error("Failed to create instance");
225
+ }
226
+
227
+ const names: string[] = [];
228
+ for (const instance of instanceOut.Instances) {
229
+ existingCounter++;
230
+ const name =
231
+ (properties.namePrefix ? properties.namePrefix : "peerbit-node") +
232
+ "-" +
233
+ existingCounter;
234
+ names.push(name);
235
+ await client.send(
236
+ new CreateTagsCommand({
237
+ Resources: [instance.InstanceId!],
238
+ Tags: [
239
+ { Key: "Name", Value: name },
240
+ { Key: "Purpose", Value: instanceTag },
241
+ ],
242
+ })
243
+ );
244
+ }
245
+
246
+ // wait for instance ips to become available
247
+ let publicIps: string[] = [];
248
+ for (let i = 0; i < 10; i++) {
249
+ const info = await client.send(
250
+ new DescribeInstancesCommand({
251
+ InstanceIds: instanceOut.Instances.map((x) => x.InstanceId!),
252
+ })
253
+ );
254
+ const foundInstances = info
255
+ .Reservations!.map((x) => x.Instances!.map((y) => y))
256
+ .flat()!;
257
+ const foundIps: string[] = [];
258
+ for (const out of instanceOut.Instances) {
259
+ const foundInstance = foundInstances.find(
260
+ (x) => x!.InstanceId === out.InstanceId!
261
+ );
262
+ if (!foundInstance!.PublicIpAddress) {
263
+ await delay(3000);
264
+ continue;
265
+ }
266
+ foundIps.push(foundInstance!.PublicIpAddress!);
267
+ }
268
+ publicIps = foundIps;
269
+ break;
270
+ }
271
+
272
+ if (publicIps.length === 0) {
273
+ throw new Error("Failed to resolve IPs for created instances");
274
+ }
275
+
276
+ return publicIps.map((v, ix) => {
277
+ return {
278
+ instanceId: instanceOut.Instances![ix].InstanceId!,
279
+ publicIp: v,
280
+ name: names[ix],
281
+ region: regionString,
282
+ };
283
+ }); // TODO types
284
+ };
285
+
286
+ export const terminateNode = async (properties: {
287
+ instanceId: string;
288
+ region?: string;
289
+ }) => {
290
+ const { EC2Client, TerminateInstancesCommand } = await import(
291
+ "@aws-sdk/client-ec2"
292
+ );
293
+ const client = new EC2Client({ region: properties.region });
294
+ await client.send(
295
+ new TerminateInstancesCommand({ InstanceIds: [properties.instanceId] })
296
+ );
297
+ };