@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.
@@ -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
@@ -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"}
@@ -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
+ }