Skip to content

Commit 206eb72

Browse files
authored
feat: support storage lending (#2650)
## Why is this change needed? All the changes required to submit storage lending messages to the protocol. ## Merge Checklist _Choose all relevant options below by adding an `x` now or at any time before submitting for review_ - [x] PR title adheres to the [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) standard - [x] PR has a [changeset](https://github.com/farcasterxyz/hub-monorepo/blob/main/CONTRIBUTING.md#35-adding-changesets) - [x] PR has been tagged with a change label(s) (i.e. documentation, feature, bugfix, or chore) - [ ] PR includes [documentation](https://github.com/farcasterxyz/hub-monorepo/blob/main/CONTRIBUTING.md#32-writing-docs) if necessary. <!-- start pr-codex --> --- ## PR-Codex overview This PR introduces support for storage lending in the system, including new message types and validation for lending operations. ### Detailed summary - Added support for `LendStorage` message type in `packages/shuttle/src/utils.ts`. - Introduced `LendStorageData` and `LendStorageMessage` types in `packages/core/src/protobufs/types.ts`. - Updated `StoreType` to include `STORAGE_LENDS`. - Implemented validation for lending storage in `packages/core/src/validations.ts`. - Enhanced `ContactInfoBody` to include `announceRpcAddress` in multiple files. - Updated related protobufs and message handling for `MergeMessage` events. > The following files were skipped due to too many changes: `packages/core/src/protobufs/generated/request_response.ts`, `packages/hub-web/src/generated/message.ts`, `packages/hub-nodejs/src/generated/message.ts`, `packages/core/src/protobufs/generated/message.ts` > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex -->
1 parent be885bd commit 206eb72

File tree

22 files changed

+1388
-396
lines changed

22 files changed

+1388
-396
lines changed

.changeset/slimy-turtles-camp.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@farcaster/hub-nodejs": patch
3+
"@farcaster/hub-web": patch
4+
"@farcaster/shuttle": patch
5+
"@farcaster/core": patch
6+
---
7+
8+
feat: support storage lending

generate-protos.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
PROTO_REPO=https://github.com/farcasterxyz/snapchain
22
PROTO_PATH=src/proto
3-
PROTO_REV=82903473a69e3cb898c4cba85cbe1a71a469355f # Update this if you want to generate off updated snapchain protos
3+
PROTO_REV=32fa4b1fa7e5ed32e271777d6854ee637678f4a9 # Update this if you want to generate off updated snapchain protos
44

55
TMPDIR=tmp-protogen
66
git clone $PROTO_REPO $TMPDIR
@@ -11,7 +11,7 @@ cd ..
1111

1212
# Determine which files you care about
1313
if [[ "$LIBRARY" == "core" ]]; then
14-
RELEVANT_PROTOS=$(ls $TMPDIR/$PROTO_PATH/*.proto | xargs -n 1 basename | xargs -I{} echo '/defs/{}' | tr '\n' ' ')
14+
RELEVANT_PROTOS="/defs/request_response.proto /defs/rpc.proto /defs/admin_rpc.proto /defs/message.proto /defs/hub_event.proto /defs/onchain_event.proto /defs/username_proof.proto"
1515
OUT_PATH=src/protobufs/generated
1616
CUSTOM_TS_PROTO_OPTS="outputServices=false"
1717
elif [[ "$LIBRARY" == "hub-nodejs" ]]; then

packages/core/src/builders.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ type MessageBodyOptions = Pick<
2727
| "linkCompactStateBody"
2828
| "usernameProofBody"
2929
| "frameActionBody"
30+
| "lendStorageBody"
3031
>;
3132

3233
/** Generic Methods */
@@ -357,3 +358,22 @@ export const makeFrameActionData = (
357358
): HubAsyncResult<protobufs.FrameActionData> => {
358359
return makeMessageData({ frameActionBody: body }, protobufs.MessageType.FRAME_ACTION, dataOptions);
359360
};
361+
362+
export const makeLendStorageData = async (
363+
body: protobufs.LendStorageBody,
364+
dataOptions: MessageDataOptions,
365+
): HubAsyncResult<protobufs.LendStorageData> => {
366+
return makeMessageData({ lendStorageBody: body }, protobufs.MessageType.LEND_STORAGE, dataOptions);
367+
};
368+
369+
export const makeLendStorage = async (
370+
body: protobufs.LendStorageBody,
371+
dataOptions: MessageDataOptions,
372+
signer: Signer,
373+
): HubAsyncResult<protobufs.LendStorageMessage> => {
374+
const data = await makeLendStorageData(body, dataOptions);
375+
if (data.isErr()) {
376+
return err(data.error);
377+
}
378+
return makeMessage(data.value, signer);
379+
};

packages/core/src/limits.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ const STORAGE_UNIT_DEFAULTS = {
3535
[StorageUnitType.UNIT_TYPE_2024]: 25,
3636
[StorageUnitType.UNIT_TYPE_2025]: 5,
3737
},
38+
[StoreType.STORAGE_LENDS]: {
39+
[StorageUnitType.UNIT_TYPE_LEGACY]: 1,
40+
[StorageUnitType.UNIT_TYPE_2024]: 1,
41+
[StorageUnitType.UNIT_TYPE_2025]: 1,
42+
},
3843
[StoreType.NONE]: {
3944
[StorageUnitType.UNIT_TYPE_LEGACY]: 0,
4045
[StorageUnitType.UNIT_TYPE_2024]: 0,

packages/core/src/protobufs/generated/blocks.ts

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,17 @@ export function voteTypeToJSON(object: VoteType): string {
3737

3838
export enum BlockEventType {
3939
HEARTBEAT = 0,
40+
MERGE_MESSAGE = 1,
4041
}
4142

4243
export function blockEventTypeFromJSON(object: any): BlockEventType {
4344
switch (object) {
4445
case 0:
4546
case "BLOCK_EVENT_TYPE_HEARTBEAT":
4647
return BlockEventType.HEARTBEAT;
48+
case 1:
49+
case "BLOCK_EVENT_TYPE_MERGE_MESSAGE":
50+
return BlockEventType.MERGE_MESSAGE;
4751
default:
4852
throw new tsProtoGlobalThis.Error("Unrecognized enum value " + object + " for enum BlockEventType");
4953
}
@@ -53,6 +57,8 @@ export function blockEventTypeToJSON(object: BlockEventType): string {
5357
switch (object) {
5458
case BlockEventType.HEARTBEAT:
5559
return "BLOCK_EVENT_TYPE_HEARTBEAT";
60+
case BlockEventType.MERGE_MESSAGE:
61+
return "BLOCK_EVENT_TYPE_MERGE_MESSAGE";
5662
default:
5763
throw new tsProtoGlobalThis.Error("Unrecognized enum value " + object + " for enum BlockEventType");
5864
}
@@ -140,13 +146,18 @@ export interface ConsensusMessage {
140146
export interface HeartbeatEventBody {
141147
}
142148

149+
export interface MergeMessageEventBody {
150+
message: Message | undefined;
151+
}
152+
143153
export interface BlockEventData {
144154
seqnum: number;
145155
type: BlockEventType;
146156
blockNumber: number;
147157
eventIndex: number;
148158
blockTimestamp: number;
149159
heartbeatEventBody?: HeartbeatEventBody | undefined;
160+
mergeMessageEventBody?: MergeMessageEventBody | undefined;
150161
}
151162

152163
export interface BlockEvent {
@@ -1369,8 +1380,74 @@ export const HeartbeatEventBody = {
13691380
},
13701381
};
13711382

1383+
function createBaseMergeMessageEventBody(): MergeMessageEventBody {
1384+
return { message: undefined };
1385+
}
1386+
1387+
export const MergeMessageEventBody = {
1388+
encode(message: MergeMessageEventBody, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
1389+
if (message.message !== undefined) {
1390+
Message.encode(message.message, writer.uint32(10).fork()).ldelim();
1391+
}
1392+
return writer;
1393+
},
1394+
1395+
decode(input: _m0.Reader | Uint8Array, length?: number): MergeMessageEventBody {
1396+
const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);
1397+
let end = length === undefined ? reader.len : reader.pos + length;
1398+
const message = createBaseMergeMessageEventBody();
1399+
while (reader.pos < end) {
1400+
const tag = reader.uint32();
1401+
switch (tag >>> 3) {
1402+
case 1:
1403+
if (tag != 10) {
1404+
break;
1405+
}
1406+
1407+
message.message = Message.decode(reader, reader.uint32());
1408+
continue;
1409+
}
1410+
if ((tag & 7) == 4 || tag == 0) {
1411+
break;
1412+
}
1413+
reader.skipType(tag & 7);
1414+
}
1415+
return message;
1416+
},
1417+
1418+
fromJSON(object: any): MergeMessageEventBody {
1419+
return { message: isSet(object.message) ? Message.fromJSON(object.message) : undefined };
1420+
},
1421+
1422+
toJSON(message: MergeMessageEventBody): unknown {
1423+
const obj: any = {};
1424+
message.message !== undefined && (obj.message = message.message ? Message.toJSON(message.message) : undefined);
1425+
return obj;
1426+
},
1427+
1428+
create<I extends Exact<DeepPartial<MergeMessageEventBody>, I>>(base?: I): MergeMessageEventBody {
1429+
return MergeMessageEventBody.fromPartial(base ?? {});
1430+
},
1431+
1432+
fromPartial<I extends Exact<DeepPartial<MergeMessageEventBody>, I>>(object: I): MergeMessageEventBody {
1433+
const message = createBaseMergeMessageEventBody();
1434+
message.message = (object.message !== undefined && object.message !== null)
1435+
? Message.fromPartial(object.message)
1436+
: undefined;
1437+
return message;
1438+
},
1439+
};
1440+
13721441
function createBaseBlockEventData(): BlockEventData {
1373-
return { seqnum: 0, type: 0, blockNumber: 0, eventIndex: 0, blockTimestamp: 0, heartbeatEventBody: undefined };
1442+
return {
1443+
seqnum: 0,
1444+
type: 0,
1445+
blockNumber: 0,
1446+
eventIndex: 0,
1447+
blockTimestamp: 0,
1448+
heartbeatEventBody: undefined,
1449+
mergeMessageEventBody: undefined,
1450+
};
13741451
}
13751452

13761453
export const BlockEventData = {
@@ -1393,6 +1470,9 @@ export const BlockEventData = {
13931470
if (message.heartbeatEventBody !== undefined) {
13941471
HeartbeatEventBody.encode(message.heartbeatEventBody, writer.uint32(50).fork()).ldelim();
13951472
}
1473+
if (message.mergeMessageEventBody !== undefined) {
1474+
MergeMessageEventBody.encode(message.mergeMessageEventBody, writer.uint32(58).fork()).ldelim();
1475+
}
13961476
return writer;
13971477
},
13981478

@@ -1445,6 +1525,13 @@ export const BlockEventData = {
14451525

14461526
message.heartbeatEventBody = HeartbeatEventBody.decode(reader, reader.uint32());
14471527
continue;
1528+
case 7:
1529+
if (tag != 58) {
1530+
break;
1531+
}
1532+
1533+
message.mergeMessageEventBody = MergeMessageEventBody.decode(reader, reader.uint32());
1534+
continue;
14481535
}
14491536
if ((tag & 7) == 4 || tag == 0) {
14501537
break;
@@ -1464,6 +1551,9 @@ export const BlockEventData = {
14641551
heartbeatEventBody: isSet(object.heartbeatEventBody)
14651552
? HeartbeatEventBody.fromJSON(object.heartbeatEventBody)
14661553
: undefined,
1554+
mergeMessageEventBody: isSet(object.mergeMessageEventBody)
1555+
? MergeMessageEventBody.fromJSON(object.mergeMessageEventBody)
1556+
: undefined,
14671557
};
14681558
},
14691559

@@ -1477,6 +1567,9 @@ export const BlockEventData = {
14771567
message.heartbeatEventBody !== undefined && (obj.heartbeatEventBody = message.heartbeatEventBody
14781568
? HeartbeatEventBody.toJSON(message.heartbeatEventBody)
14791569
: undefined);
1570+
message.mergeMessageEventBody !== undefined && (obj.mergeMessageEventBody = message.mergeMessageEventBody
1571+
? MergeMessageEventBody.toJSON(message.mergeMessageEventBody)
1572+
: undefined);
14801573
return obj;
14811574
},
14821575

@@ -1494,6 +1587,10 @@ export const BlockEventData = {
14941587
message.heartbeatEventBody = (object.heartbeatEventBody !== undefined && object.heartbeatEventBody !== null)
14951588
? HeartbeatEventBody.fromPartial(object.heartbeatEventBody)
14961589
: undefined;
1590+
message.mergeMessageEventBody =
1591+
(object.mergeMessageEventBody !== undefined && object.mergeMessageEventBody !== null)
1592+
? MergeMessageEventBody.fromPartial(object.mergeMessageEventBody)
1593+
: undefined;
14971594
return message;
14981595
},
14991596
};

0 commit comments

Comments
 (0)