Skip to content

Commit

Permalink
feat: add address to the messageToFrameData (#138)
Browse files Browse the repository at this point in the history
* feat: add address to the `messageVerifyBody`

* chore: regenerate protobufs

* fix: type

* chore: changesets

* fix: have `address` to be defined only in `TransactionContext`

* nit: add docs

* nit: add the missing `transactionId` docs

* fix: hoist `address` from `frameData` to `c`

* tweaks

---------

Co-authored-by: moxey.eth <[email protected]>
  • Loading branch information
dalechyn and jxom authored Mar 13, 2024
1 parent a0bc957 commit d555b1c
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/gentle-dots-talk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"frog": patch
---

Added `address` to `FrameData`. Read more at https://warpcast.com/horsefacts.eth/0xb98e17d8.
1 change: 1 addition & 0 deletions protobufs/schemas/message.proto
Original file line number Diff line number Diff line change
Expand Up @@ -181,4 +181,5 @@ message FrameActionBody {
bytes input_text = 4; // Text input from the user, if present
bytes state = 5; // Serialized frame state value
bytes transaction_id = 6; // Chain-specific transaction ID for tx actions
bytes address = 7; // Chain-specific address for tx actions
}
43 changes: 42 additions & 1 deletion site/pages/reference/frog-frame-context.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,47 @@ app.frame('/', (c) => {
})
```

## transactionId

- **Type**: `string | undefined`

The chain-specific transaction ID. Defined at the `action` frame of `transaction` route.

```tsx twoslash
// @noErrors
/** @jsxImportSource frog/jsx */
// ---cut---
import { Button, Frog } from 'frog'

export const app = new Frog()

app.frame('/', (c) => {
return c.res({
action: '/finish',
image: (
<div style={{ color: 'white', display: 'flex', fontSize: 60 }}>
Perform a transaction
</div>
),
intents: [
<TextInput placeholder="Value (ETH)" />,
<Button.Transaction target="/send-ether">Send Ether</Button.Transaction>,
]
})
})

app.frame('/finish', (c) => {
const { transactionId } = c
return c.res({
image: (
<div style={{ color: 'white', display: 'flex', fontSize: 60 }}>
Transaction ID: {transactionId}
</div>
)
})
})
```

## var

- **Type**: `HonoContext['var']`
Expand Down Expand Up @@ -415,4 +456,4 @@ app.frame('/', (c) => {
const { url } = c // [!code focus]
return c.res({/* ... */})
})
```
```
22 changes: 21 additions & 1 deletion site/pages/reference/frog-transaction-context.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,26 @@ app.transaction('/send-ether', (c) => { // [!code focus]
A transaction handler can also be asynchronous (ie. `async (c) => { ... }{:js}`).
:::

## address

- **Type**: `string | undefined`

The address of a wallet that sends a transaction.

```tsx twoslash
// @noErrors
/** @jsxImportSource frog/jsx */
// ---cut---
import { Button, Frog } from 'frog'

export const app = new Frog()

app.transaction('/send-ether', (c) => {
const { address } = c // [!code focus]
return c.send({/* ... */})
})
```

## buttonIndex

- **Type**: `number`
Expand Down Expand Up @@ -421,4 +441,4 @@ app.transaction('/send-ether', (c) => {
const { url } = c // [!code focus]
return c.send({/* ... */})
})
```
```
8 changes: 8 additions & 0 deletions src/protobufs/generated/message_pb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1457,6 +1457,13 @@ export class FrameActionBody extends Message$1<FrameActionBody> {
*/
transactionId = new Uint8Array(0)

/**
* Chain-specific address for tx actions
*
* @generated from field: bytes address = 7;
*/
address = new Uint8Array(0)

constructor(data?: PartialMessage<FrameActionBody>) {
super()
proto3.util.initPartial(data, this)
Expand All @@ -1481,6 +1488,7 @@ export class FrameActionBody extends Message$1<FrameActionBody> {
kind: 'scalar',
T: 12 /* ScalarType.BYTES */,
},
{ no: 7, name: 'address', kind: 'scalar', T: 12 /* ScalarType.BYTES */ },
])

static fromBinary(
Expand Down
10 changes: 10 additions & 0 deletions src/types/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,16 @@ export type TransactionContext<
//
_state = env['State'],
> = Context<env, path, _state> & {
/**
* Address of the account that is executing a transaction (if any). Maps to:
* - Ethereum: 20-byte address string.
*/
address: string
/**
* Data from the frame that was passed via the POST body.
* The {@link Context`verified`} flag indicates whether the data is trusted or not.
*/
frameData?: Pretty<FrameData>
/**
* Contract transaction request.
*
Expand Down
1 change: 1 addition & 0 deletions src/types/frame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ export type FrameResponseFn = (
) => TypedResponse<FrameResponse>

export type FrameData = {
address?: string | undefined
buttonIndex?: 1 | 2 | 3 | 4 | undefined
castId: { fid: number; hash: string }
fid: number
Expand Down
1 change: 1 addition & 0 deletions src/utils/getTransactionContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export function getTransactionContext<

return {
context: {
address: frameData?.address!,
buttonIndex: frameData?.buttonIndex,
buttonValue,
contract(parameters) {
Expand Down
3 changes: 3 additions & 0 deletions src/utils/verifyFrame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ export async function verifyFrame({
export function messageToFrameData(message: Message): FrameData {
const frameActionBody = message.data?.body.value as FrameActionBody
const frameData: FrameData = {
address: frameActionBody.address
? bytesToHex(frameActionBody.address)
: undefined,
castId: {
fid: Number(frameActionBody.castId?.fid),
hash: bytesToHex(frameActionBody.castId?.hash!),
Expand Down

0 comments on commit d555b1c

Please sign in to comment.