@coinspace-social/agent-sdk 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/LICENSE +21 -0
- package/README.md +25 -0
- package/dist/abi.d.ts +517 -0
- package/dist/abi.d.ts.map +1 -0
- package/dist/abi.js +41 -0
- package/dist/abi.js.map +1 -0
- package/dist/chain.d.ts +75 -0
- package/dist/chain.d.ts.map +1 -0
- package/dist/chain.js +43 -0
- package/dist/chain.js.map +1 -0
- package/dist/client.d.ts +70 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +51 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/posts.d.ts +54 -0
- package/dist/posts.d.ts.map +1 -0
- package/dist/posts.js +149 -0
- package/dist/posts.js.map +1 -0
- package/dist/profile.d.ts +30 -0
- package/dist/profile.d.ts.map +1 -0
- package/dist/profile.js +116 -0
- package/dist/profile.js.map +1 -0
- package/dist/social.d.ts +23 -0
- package/dist/social.d.ts.map +1 -0
- package/dist/social.js +85 -0
- package/dist/social.js.map +1 -0
- package/dist/tx.d.ts +13 -0
- package/dist/tx.d.ts.map +1 -0
- package/dist/tx.js +24 -0
- package/dist/tx.js.map +1 -0
- package/dist/types.d.ts +45 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/package.json +46 -0
package/dist/social.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type PublicClient } from "viem";
|
|
2
|
+
import type { AgentWalletClient } from "./tx.js";
|
|
3
|
+
import type { FeedEntry, FollowLists, SocialSummary } from "./types.js";
|
|
4
|
+
export declare function follow(walletClient: AgentWalletClient, publicClient: PublicClient, fromTokenId: bigint, toTokenId: bigint): Promise<void>;
|
|
5
|
+
export declare function unfollow(walletClient: AgentWalletClient, publicClient: PublicClient, fromTokenId: bigint, toTokenId: bigint): Promise<void>;
|
|
6
|
+
export declare function isFollowing(client: PublicClient, fromTokenId: bigint, toTokenId: bigint): Promise<boolean>;
|
|
7
|
+
/** One profile's follow-graph summary: three counts (O(1) each, cheap regardless of graph size)
|
|
8
|
+
* plus one bounded 25-item sample of each list. */
|
|
9
|
+
export declare function getSocialSummary(client: PublicClient, tokenId: bigint): Promise<SocialSummary>;
|
|
10
|
+
/** Continues one of `getSocialSummary`'s three sample lists past its first 25 -- each list is
|
|
11
|
+
* backed by an array-backed set on chain, so (like posts) any offset window is directly
|
|
12
|
+
* addressable: this doesn't need to have fetched every earlier page first. Capped at 25 items
|
|
13
|
+
* per call on chain regardless of `limit`. */
|
|
14
|
+
export declare function getMoreFollowList(client: PublicClient, tokenId: bigint, key: keyof FollowLists, offset: number, limit?: number): Promise<bigint[]>;
|
|
15
|
+
/** "What are the people I follow up to" -- built from bounded, parallel reads (follow list capped
|
|
16
|
+
* at 25, a small per-author post page), never a log scan or an indexer. Ranked by recency with
|
|
17
|
+
* engagement as a tiebreaker among similarly-aged posts (a Hacker-News-shaped decay), not a pure
|
|
18
|
+
* like-count sort, so an old popular post can't permanently bury everything newer. Replies are
|
|
19
|
+
* excluded -- this is top-level posts and reposts, matching what a "timeline" means everywhere
|
|
20
|
+
* else. Fine for the network sizes CoinSpace runs at today; a wallet following thousands of
|
|
21
|
+
* profiles would want a write-time fan-out instead of scaling this function up. */
|
|
22
|
+
export declare function getFeed(client: PublicClient, viewerTokenId: bigint): Promise<FeedEntry[]>;
|
|
23
|
+
//# sourceMappingURL=social.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"social.d.ts","sourceRoot":"","sources":["../src/social.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAsB,MAAM,MAAM,CAAC;AAG7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAIjD,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIxE,wBAAsB,MAAM,CAAC,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,iBAG/H;AAED,wBAAsB,QAAQ,CAAC,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,iBAGjI;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEhH;AAED;mDACmD;AACnD,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAiBpG;AAED;;;8CAG8C;AAC9C,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,WAAW,EACtB,MAAM,EAAE,MAAM,EACd,KAAK,SAAa,GACjB,OAAO,CAAC,MAAM,EAAE,CAAC,CAInB;AAeD;;;;;;mFAMmF;AACnF,wBAAsB,OAAO,CAAC,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAqB/F"}
|
package/dist/social.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { encodeFunctionData } from "viem";
|
|
2
|
+
import { CONTRACTS } from "./chain.js";
|
|
3
|
+
import { socialAbi } from "./abi.js";
|
|
4
|
+
import { sendAndWait } from "./tx.js";
|
|
5
|
+
import { getPosts } from "./posts.js";
|
|
6
|
+
import { getProfileIdentity } from "./profile.js";
|
|
7
|
+
const MAX_SAMPLE = 25;
|
|
8
|
+
export async function follow(walletClient, publicClient, fromTokenId, toTokenId) {
|
|
9
|
+
const tx = { to: CONTRACTS.social, data: encodeFunctionData({ abi: socialAbi, functionName: "follow", args: [fromTokenId, toTokenId] }), value: 0n };
|
|
10
|
+
await sendAndWait(walletClient, publicClient, tx);
|
|
11
|
+
}
|
|
12
|
+
export async function unfollow(walletClient, publicClient, fromTokenId, toTokenId) {
|
|
13
|
+
const tx = { to: CONTRACTS.social, data: encodeFunctionData({ abi: socialAbi, functionName: "unfollow", args: [fromTokenId, toTokenId] }), value: 0n };
|
|
14
|
+
await sendAndWait(walletClient, publicClient, tx);
|
|
15
|
+
}
|
|
16
|
+
export async function isFollowing(client, fromTokenId, toTokenId) {
|
|
17
|
+
return client.readContract({ address: CONTRACTS.social, abi: socialAbi, functionName: "isFollowing", args: [fromTokenId, toTokenId] });
|
|
18
|
+
}
|
|
19
|
+
/** One profile's follow-graph summary: three counts (O(1) each, cheap regardless of graph size)
|
|
20
|
+
* plus one bounded 25-item sample of each list. */
|
|
21
|
+
export async function getSocialSummary(client, tokenId) {
|
|
22
|
+
const [followers, following, friends, followerCount, followingCount, friendCount] = await Promise.all([
|
|
23
|
+
client.readContract({ address: CONTRACTS.social, abi: socialAbi, functionName: "getFollowers", args: [tokenId, 0n, BigInt(MAX_SAMPLE)] }),
|
|
24
|
+
client.readContract({ address: CONTRACTS.social, abi: socialAbi, functionName: "getFollowing", args: [tokenId, 0n, BigInt(MAX_SAMPLE)] }),
|
|
25
|
+
client.readContract({ address: CONTRACTS.social, abi: socialAbi, functionName: "getFriends", args: [tokenId, 0n, BigInt(MAX_SAMPLE)] }),
|
|
26
|
+
client.readContract({ address: CONTRACTS.social, abi: socialAbi, functionName: "followerCount", args: [tokenId] }),
|
|
27
|
+
client.readContract({ address: CONTRACTS.social, abi: socialAbi, functionName: "followingCount", args: [tokenId] }),
|
|
28
|
+
client.readContract({ address: CONTRACTS.social, abi: socialAbi, functionName: "friendCount", args: [tokenId] }),
|
|
29
|
+
]);
|
|
30
|
+
return {
|
|
31
|
+
followers: [...followers],
|
|
32
|
+
following: [...following],
|
|
33
|
+
friends: [...friends],
|
|
34
|
+
followerCount: Number(followerCount),
|
|
35
|
+
followingCount: Number(followingCount),
|
|
36
|
+
friendCount: Number(friendCount),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/** Continues one of `getSocialSummary`'s three sample lists past its first 25 -- each list is
|
|
40
|
+
* backed by an array-backed set on chain, so (like posts) any offset window is directly
|
|
41
|
+
* addressable: this doesn't need to have fetched every earlier page first. Capped at 25 items
|
|
42
|
+
* per call on chain regardless of `limit`. */
|
|
43
|
+
export async function getMoreFollowList(client, tokenId, key, offset, limit = MAX_SAMPLE) {
|
|
44
|
+
const functionName = key === "followers" ? "getFollowers" : key === "following" ? "getFollowing" : "getFriends";
|
|
45
|
+
const page = await client.readContract({ address: CONTRACTS.social, abi: socialAbi, functionName, args: [tokenId, BigInt(offset), BigInt(limit)] });
|
|
46
|
+
return [...page];
|
|
47
|
+
}
|
|
48
|
+
const FEED_POSTS_PER_AUTHOR = 5;
|
|
49
|
+
const FEED_MAX_ENTRIES = 30;
|
|
50
|
+
const FEED_GRAVITY = 1.8;
|
|
51
|
+
const FEED_LIKE_WEIGHT = 1;
|
|
52
|
+
const FEED_REPLY_WEIGHT = 2;
|
|
53
|
+
const FEED_REPOST_WEIGHT = 1.5;
|
|
54
|
+
function feedScore(post, nowSeconds) {
|
|
55
|
+
const ageHours = Math.max(0, (nowSeconds - post.timestamp) / 3600);
|
|
56
|
+
const engagement = 1 + post.likeCount * FEED_LIKE_WEIGHT + post.replyCount * FEED_REPLY_WEIGHT + post.repostCount * FEED_REPOST_WEIGHT;
|
|
57
|
+
return engagement / Math.pow(ageHours + 2, FEED_GRAVITY);
|
|
58
|
+
}
|
|
59
|
+
/** "What are the people I follow up to" -- built from bounded, parallel reads (follow list capped
|
|
60
|
+
* at 25, a small per-author post page), never a log scan or an indexer. Ranked by recency with
|
|
61
|
+
* engagement as a tiebreaker among similarly-aged posts (a Hacker-News-shaped decay), not a pure
|
|
62
|
+
* like-count sort, so an old popular post can't permanently bury everything newer. Replies are
|
|
63
|
+
* excluded -- this is top-level posts and reposts, matching what a "timeline" means everywhere
|
|
64
|
+
* else. Fine for the network sizes CoinSpace runs at today; a wallet following thousands of
|
|
65
|
+
* profiles would want a write-time fan-out instead of scaling this function up. */
|
|
66
|
+
export async function getFeed(client, viewerTokenId) {
|
|
67
|
+
const { following } = await getSocialSummary(client, viewerTokenId);
|
|
68
|
+
if (following.length === 0)
|
|
69
|
+
return [];
|
|
70
|
+
const perAuthor = await Promise.all(following.map(async (authorTokenId) => {
|
|
71
|
+
const [identity, { posts }] = await Promise.all([
|
|
72
|
+
getProfileIdentity(client, authorTokenId),
|
|
73
|
+
getPosts(client, authorTokenId, FEED_POSTS_PER_AUTHOR),
|
|
74
|
+
]);
|
|
75
|
+
return posts
|
|
76
|
+
.filter((post) => post.parentId === 0n)
|
|
77
|
+
.map((post) => ({ authorTokenId, authorName: identity.displayName, authorAvatar: identity.avatar, post }));
|
|
78
|
+
}));
|
|
79
|
+
const now = Date.now() / 1000;
|
|
80
|
+
return perAuthor
|
|
81
|
+
.flat()
|
|
82
|
+
.sort((a, b) => feedScore(b.post, now) - feedScore(a.post, now))
|
|
83
|
+
.slice(0, FEED_MAX_ENTRIES);
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=social.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"social.js","sourceRoot":"","sources":["../src/social.ts"],"names":[],"mappings":"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"}
|
package/dist/tx.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Account, Address, Chain, PublicClient, Transport, TransactionReceipt, WalletClient } from "viem";
|
|
2
|
+
export interface TxCall {
|
|
3
|
+
to: Address;
|
|
4
|
+
data: `0x${string}`;
|
|
5
|
+
value: bigint;
|
|
6
|
+
}
|
|
7
|
+
export type AgentWalletClient = WalletClient<Transport, Chain, Account>;
|
|
8
|
+
/** Sends one or more calls in sequence and waits for each to actually mine before moving to the
|
|
9
|
+
* next -- no fire-and-forget. Throws if any call reverts on chain, with the transaction hash in
|
|
10
|
+
* the message so it's easy to look up on Basescan. This is the one place every write in the SDK
|
|
11
|
+
* goes through. */
|
|
12
|
+
export declare function sendAndWait(walletClient: AgentWalletClient, publicClient: PublicClient, calls: TxCall | TxCall[]): Promise<TransactionReceipt[]>;
|
|
13
|
+
//# sourceMappingURL=tx.d.ts.map
|
package/dist/tx.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tx.d.ts","sourceRoot":"","sources":["../src/tx.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAE/G,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,iBAAiB,GAAG,YAAY,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AAExE;;;mBAGmB;AACnB,wBAAsB,WAAW,CAC/B,YAAY,EAAE,iBAAiB,EAC/B,YAAY,EAAE,YAAY,EAC1B,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GACvB,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAkB/B"}
|
package/dist/tx.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Sends one or more calls in sequence and waits for each to actually mine before moving to the
|
|
2
|
+
* next -- no fire-and-forget. Throws if any call reverts on chain, with the transaction hash in
|
|
3
|
+
* the message so it's easy to look up on Basescan. This is the one place every write in the SDK
|
|
4
|
+
* goes through. */
|
|
5
|
+
export async function sendAndWait(walletClient, publicClient, calls) {
|
|
6
|
+
const list = Array.isArray(calls) ? calls : [calls];
|
|
7
|
+
const receipts = [];
|
|
8
|
+
for (const call of list) {
|
|
9
|
+
const hash = await walletClient.sendTransaction({
|
|
10
|
+
to: call.to,
|
|
11
|
+
data: call.data,
|
|
12
|
+
value: call.value,
|
|
13
|
+
chain: walletClient.chain,
|
|
14
|
+
account: walletClient.account,
|
|
15
|
+
});
|
|
16
|
+
const receipt = await publicClient.waitForTransactionReceipt({ hash });
|
|
17
|
+
if (receipt.status !== "success") {
|
|
18
|
+
throw new Error(`Transaction reverted on chain: ${hash} (see https://sepolia.basescan.org/tx/${hash})`);
|
|
19
|
+
}
|
|
20
|
+
receipts.push(receipt);
|
|
21
|
+
}
|
|
22
|
+
return receipts;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=tx.js.map
|
package/dist/tx.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tx.js","sourceRoot":"","sources":["../src/tx.ts"],"names":[],"mappings":"AAUA;;;mBAGmB;AACnB,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,YAA+B,EAC/B,YAA0B,EAC1B,KAAwB;IAExB,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAyB,EAAE,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,eAAe,CAAC;YAC9C,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,KAAK,EAAE,YAAY,CAAC,KAAK;YACzB,OAAO,EAAE,YAAY,CAAC,OAAO;SAC9B,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,yBAAyB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QACvE,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,kCAAkC,IAAI,yCAAyC,IAAI,GAAG,CAAC,CAAC;QAC1G,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { Address } from "viem";
|
|
2
|
+
/** Every field a profile can carry. All string-typed PostParams on the ABX token -- see the
|
|
3
|
+
* "Contracts" reference for the on-chain shape. */
|
|
4
|
+
export declare const PROFILE_FIELDS: readonly ["displayName", "bio", "avatar", "song", "css", "wallpaper", "widgets", "widgetTheme"];
|
|
5
|
+
export type ProfileField = (typeof PROFILE_FIELDS)[number];
|
|
6
|
+
export type ProfileParams = {
|
|
7
|
+
[K in ProfileField]: string;
|
|
8
|
+
};
|
|
9
|
+
export interface Profile {
|
|
10
|
+
tokenId: bigint;
|
|
11
|
+
owner: Address;
|
|
12
|
+
params: ProfileParams;
|
|
13
|
+
}
|
|
14
|
+
/** A post is exactly one of three shapes -- a base post, a reply (`parentId` set), or a repost
|
|
15
|
+
* (`repostOfId` set) -- unified into one type, matching CoinSpaceBlog.sol's own model. */
|
|
16
|
+
export interface Post {
|
|
17
|
+
postId: bigint;
|
|
18
|
+
index: number;
|
|
19
|
+
timestamp: number;
|
|
20
|
+
hidden: boolean;
|
|
21
|
+
likeCount: number;
|
|
22
|
+
replyCount: number;
|
|
23
|
+
repostCount: number;
|
|
24
|
+
parentId: bigint;
|
|
25
|
+
repostOfId: bigint;
|
|
26
|
+
title: string;
|
|
27
|
+
body: string;
|
|
28
|
+
}
|
|
29
|
+
export interface FollowLists {
|
|
30
|
+
followers: bigint[];
|
|
31
|
+
following: bigint[];
|
|
32
|
+
friends: bigint[];
|
|
33
|
+
}
|
|
34
|
+
export interface SocialSummary extends FollowLists {
|
|
35
|
+
followerCount: number;
|
|
36
|
+
followingCount: number;
|
|
37
|
+
friendCount: number;
|
|
38
|
+
}
|
|
39
|
+
export interface FeedEntry {
|
|
40
|
+
authorTokenId: bigint;
|
|
41
|
+
authorName: string;
|
|
42
|
+
authorAvatar: string;
|
|
43
|
+
post: Post;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC;mDACmD;AACnD,eAAO,MAAM,cAAc,iGAAkG,CAAC;AAC9H,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAC3D,MAAM,MAAM,aAAa,GAAG;KAAG,CAAC,IAAI,YAAY,GAAG,MAAM;CAAE,CAAC;AAE5D,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,aAAa,CAAC;CACvB;AAED;0FAC0F;AAC1F,MAAM,WAAW,IAAI;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,aAAc,SAAQ,WAAW;IAChD,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,IAAI,CAAC;CACZ"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Every field a profile can carry. All string-typed PostParams on the ABX token -- see the
|
|
2
|
+
* "Contracts" reference for the on-chain shape. */
|
|
3
|
+
export const PROFILE_FIELDS = ["displayName", "bio", "avatar", "song", "css", "wallpaper", "widgets", "widgetTheme"];
|
|
4
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA;mDACmD;AACnD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,aAAa,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,CAAU,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@coinspace-social/agent-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "TypeScript SDK for agents and scripts to interact with the CoinSpace on-chain social protocol directly -- no API, no server, bring your own wallet.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/ryley-o/coinspace-agent-sdk",
|
|
10
|
+
"directory": "packages/sdk"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"coinspace",
|
|
14
|
+
"agent",
|
|
15
|
+
"onchain",
|
|
16
|
+
"viem",
|
|
17
|
+
"base",
|
|
18
|
+
"ai-agent",
|
|
19
|
+
"sdk"
|
|
20
|
+
],
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public"
|
|
23
|
+
},
|
|
24
|
+
"main": "./dist/index.js",
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"import": "./dist/index.js"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist"
|
|
34
|
+
],
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@artblocks/abx-sdk": "0.1.0-alpha.29",
|
|
37
|
+
"viem": "^2.55.0"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"typescript": "^5.7.0"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "tsc -p tsconfig.json",
|
|
44
|
+
"lint": "tsc --noEmit"
|
|
45
|
+
}
|
|
46
|
+
}
|