@net-protocol/profiles 0.1.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.
- package/README.md +147 -0
- package/dist/index.d.mts +117 -0
- package/dist/index.d.ts +117 -0
- package/dist/index.js +109 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +88 -0
- package/dist/index.mjs.map +1 -0
- package/dist/react.d.mts +110 -0
- package/dist/react.d.ts +110 -0
- package/dist/react.js +149 -0
- package/dist/react.js.map +1 -0
- package/dist/react.mjs +144 -0
- package/dist/react.mjs.map +1 -0
- package/dist/types-DTmd-Ngx.d.mts +52 -0
- package/dist/types-DTmd-Ngx.d.ts +52 -0
- package/package.json +90 -0
package/README.md
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# @net-protocol/profiles
|
|
2
|
+
|
|
3
|
+
Net Profiles SDK for reading and writing user profile data on the Net protocol.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @net-protocol/profiles
|
|
9
|
+
# or
|
|
10
|
+
yarn add @net-protocol/profiles
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- **Read profile data**: Profile picture, X username, canvas content
|
|
16
|
+
- **Write profile data**: Utilities to prepare Storage.put() transactions
|
|
17
|
+
- **Efficient batch reads**: `useBasicUserProfileMetadata` batches multiple reads
|
|
18
|
+
- **Built on net-storage**: Uses the Net Storage SDK for underlying storage operations
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
### Reading Profile Data (React)
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
import {
|
|
26
|
+
useProfilePicture,
|
|
27
|
+
useProfileXUsername,
|
|
28
|
+
useBasicUserProfileMetadata,
|
|
29
|
+
} from "@net-protocol/profiles/react";
|
|
30
|
+
|
|
31
|
+
function UserProfile({ address }: { address: string }) {
|
|
32
|
+
// Option 1: Individual hooks
|
|
33
|
+
const { profilePicture, isLoading: pictureLoading } = useProfilePicture({
|
|
34
|
+
chainId: 8453, // Base
|
|
35
|
+
userAddress: address,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const { xUsername, isLoading: usernameLoading } = useProfileXUsername({
|
|
39
|
+
chainId: 8453,
|
|
40
|
+
userAddress: address,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Option 2: Batch read (more efficient)
|
|
44
|
+
const { profilePicture, xUsername, isLoading } = useBasicUserProfileMetadata({
|
|
45
|
+
chainId: 8453,
|
|
46
|
+
userAddress: address,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<div>
|
|
51
|
+
{profilePicture && <img src={profilePicture} alt="Profile" />}
|
|
52
|
+
{xUsername && <a href={`https://x.com/${xUsername}`}>@{xUsername}</a>}
|
|
53
|
+
</div>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Writing Profile Data
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
import { useWriteContract } from "wagmi";
|
|
62
|
+
import {
|
|
63
|
+
getProfilePictureStorageArgs,
|
|
64
|
+
getXUsernameStorageArgs,
|
|
65
|
+
STORAGE_CONTRACT,
|
|
66
|
+
} from "@net-protocol/profiles";
|
|
67
|
+
|
|
68
|
+
function UpdateProfile() {
|
|
69
|
+
const { writeContract } = useWriteContract();
|
|
70
|
+
|
|
71
|
+
const handleUpdatePicture = (imageUrl: string) => {
|
|
72
|
+
const args = getProfilePictureStorageArgs(imageUrl);
|
|
73
|
+
writeContract({
|
|
74
|
+
abi: STORAGE_CONTRACT.abi,
|
|
75
|
+
address: STORAGE_CONTRACT.address,
|
|
76
|
+
functionName: "put",
|
|
77
|
+
args: [args.bytesKey, args.topic, args.bytesValue],
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const handleUpdateXUsername = (username: string) => {
|
|
82
|
+
const args = getXUsernameStorageArgs(username);
|
|
83
|
+
writeContract({
|
|
84
|
+
abi: STORAGE_CONTRACT.abi,
|
|
85
|
+
address: STORAGE_CONTRACT.address,
|
|
86
|
+
functionName: "put",
|
|
87
|
+
args: [args.bytesKey, args.topic, args.bytesValue],
|
|
88
|
+
});
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<form>
|
|
93
|
+
{/* Form fields */}
|
|
94
|
+
</form>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Profile Fields
|
|
100
|
+
|
|
101
|
+
| Field | Description | Notes |
|
|
102
|
+
|-------|-------------|-------|
|
|
103
|
+
| Profile Picture | URL to your profile image | Any valid URL (HTTPS, IPFS, etc.) |
|
|
104
|
+
| X Username | Your X (Twitter) handle | Stored with @ prefix, displayed without |
|
|
105
|
+
| Canvas | Custom HTML profile page | For advanced customization |
|
|
106
|
+
|
|
107
|
+
## Storage Keys
|
|
108
|
+
|
|
109
|
+
| Key | Description | Data Format |
|
|
110
|
+
|-----|-------------|-------------|
|
|
111
|
+
| `PROFILE_PICTURE_STORAGE_KEY` | Profile picture URL | Plain string (URL) |
|
|
112
|
+
| `PROFILE_METADATA_STORAGE_KEY` | Profile metadata JSON | `{ x_username: "@handle" }` |
|
|
113
|
+
| `PROFILE_CANVAS_STORAGE_KEY` | Custom HTML canvas | HTML string |
|
|
114
|
+
|
|
115
|
+
## API Reference
|
|
116
|
+
|
|
117
|
+
### Hooks (from `@net-protocol/profiles/react`)
|
|
118
|
+
|
|
119
|
+
- `useProfilePicture({ chainId, userAddress })` - Fetch profile picture URL
|
|
120
|
+
- `useProfileXUsername({ chainId, userAddress })` - Fetch X username
|
|
121
|
+
- `useProfileCanvas({ chainId, userAddress })` - Fetch canvas HTML
|
|
122
|
+
- `useBasicUserProfileMetadata({ chainId, userAddress })` - Batch fetch picture & username
|
|
123
|
+
|
|
124
|
+
### Utilities (from `@net-protocol/profiles`)
|
|
125
|
+
|
|
126
|
+
- `getProfilePictureStorageArgs(imageUrl)` - Prepare picture update args
|
|
127
|
+
- `getXUsernameStorageArgs(username)` - Prepare X username update args
|
|
128
|
+
- `getProfileMetadataStorageArgs(metadata)` - Prepare metadata update args
|
|
129
|
+
- `getProfileCanvasStorageArgs(html)` - Prepare canvas update args
|
|
130
|
+
- `parseProfileMetadata(json)` - Parse metadata JSON
|
|
131
|
+
- `isValidUrl(url)` - Validate URL format
|
|
132
|
+
- `isValidXUsername(username)` - Validate X username format
|
|
133
|
+
|
|
134
|
+
## Dependencies
|
|
135
|
+
|
|
136
|
+
- `@net-protocol/storage` - Storage SDK
|
|
137
|
+
- `@net-protocol/core` - Core utilities
|
|
138
|
+
- `viem` - Ethereum utilities
|
|
139
|
+
|
|
140
|
+
### Peer Dependencies (for React hooks)
|
|
141
|
+
|
|
142
|
+
- `react` ^18.0.0
|
|
143
|
+
- `wagmi` ^2.15.0
|
|
144
|
+
|
|
145
|
+
## License
|
|
146
|
+
|
|
147
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { P as ProfileStorageArgs, a as ProfileMetadata } from './types-DTmd-Ngx.mjs';
|
|
2
|
+
export { B as BasicUserProfileMetadata, b as UseProfileOptions, U as UserDisplayName, c as UserProfile } from './types-DTmd-Ngx.mjs';
|
|
3
|
+
export { STORAGE_CONTRACT } from '@net-protocol/storage';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Profile-related storage keys
|
|
7
|
+
*
|
|
8
|
+
* Using descriptive keys under 32 bytes to avoid hashing complexity and work seamlessly
|
|
9
|
+
* with existing storage infrastructure. The key includes app prefix and versioning for
|
|
10
|
+
* clarity and future-proofing.
|
|
11
|
+
*
|
|
12
|
+
* NOTE: if we change these keys, users will not be able to see their profile data
|
|
13
|
+
*/
|
|
14
|
+
declare const PROFILE_CANVAS_STORAGE_KEY = "net-beta0.0.1-profile-canvas";
|
|
15
|
+
declare const PROFILE_PICTURE_STORAGE_KEY = "net-beta0.0.1-profile-picture";
|
|
16
|
+
declare const PROFILE_X_USERNAME_STORAGE_KEY = "net-beta0.0.1-profile-x-username";
|
|
17
|
+
declare const PROFILE_METADATA_STORAGE_KEY = "net-beta0.0.1-profile-metadata";
|
|
18
|
+
/**
|
|
19
|
+
* Topic strings used when writing to storage
|
|
20
|
+
* These are the second argument to Storage.put()
|
|
21
|
+
*/
|
|
22
|
+
declare const PROFILE_PICTURE_TOPIC = "profile-picture";
|
|
23
|
+
declare const PROFILE_METADATA_TOPIC = "profile-metadata";
|
|
24
|
+
declare const PROFILE_CANVAS_TOPIC = "profile-canvas";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Convert a string value to hex for storage
|
|
28
|
+
*/
|
|
29
|
+
declare function getValueArgForStorage(value: string): `0x${string}`;
|
|
30
|
+
/**
|
|
31
|
+
* Get storage args (key as bytes32, value as hex)
|
|
32
|
+
*/
|
|
33
|
+
declare function getBytesArgsForStorage(key: string, value: string): {
|
|
34
|
+
bytesKey: `0x${string}`;
|
|
35
|
+
bytesValue: `0x${string}`;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Prepare transaction arguments for updating profile picture
|
|
39
|
+
*
|
|
40
|
+
* @param imageUrl - The URL of the profile picture
|
|
41
|
+
* @returns Arguments for Storage.put() - [bytesKey, topic, bytesValue]
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```ts
|
|
45
|
+
* const args = getProfilePictureStorageArgs("https://example.com/image.jpg");
|
|
46
|
+
* // Use with wagmi writeContract:
|
|
47
|
+
* writeContract({
|
|
48
|
+
* abi: STORAGE_CONTRACT.abi,
|
|
49
|
+
* address: STORAGE_CONTRACT.address,
|
|
50
|
+
* functionName: "put",
|
|
51
|
+
* args: [args.bytesKey, args.topic, args.bytesValue],
|
|
52
|
+
* });
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
declare function getProfilePictureStorageArgs(imageUrl: string): ProfileStorageArgs;
|
|
56
|
+
/**
|
|
57
|
+
* Prepare transaction arguments for updating profile metadata (X username, etc.)
|
|
58
|
+
*
|
|
59
|
+
* @param metadata - Profile metadata object to store
|
|
60
|
+
* @returns Arguments for Storage.put() - [bytesKey, topic, bytesValue]
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```ts
|
|
64
|
+
* const args = getProfileMetadataStorageArgs({ x_username: "@myusername" });
|
|
65
|
+
* writeContract({
|
|
66
|
+
* abi: STORAGE_CONTRACT.abi,
|
|
67
|
+
* address: STORAGE_CONTRACT.address,
|
|
68
|
+
* functionName: "put",
|
|
69
|
+
* args: [args.bytesKey, args.topic, args.bytesValue],
|
|
70
|
+
* });
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
declare function getProfileMetadataStorageArgs(metadata: ProfileMetadata): ProfileStorageArgs;
|
|
74
|
+
/**
|
|
75
|
+
* Prepare transaction arguments for updating X username
|
|
76
|
+
* This is a convenience wrapper around getProfileMetadataStorageArgs
|
|
77
|
+
*
|
|
78
|
+
* @param username - X/Twitter username (with or without @)
|
|
79
|
+
* @returns Arguments for Storage.put()
|
|
80
|
+
*/
|
|
81
|
+
declare function getXUsernameStorageArgs(username: string): ProfileStorageArgs;
|
|
82
|
+
/**
|
|
83
|
+
* Prepare transaction arguments for updating profile canvas (HTML content)
|
|
84
|
+
*
|
|
85
|
+
* @param htmlContent - HTML content for the profile canvas
|
|
86
|
+
* @returns Arguments for Storage.put()
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* const args = getProfileCanvasStorageArgs("<div>My custom profile</div>");
|
|
91
|
+
* writeContract({
|
|
92
|
+
* abi: STORAGE_CONTRACT.abi,
|
|
93
|
+
* address: STORAGE_CONTRACT.address,
|
|
94
|
+
* functionName: "put",
|
|
95
|
+
* args: [args.bytesKey, args.topic, args.bytesValue],
|
|
96
|
+
* });
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
declare function getProfileCanvasStorageArgs(htmlContent: string): ProfileStorageArgs;
|
|
100
|
+
/**
|
|
101
|
+
* Parse profile metadata JSON and extract profile data
|
|
102
|
+
*
|
|
103
|
+
* @param jsonData - JSON string from storage
|
|
104
|
+
* @returns Parsed profile metadata or undefined if invalid
|
|
105
|
+
*/
|
|
106
|
+
declare function parseProfileMetadata(jsonData: string): ProfileMetadata | undefined;
|
|
107
|
+
/**
|
|
108
|
+
* Validate that a string is a valid URL
|
|
109
|
+
*/
|
|
110
|
+
declare function isValidUrl(url: string): boolean;
|
|
111
|
+
/**
|
|
112
|
+
* Validate X/Twitter username format
|
|
113
|
+
* Returns true if valid (alphanumeric and underscores, 1-15 chars)
|
|
114
|
+
*/
|
|
115
|
+
declare function isValidXUsername(username: string): boolean;
|
|
116
|
+
|
|
117
|
+
export { PROFILE_CANVAS_STORAGE_KEY, PROFILE_CANVAS_TOPIC, PROFILE_METADATA_STORAGE_KEY, PROFILE_METADATA_TOPIC, PROFILE_PICTURE_STORAGE_KEY, PROFILE_PICTURE_TOPIC, PROFILE_X_USERNAME_STORAGE_KEY, ProfileMetadata, ProfileStorageArgs, getBytesArgsForStorage, getProfileCanvasStorageArgs, getProfileMetadataStorageArgs, getProfilePictureStorageArgs, getValueArgForStorage, getXUsernameStorageArgs, isValidUrl, isValidXUsername, parseProfileMetadata };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { P as ProfileStorageArgs, a as ProfileMetadata } from './types-DTmd-Ngx.js';
|
|
2
|
+
export { B as BasicUserProfileMetadata, b as UseProfileOptions, U as UserDisplayName, c as UserProfile } from './types-DTmd-Ngx.js';
|
|
3
|
+
export { STORAGE_CONTRACT } from '@net-protocol/storage';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Profile-related storage keys
|
|
7
|
+
*
|
|
8
|
+
* Using descriptive keys under 32 bytes to avoid hashing complexity and work seamlessly
|
|
9
|
+
* with existing storage infrastructure. The key includes app prefix and versioning for
|
|
10
|
+
* clarity and future-proofing.
|
|
11
|
+
*
|
|
12
|
+
* NOTE: if we change these keys, users will not be able to see their profile data
|
|
13
|
+
*/
|
|
14
|
+
declare const PROFILE_CANVAS_STORAGE_KEY = "net-beta0.0.1-profile-canvas";
|
|
15
|
+
declare const PROFILE_PICTURE_STORAGE_KEY = "net-beta0.0.1-profile-picture";
|
|
16
|
+
declare const PROFILE_X_USERNAME_STORAGE_KEY = "net-beta0.0.1-profile-x-username";
|
|
17
|
+
declare const PROFILE_METADATA_STORAGE_KEY = "net-beta0.0.1-profile-metadata";
|
|
18
|
+
/**
|
|
19
|
+
* Topic strings used when writing to storage
|
|
20
|
+
* These are the second argument to Storage.put()
|
|
21
|
+
*/
|
|
22
|
+
declare const PROFILE_PICTURE_TOPIC = "profile-picture";
|
|
23
|
+
declare const PROFILE_METADATA_TOPIC = "profile-metadata";
|
|
24
|
+
declare const PROFILE_CANVAS_TOPIC = "profile-canvas";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Convert a string value to hex for storage
|
|
28
|
+
*/
|
|
29
|
+
declare function getValueArgForStorage(value: string): `0x${string}`;
|
|
30
|
+
/**
|
|
31
|
+
* Get storage args (key as bytes32, value as hex)
|
|
32
|
+
*/
|
|
33
|
+
declare function getBytesArgsForStorage(key: string, value: string): {
|
|
34
|
+
bytesKey: `0x${string}`;
|
|
35
|
+
bytesValue: `0x${string}`;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Prepare transaction arguments for updating profile picture
|
|
39
|
+
*
|
|
40
|
+
* @param imageUrl - The URL of the profile picture
|
|
41
|
+
* @returns Arguments for Storage.put() - [bytesKey, topic, bytesValue]
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```ts
|
|
45
|
+
* const args = getProfilePictureStorageArgs("https://example.com/image.jpg");
|
|
46
|
+
* // Use with wagmi writeContract:
|
|
47
|
+
* writeContract({
|
|
48
|
+
* abi: STORAGE_CONTRACT.abi,
|
|
49
|
+
* address: STORAGE_CONTRACT.address,
|
|
50
|
+
* functionName: "put",
|
|
51
|
+
* args: [args.bytesKey, args.topic, args.bytesValue],
|
|
52
|
+
* });
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
declare function getProfilePictureStorageArgs(imageUrl: string): ProfileStorageArgs;
|
|
56
|
+
/**
|
|
57
|
+
* Prepare transaction arguments for updating profile metadata (X username, etc.)
|
|
58
|
+
*
|
|
59
|
+
* @param metadata - Profile metadata object to store
|
|
60
|
+
* @returns Arguments for Storage.put() - [bytesKey, topic, bytesValue]
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```ts
|
|
64
|
+
* const args = getProfileMetadataStorageArgs({ x_username: "@myusername" });
|
|
65
|
+
* writeContract({
|
|
66
|
+
* abi: STORAGE_CONTRACT.abi,
|
|
67
|
+
* address: STORAGE_CONTRACT.address,
|
|
68
|
+
* functionName: "put",
|
|
69
|
+
* args: [args.bytesKey, args.topic, args.bytesValue],
|
|
70
|
+
* });
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
declare function getProfileMetadataStorageArgs(metadata: ProfileMetadata): ProfileStorageArgs;
|
|
74
|
+
/**
|
|
75
|
+
* Prepare transaction arguments for updating X username
|
|
76
|
+
* This is a convenience wrapper around getProfileMetadataStorageArgs
|
|
77
|
+
*
|
|
78
|
+
* @param username - X/Twitter username (with or without @)
|
|
79
|
+
* @returns Arguments for Storage.put()
|
|
80
|
+
*/
|
|
81
|
+
declare function getXUsernameStorageArgs(username: string): ProfileStorageArgs;
|
|
82
|
+
/**
|
|
83
|
+
* Prepare transaction arguments for updating profile canvas (HTML content)
|
|
84
|
+
*
|
|
85
|
+
* @param htmlContent - HTML content for the profile canvas
|
|
86
|
+
* @returns Arguments for Storage.put()
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* const args = getProfileCanvasStorageArgs("<div>My custom profile</div>");
|
|
91
|
+
* writeContract({
|
|
92
|
+
* abi: STORAGE_CONTRACT.abi,
|
|
93
|
+
* address: STORAGE_CONTRACT.address,
|
|
94
|
+
* functionName: "put",
|
|
95
|
+
* args: [args.bytesKey, args.topic, args.bytesValue],
|
|
96
|
+
* });
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
declare function getProfileCanvasStorageArgs(htmlContent: string): ProfileStorageArgs;
|
|
100
|
+
/**
|
|
101
|
+
* Parse profile metadata JSON and extract profile data
|
|
102
|
+
*
|
|
103
|
+
* @param jsonData - JSON string from storage
|
|
104
|
+
* @returns Parsed profile metadata or undefined if invalid
|
|
105
|
+
*/
|
|
106
|
+
declare function parseProfileMetadata(jsonData: string): ProfileMetadata | undefined;
|
|
107
|
+
/**
|
|
108
|
+
* Validate that a string is a valid URL
|
|
109
|
+
*/
|
|
110
|
+
declare function isValidUrl(url: string): boolean;
|
|
111
|
+
/**
|
|
112
|
+
* Validate X/Twitter username format
|
|
113
|
+
* Returns true if valid (alphanumeric and underscores, 1-15 chars)
|
|
114
|
+
*/
|
|
115
|
+
declare function isValidXUsername(username: string): boolean;
|
|
116
|
+
|
|
117
|
+
export { PROFILE_CANVAS_STORAGE_KEY, PROFILE_CANVAS_TOPIC, PROFILE_METADATA_STORAGE_KEY, PROFILE_METADATA_TOPIC, PROFILE_PICTURE_STORAGE_KEY, PROFILE_PICTURE_TOPIC, PROFILE_X_USERNAME_STORAGE_KEY, ProfileMetadata, ProfileStorageArgs, getBytesArgsForStorage, getProfileCanvasStorageArgs, getProfileMetadataStorageArgs, getProfilePictureStorageArgs, getValueArgForStorage, getXUsernameStorageArgs, isValidUrl, isValidXUsername, parseProfileMetadata };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var viem = require('viem');
|
|
4
|
+
var core = require('@net-protocol/core');
|
|
5
|
+
var storage = require('@net-protocol/storage');
|
|
6
|
+
|
|
7
|
+
// src/constants.ts
|
|
8
|
+
var PROFILE_CANVAS_STORAGE_KEY = "net-beta0.0.1-profile-canvas";
|
|
9
|
+
var PROFILE_PICTURE_STORAGE_KEY = "net-beta0.0.1-profile-picture";
|
|
10
|
+
var PROFILE_X_USERNAME_STORAGE_KEY = "net-beta0.0.1-profile-x-username";
|
|
11
|
+
var PROFILE_METADATA_STORAGE_KEY = "net-beta0.0.1-profile-metadata";
|
|
12
|
+
var PROFILE_PICTURE_TOPIC = "profile-picture";
|
|
13
|
+
var PROFILE_METADATA_TOPIC = "profile-metadata";
|
|
14
|
+
var PROFILE_CANVAS_TOPIC = "profile-canvas";
|
|
15
|
+
function getValueArgForStorage(value) {
|
|
16
|
+
return viem.stringToHex(value);
|
|
17
|
+
}
|
|
18
|
+
function getBytesArgsForStorage(key, value) {
|
|
19
|
+
const bytesKey = core.toBytes32(key);
|
|
20
|
+
const bytesValue = getValueArgForStorage(value);
|
|
21
|
+
return { bytesKey, bytesValue };
|
|
22
|
+
}
|
|
23
|
+
function getProfilePictureStorageArgs(imageUrl) {
|
|
24
|
+
const { bytesKey, bytesValue } = getBytesArgsForStorage(
|
|
25
|
+
PROFILE_PICTURE_STORAGE_KEY,
|
|
26
|
+
imageUrl
|
|
27
|
+
);
|
|
28
|
+
return {
|
|
29
|
+
bytesKey,
|
|
30
|
+
topic: PROFILE_PICTURE_TOPIC,
|
|
31
|
+
bytesValue
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function getProfileMetadataStorageArgs(metadata) {
|
|
35
|
+
const jsonString = JSON.stringify(metadata);
|
|
36
|
+
const { bytesKey, bytesValue } = getBytesArgsForStorage(
|
|
37
|
+
PROFILE_METADATA_STORAGE_KEY,
|
|
38
|
+
jsonString
|
|
39
|
+
);
|
|
40
|
+
return {
|
|
41
|
+
bytesKey,
|
|
42
|
+
topic: PROFILE_METADATA_TOPIC,
|
|
43
|
+
bytesValue
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function getXUsernameStorageArgs(username) {
|
|
47
|
+
const normalizedUsername = username.startsWith("@") ? username : `@${username}`;
|
|
48
|
+
return getProfileMetadataStorageArgs({ x_username: normalizedUsername });
|
|
49
|
+
}
|
|
50
|
+
function getProfileCanvasStorageArgs(htmlContent) {
|
|
51
|
+
const { bytesKey, bytesValue } = getBytesArgsForStorage(
|
|
52
|
+
PROFILE_CANVAS_STORAGE_KEY,
|
|
53
|
+
htmlContent
|
|
54
|
+
);
|
|
55
|
+
return {
|
|
56
|
+
bytesKey,
|
|
57
|
+
topic: PROFILE_CANVAS_TOPIC,
|
|
58
|
+
bytesValue
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function parseProfileMetadata(jsonData) {
|
|
62
|
+
try {
|
|
63
|
+
const parsed = JSON.parse(jsonData);
|
|
64
|
+
const storedUsername = parsed?.x_username && typeof parsed.x_username === "string" && parsed.x_username.length > 0 ? parsed.x_username : void 0;
|
|
65
|
+
const usernameWithoutAt = storedUsername?.startsWith("@") ? storedUsername.slice(1) : storedUsername;
|
|
66
|
+
return {
|
|
67
|
+
x_username: usernameWithoutAt
|
|
68
|
+
};
|
|
69
|
+
} catch {
|
|
70
|
+
return void 0;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function isValidUrl(url) {
|
|
74
|
+
if (!url) return false;
|
|
75
|
+
try {
|
|
76
|
+
new URL(url);
|
|
77
|
+
return true;
|
|
78
|
+
} catch {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function isValidXUsername(username) {
|
|
83
|
+
if (!username) return false;
|
|
84
|
+
const cleanUsername = username.startsWith("@") ? username.slice(1) : username;
|
|
85
|
+
return /^[a-zA-Z0-9_]{1,15}$/.test(cleanUsername);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
Object.defineProperty(exports, "STORAGE_CONTRACT", {
|
|
89
|
+
enumerable: true,
|
|
90
|
+
get: function () { return storage.STORAGE_CONTRACT; }
|
|
91
|
+
});
|
|
92
|
+
exports.PROFILE_CANVAS_STORAGE_KEY = PROFILE_CANVAS_STORAGE_KEY;
|
|
93
|
+
exports.PROFILE_CANVAS_TOPIC = PROFILE_CANVAS_TOPIC;
|
|
94
|
+
exports.PROFILE_METADATA_STORAGE_KEY = PROFILE_METADATA_STORAGE_KEY;
|
|
95
|
+
exports.PROFILE_METADATA_TOPIC = PROFILE_METADATA_TOPIC;
|
|
96
|
+
exports.PROFILE_PICTURE_STORAGE_KEY = PROFILE_PICTURE_STORAGE_KEY;
|
|
97
|
+
exports.PROFILE_PICTURE_TOPIC = PROFILE_PICTURE_TOPIC;
|
|
98
|
+
exports.PROFILE_X_USERNAME_STORAGE_KEY = PROFILE_X_USERNAME_STORAGE_KEY;
|
|
99
|
+
exports.getBytesArgsForStorage = getBytesArgsForStorage;
|
|
100
|
+
exports.getProfileCanvasStorageArgs = getProfileCanvasStorageArgs;
|
|
101
|
+
exports.getProfileMetadataStorageArgs = getProfileMetadataStorageArgs;
|
|
102
|
+
exports.getProfilePictureStorageArgs = getProfilePictureStorageArgs;
|
|
103
|
+
exports.getValueArgForStorage = getValueArgForStorage;
|
|
104
|
+
exports.getXUsernameStorageArgs = getXUsernameStorageArgs;
|
|
105
|
+
exports.isValidUrl = isValidUrl;
|
|
106
|
+
exports.isValidXUsername = isValidXUsername;
|
|
107
|
+
exports.parseProfileMetadata = parseProfileMetadata;
|
|
108
|
+
//# sourceMappingURL=index.js.map
|
|
109
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/utils.ts"],"names":["stringToHex","toBytes32"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Profile-related storage keys\n *\n * Using descriptive keys under 32 bytes to avoid hashing complexity and work seamlessly\n * with existing storage infrastructure. The key includes app prefix and versioning for\n * clarity and future-proofing.\n *\n * NOTE: if we change these keys, users will not be able to see their profile data\n */\nexport const PROFILE_CANVAS_STORAGE_KEY = \"net-beta0.0.1-profile-canvas\";\nexport const PROFILE_PICTURE_STORAGE_KEY = \"net-beta0.0.1-profile-picture\";\nexport const PROFILE_X_USERNAME_STORAGE_KEY =\n \"net-beta0.0.1-profile-x-username\";\nexport const PROFILE_METADATA_STORAGE_KEY = \"net-beta0.0.1-profile-metadata\";\n\n/**\n * Topic strings used when writing to storage\n * These are the second argument to Storage.put()\n */\nexport const PROFILE_PICTURE_TOPIC = \"profile-picture\";\nexport const PROFILE_METADATA_TOPIC = \"profile-metadata\";\nexport const PROFILE_CANVAS_TOPIC = \"profile-canvas\";\n","import { stringToHex } from \"viem\";\nimport { toBytes32 } from \"@net-protocol/core\";\nimport {\n PROFILE_PICTURE_STORAGE_KEY,\n PROFILE_METADATA_STORAGE_KEY,\n PROFILE_CANVAS_STORAGE_KEY,\n PROFILE_PICTURE_TOPIC,\n PROFILE_METADATA_TOPIC,\n PROFILE_CANVAS_TOPIC,\n} from \"./constants\";\nimport type { ProfileMetadata, ProfileStorageArgs } from \"./types\";\n\n/**\n * Convert a string value to hex for storage\n */\nexport function getValueArgForStorage(value: string): `0x${string}` {\n return stringToHex(value);\n}\n\n/**\n * Get storage args (key as bytes32, value as hex)\n */\nexport function getBytesArgsForStorage(\n key: string,\n value: string\n): { bytesKey: `0x${string}`; bytesValue: `0x${string}` } {\n const bytesKey = toBytes32(key) as `0x${string}`;\n const bytesValue = getValueArgForStorage(value);\n return { bytesKey, bytesValue };\n}\n\n/**\n * Prepare transaction arguments for updating profile picture\n *\n * @param imageUrl - The URL of the profile picture\n * @returns Arguments for Storage.put() - [bytesKey, topic, bytesValue]\n *\n * @example\n * ```ts\n * const args = getProfilePictureStorageArgs(\"https://example.com/image.jpg\");\n * // Use with wagmi writeContract:\n * writeContract({\n * abi: STORAGE_CONTRACT.abi,\n * address: STORAGE_CONTRACT.address,\n * functionName: \"put\",\n * args: [args.bytesKey, args.topic, args.bytesValue],\n * });\n * ```\n */\nexport function getProfilePictureStorageArgs(\n imageUrl: string\n): ProfileStorageArgs {\n const { bytesKey, bytesValue } = getBytesArgsForStorage(\n PROFILE_PICTURE_STORAGE_KEY,\n imageUrl\n );\n return {\n bytesKey,\n topic: PROFILE_PICTURE_TOPIC,\n bytesValue,\n };\n}\n\n/**\n * Prepare transaction arguments for updating profile metadata (X username, etc.)\n *\n * @param metadata - Profile metadata object to store\n * @returns Arguments for Storage.put() - [bytesKey, topic, bytesValue]\n *\n * @example\n * ```ts\n * const args = getProfileMetadataStorageArgs({ x_username: \"@myusername\" });\n * writeContract({\n * abi: STORAGE_CONTRACT.abi,\n * address: STORAGE_CONTRACT.address,\n * functionName: \"put\",\n * args: [args.bytesKey, args.topic, args.bytesValue],\n * });\n * ```\n */\nexport function getProfileMetadataStorageArgs(\n metadata: ProfileMetadata\n): ProfileStorageArgs {\n const jsonString = JSON.stringify(metadata);\n const { bytesKey, bytesValue } = getBytesArgsForStorage(\n PROFILE_METADATA_STORAGE_KEY,\n jsonString\n );\n return {\n bytesKey,\n topic: PROFILE_METADATA_TOPIC,\n bytesValue,\n };\n}\n\n/**\n * Prepare transaction arguments for updating X username\n * This is a convenience wrapper around getProfileMetadataStorageArgs\n *\n * @param username - X/Twitter username (with or without @)\n * @returns Arguments for Storage.put()\n */\nexport function getXUsernameStorageArgs(username: string): ProfileStorageArgs {\n // Ensure username has @ prefix for storage\n const normalizedUsername = username.startsWith(\"@\")\n ? username\n : `@${username}`;\n return getProfileMetadataStorageArgs({ x_username: normalizedUsername });\n}\n\n/**\n * Prepare transaction arguments for updating profile canvas (HTML content)\n *\n * @param htmlContent - HTML content for the profile canvas\n * @returns Arguments for Storage.put()\n *\n * @example\n * ```ts\n * const args = getProfileCanvasStorageArgs(\"<div>My custom profile</div>\");\n * writeContract({\n * abi: STORAGE_CONTRACT.abi,\n * address: STORAGE_CONTRACT.address,\n * functionName: \"put\",\n * args: [args.bytesKey, args.topic, args.bytesValue],\n * });\n * ```\n */\nexport function getProfileCanvasStorageArgs(\n htmlContent: string\n): ProfileStorageArgs {\n const { bytesKey, bytesValue } = getBytesArgsForStorage(\n PROFILE_CANVAS_STORAGE_KEY,\n htmlContent\n );\n return {\n bytesKey,\n topic: PROFILE_CANVAS_TOPIC,\n bytesValue,\n };\n}\n\n/**\n * Parse profile metadata JSON and extract profile data\n *\n * @param jsonData - JSON string from storage\n * @returns Parsed profile metadata or undefined if invalid\n */\nexport function parseProfileMetadata(\n jsonData: string\n): ProfileMetadata | undefined {\n try {\n const parsed = JSON.parse(jsonData);\n const storedUsername =\n parsed?.x_username &&\n typeof parsed.x_username === \"string\" &&\n parsed.x_username.length > 0\n ? parsed.x_username\n : undefined;\n\n // Strip @ from stored username for display\n const usernameWithoutAt = storedUsername?.startsWith(\"@\")\n ? storedUsername.slice(1)\n : storedUsername;\n\n return {\n x_username: usernameWithoutAt,\n };\n } catch {\n return undefined;\n }\n}\n\n/**\n * Validate that a string is a valid URL\n */\nexport function isValidUrl(url: string): boolean {\n if (!url) return false;\n try {\n new URL(url);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Validate X/Twitter username format\n * Returns true if valid (alphanumeric and underscores, 1-15 chars)\n */\nexport function isValidXUsername(username: string): boolean {\n if (!username) return false;\n // Remove @ prefix if present\n const cleanUsername = username.startsWith(\"@\") ? username.slice(1) : username;\n // X usernames: 1-15 chars, alphanumeric and underscores only\n return /^[a-zA-Z0-9_]{1,15}$/.test(cleanUsername);\n}\n"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { stringToHex } from 'viem';
|
|
2
|
+
import { toBytes32 } from '@net-protocol/core';
|
|
3
|
+
export { STORAGE_CONTRACT } from '@net-protocol/storage';
|
|
4
|
+
|
|
5
|
+
// src/constants.ts
|
|
6
|
+
var PROFILE_CANVAS_STORAGE_KEY = "net-beta0.0.1-profile-canvas";
|
|
7
|
+
var PROFILE_PICTURE_STORAGE_KEY = "net-beta0.0.1-profile-picture";
|
|
8
|
+
var PROFILE_X_USERNAME_STORAGE_KEY = "net-beta0.0.1-profile-x-username";
|
|
9
|
+
var PROFILE_METADATA_STORAGE_KEY = "net-beta0.0.1-profile-metadata";
|
|
10
|
+
var PROFILE_PICTURE_TOPIC = "profile-picture";
|
|
11
|
+
var PROFILE_METADATA_TOPIC = "profile-metadata";
|
|
12
|
+
var PROFILE_CANVAS_TOPIC = "profile-canvas";
|
|
13
|
+
function getValueArgForStorage(value) {
|
|
14
|
+
return stringToHex(value);
|
|
15
|
+
}
|
|
16
|
+
function getBytesArgsForStorage(key, value) {
|
|
17
|
+
const bytesKey = toBytes32(key);
|
|
18
|
+
const bytesValue = getValueArgForStorage(value);
|
|
19
|
+
return { bytesKey, bytesValue };
|
|
20
|
+
}
|
|
21
|
+
function getProfilePictureStorageArgs(imageUrl) {
|
|
22
|
+
const { bytesKey, bytesValue } = getBytesArgsForStorage(
|
|
23
|
+
PROFILE_PICTURE_STORAGE_KEY,
|
|
24
|
+
imageUrl
|
|
25
|
+
);
|
|
26
|
+
return {
|
|
27
|
+
bytesKey,
|
|
28
|
+
topic: PROFILE_PICTURE_TOPIC,
|
|
29
|
+
bytesValue
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function getProfileMetadataStorageArgs(metadata) {
|
|
33
|
+
const jsonString = JSON.stringify(metadata);
|
|
34
|
+
const { bytesKey, bytesValue } = getBytesArgsForStorage(
|
|
35
|
+
PROFILE_METADATA_STORAGE_KEY,
|
|
36
|
+
jsonString
|
|
37
|
+
);
|
|
38
|
+
return {
|
|
39
|
+
bytesKey,
|
|
40
|
+
topic: PROFILE_METADATA_TOPIC,
|
|
41
|
+
bytesValue
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function getXUsernameStorageArgs(username) {
|
|
45
|
+
const normalizedUsername = username.startsWith("@") ? username : `@${username}`;
|
|
46
|
+
return getProfileMetadataStorageArgs({ x_username: normalizedUsername });
|
|
47
|
+
}
|
|
48
|
+
function getProfileCanvasStorageArgs(htmlContent) {
|
|
49
|
+
const { bytesKey, bytesValue } = getBytesArgsForStorage(
|
|
50
|
+
PROFILE_CANVAS_STORAGE_KEY,
|
|
51
|
+
htmlContent
|
|
52
|
+
);
|
|
53
|
+
return {
|
|
54
|
+
bytesKey,
|
|
55
|
+
topic: PROFILE_CANVAS_TOPIC,
|
|
56
|
+
bytesValue
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function parseProfileMetadata(jsonData) {
|
|
60
|
+
try {
|
|
61
|
+
const parsed = JSON.parse(jsonData);
|
|
62
|
+
const storedUsername = parsed?.x_username && typeof parsed.x_username === "string" && parsed.x_username.length > 0 ? parsed.x_username : void 0;
|
|
63
|
+
const usernameWithoutAt = storedUsername?.startsWith("@") ? storedUsername.slice(1) : storedUsername;
|
|
64
|
+
return {
|
|
65
|
+
x_username: usernameWithoutAt
|
|
66
|
+
};
|
|
67
|
+
} catch {
|
|
68
|
+
return void 0;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function isValidUrl(url) {
|
|
72
|
+
if (!url) return false;
|
|
73
|
+
try {
|
|
74
|
+
new URL(url);
|
|
75
|
+
return true;
|
|
76
|
+
} catch {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function isValidXUsername(username) {
|
|
81
|
+
if (!username) return false;
|
|
82
|
+
const cleanUsername = username.startsWith("@") ? username.slice(1) : username;
|
|
83
|
+
return /^[a-zA-Z0-9_]{1,15}$/.test(cleanUsername);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export { PROFILE_CANVAS_STORAGE_KEY, PROFILE_CANVAS_TOPIC, PROFILE_METADATA_STORAGE_KEY, PROFILE_METADATA_TOPIC, PROFILE_PICTURE_STORAGE_KEY, PROFILE_PICTURE_TOPIC, PROFILE_X_USERNAME_STORAGE_KEY, getBytesArgsForStorage, getProfileCanvasStorageArgs, getProfileMetadataStorageArgs, getProfilePictureStorageArgs, getValueArgForStorage, getXUsernameStorageArgs, isValidUrl, isValidXUsername, parseProfileMetadata };
|
|
87
|
+
//# sourceMappingURL=index.mjs.map
|
|
88
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/utils.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Profile-related storage keys\n *\n * Using descriptive keys under 32 bytes to avoid hashing complexity and work seamlessly\n * with existing storage infrastructure. The key includes app prefix and versioning for\n * clarity and future-proofing.\n *\n * NOTE: if we change these keys, users will not be able to see their profile data\n */\nexport const PROFILE_CANVAS_STORAGE_KEY = \"net-beta0.0.1-profile-canvas\";\nexport const PROFILE_PICTURE_STORAGE_KEY = \"net-beta0.0.1-profile-picture\";\nexport const PROFILE_X_USERNAME_STORAGE_KEY =\n \"net-beta0.0.1-profile-x-username\";\nexport const PROFILE_METADATA_STORAGE_KEY = \"net-beta0.0.1-profile-metadata\";\n\n/**\n * Topic strings used when writing to storage\n * These are the second argument to Storage.put()\n */\nexport const PROFILE_PICTURE_TOPIC = \"profile-picture\";\nexport const PROFILE_METADATA_TOPIC = \"profile-metadata\";\nexport const PROFILE_CANVAS_TOPIC = \"profile-canvas\";\n","import { stringToHex } from \"viem\";\nimport { toBytes32 } from \"@net-protocol/core\";\nimport {\n PROFILE_PICTURE_STORAGE_KEY,\n PROFILE_METADATA_STORAGE_KEY,\n PROFILE_CANVAS_STORAGE_KEY,\n PROFILE_PICTURE_TOPIC,\n PROFILE_METADATA_TOPIC,\n PROFILE_CANVAS_TOPIC,\n} from \"./constants\";\nimport type { ProfileMetadata, ProfileStorageArgs } from \"./types\";\n\n/**\n * Convert a string value to hex for storage\n */\nexport function getValueArgForStorage(value: string): `0x${string}` {\n return stringToHex(value);\n}\n\n/**\n * Get storage args (key as bytes32, value as hex)\n */\nexport function getBytesArgsForStorage(\n key: string,\n value: string\n): { bytesKey: `0x${string}`; bytesValue: `0x${string}` } {\n const bytesKey = toBytes32(key) as `0x${string}`;\n const bytesValue = getValueArgForStorage(value);\n return { bytesKey, bytesValue };\n}\n\n/**\n * Prepare transaction arguments for updating profile picture\n *\n * @param imageUrl - The URL of the profile picture\n * @returns Arguments for Storage.put() - [bytesKey, topic, bytesValue]\n *\n * @example\n * ```ts\n * const args = getProfilePictureStorageArgs(\"https://example.com/image.jpg\");\n * // Use with wagmi writeContract:\n * writeContract({\n * abi: STORAGE_CONTRACT.abi,\n * address: STORAGE_CONTRACT.address,\n * functionName: \"put\",\n * args: [args.bytesKey, args.topic, args.bytesValue],\n * });\n * ```\n */\nexport function getProfilePictureStorageArgs(\n imageUrl: string\n): ProfileStorageArgs {\n const { bytesKey, bytesValue } = getBytesArgsForStorage(\n PROFILE_PICTURE_STORAGE_KEY,\n imageUrl\n );\n return {\n bytesKey,\n topic: PROFILE_PICTURE_TOPIC,\n bytesValue,\n };\n}\n\n/**\n * Prepare transaction arguments for updating profile metadata (X username, etc.)\n *\n * @param metadata - Profile metadata object to store\n * @returns Arguments for Storage.put() - [bytesKey, topic, bytesValue]\n *\n * @example\n * ```ts\n * const args = getProfileMetadataStorageArgs({ x_username: \"@myusername\" });\n * writeContract({\n * abi: STORAGE_CONTRACT.abi,\n * address: STORAGE_CONTRACT.address,\n * functionName: \"put\",\n * args: [args.bytesKey, args.topic, args.bytesValue],\n * });\n * ```\n */\nexport function getProfileMetadataStorageArgs(\n metadata: ProfileMetadata\n): ProfileStorageArgs {\n const jsonString = JSON.stringify(metadata);\n const { bytesKey, bytesValue } = getBytesArgsForStorage(\n PROFILE_METADATA_STORAGE_KEY,\n jsonString\n );\n return {\n bytesKey,\n topic: PROFILE_METADATA_TOPIC,\n bytesValue,\n };\n}\n\n/**\n * Prepare transaction arguments for updating X username\n * This is a convenience wrapper around getProfileMetadataStorageArgs\n *\n * @param username - X/Twitter username (with or without @)\n * @returns Arguments for Storage.put()\n */\nexport function getXUsernameStorageArgs(username: string): ProfileStorageArgs {\n // Ensure username has @ prefix for storage\n const normalizedUsername = username.startsWith(\"@\")\n ? username\n : `@${username}`;\n return getProfileMetadataStorageArgs({ x_username: normalizedUsername });\n}\n\n/**\n * Prepare transaction arguments for updating profile canvas (HTML content)\n *\n * @param htmlContent - HTML content for the profile canvas\n * @returns Arguments for Storage.put()\n *\n * @example\n * ```ts\n * const args = getProfileCanvasStorageArgs(\"<div>My custom profile</div>\");\n * writeContract({\n * abi: STORAGE_CONTRACT.abi,\n * address: STORAGE_CONTRACT.address,\n * functionName: \"put\",\n * args: [args.bytesKey, args.topic, args.bytesValue],\n * });\n * ```\n */\nexport function getProfileCanvasStorageArgs(\n htmlContent: string\n): ProfileStorageArgs {\n const { bytesKey, bytesValue } = getBytesArgsForStorage(\n PROFILE_CANVAS_STORAGE_KEY,\n htmlContent\n );\n return {\n bytesKey,\n topic: PROFILE_CANVAS_TOPIC,\n bytesValue,\n };\n}\n\n/**\n * Parse profile metadata JSON and extract profile data\n *\n * @param jsonData - JSON string from storage\n * @returns Parsed profile metadata or undefined if invalid\n */\nexport function parseProfileMetadata(\n jsonData: string\n): ProfileMetadata | undefined {\n try {\n const parsed = JSON.parse(jsonData);\n const storedUsername =\n parsed?.x_username &&\n typeof parsed.x_username === \"string\" &&\n parsed.x_username.length > 0\n ? parsed.x_username\n : undefined;\n\n // Strip @ from stored username for display\n const usernameWithoutAt = storedUsername?.startsWith(\"@\")\n ? storedUsername.slice(1)\n : storedUsername;\n\n return {\n x_username: usernameWithoutAt,\n };\n } catch {\n return undefined;\n }\n}\n\n/**\n * Validate that a string is a valid URL\n */\nexport function isValidUrl(url: string): boolean {\n if (!url) return false;\n try {\n new URL(url);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Validate X/Twitter username format\n * Returns true if valid (alphanumeric and underscores, 1-15 chars)\n */\nexport function isValidXUsername(username: string): boolean {\n if (!username) return false;\n // Remove @ prefix if present\n const cleanUsername = username.startsWith(\"@\") ? username.slice(1) : username;\n // X usernames: 1-15 chars, alphanumeric and underscores only\n return /^[a-zA-Z0-9_]{1,15}$/.test(cleanUsername);\n}\n"]}
|