@farcaster/frame-core 0.0.35 → 0.0.36

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.
@@ -2,11 +2,11 @@ import * as Errors from '../errors'
2
2
  import type { OneOf } from '../internal/types'
3
3
  import type { FrameNotificationDetails } from '../schemas'
4
4
 
5
- export type AddFrameResult = {
5
+ export type AddMiniAppResult = {
6
6
  notificationDetails?: FrameNotificationDetails
7
7
  }
8
8
 
9
- export type AddFrame = () => Promise<AddFrameResult>
9
+ export type AddMiniApp = () => Promise<AddMiniAppResult>
10
10
 
11
11
  type InvalidDomainManifestJsonError = {
12
12
  type: 'invalid_domain_manifest'
@@ -16,23 +16,23 @@ type RejectedByUserJsonError = {
16
16
  type: 'rejected_by_user'
17
17
  }
18
18
 
19
- export type AddFrameJsonError =
19
+ export type AddMiniAppJsonError =
20
20
  | InvalidDomainManifestJsonError
21
21
  | RejectedByUserJsonError
22
22
 
23
- export type AddFrameRejectedReason = AddFrameJsonError['type']
23
+ export type AddMiniAppRejectedReason = AddMiniAppJsonError['type']
24
24
 
25
- export type AddFrameJsonResult = OneOf<
26
- { result: AddFrameResult } | { error: AddFrameJsonError }
25
+ export type AddMiniAppJsonResult = OneOf<
26
+ { result: AddMiniAppResult } | { error: AddMiniAppJsonError }
27
27
  >
28
28
 
29
- export type WireAddFrame = () => Promise<AddFrameJsonResult>
29
+ export type WireAddMiniApp = () => Promise<AddMiniAppJsonResult>
30
30
 
31
31
  /**
32
32
  * Thrown when the frame does not have a valid domain manifest.
33
33
  */
34
34
  export class InvalidDomainManifest extends Errors.BaseError {
35
- override readonly name = 'AddFrame.InvalidDomainManifest'
35
+ override readonly name = 'AddMiniApp.InvalidDomainManifest'
36
36
 
37
37
  constructor() {
38
38
  super('Invalid domain manifest')
@@ -43,7 +43,7 @@ export class InvalidDomainManifest extends Errors.BaseError {
43
43
  * Thrown when add frame action was rejected by the user.
44
44
  */
45
45
  export class RejectedByUser extends Errors.BaseError {
46
- override readonly name = 'AddFrame.RejectedByUser'
46
+ override readonly name = 'AddMiniApp.RejectedByUser'
47
47
 
48
48
  constructor() {
49
49
  super('Add frame rejected by user')
@@ -1,4 +1,4 @@
1
- export * as AddFrame from './AddFrame'
1
+ export * as AddMiniApp from './AddMiniApp'
2
2
  export * as ComposeCast from './ComposeCast'
3
3
  export * as Ready from './Ready'
4
4
  export * as SignIn from './SignIn'
package/src/index.ts CHANGED
@@ -6,3 +6,4 @@ export * as Manifest from './manifest'
6
6
  export * from './types'
7
7
  export * from './schemas'
8
8
  export * from './solana'
9
+ export * from './solanaWire'
package/src/solana.ts CHANGED
@@ -1,11 +1,12 @@
1
- import type {
1
+ import {
2
2
  Connection as SolanaConnection,
3
- SendOptions as SolanaSendOptions,
4
- Transaction as SolanaTransaction,
5
- VersionedTransaction as SolanaVersionedTransaction,
3
+ type SendOptions as SolanaSendOptions,
4
+ type Transaction as SolanaTransaction,
5
+ type VersionedTransaction as SolanaVersionedTransaction,
6
6
  } from '@solana/web3.js'
7
7
 
8
- export type { SolanaConnection }
8
+ export { SolanaConnection }
9
+ export type { SolanaSendOptions }
9
10
 
10
11
  export type SolanaCombinedTransaction =
11
12
  | SolanaTransaction
@@ -24,7 +25,6 @@ export type SolanaSignAndSendTransactionRequestArguments = {
24
25
  method: 'signAndSendTransaction'
25
26
  params: {
26
27
  transaction: SolanaCombinedTransaction
27
- connection: SolanaConnection
28
28
  options?: SolanaSendOptions
29
29
  }
30
30
  }
@@ -59,7 +59,6 @@ export interface SolanaWalletProvider {
59
59
  ): Promise<{ signedTransaction: T }>
60
60
  signAndSendTransaction(input: {
61
61
  transaction: SolanaCombinedTransaction
62
- connection: SolanaConnection
63
62
  }): Promise<{ signature: string }>
64
63
  }
65
64
 
@@ -73,10 +72,37 @@ export const createSolanaWalletProvider = (
73
72
  request({ method: 'signTransaction', params: { transaction } }),
74
73
  signAndSendTransaction: (input: {
75
74
  transaction: SolanaCombinedTransaction
76
- connection: SolanaConnection
77
75
  }) =>
78
76
  request({
79
77
  method: 'signAndSendTransaction',
80
78
  params: input,
81
79
  }),
82
80
  })
81
+
82
+ export type SolanaWireSignAndSendTransactionRequestArguments = {
83
+ method: 'signAndSendTransaction'
84
+ params: {
85
+ transaction: string
86
+ options?: SolanaSendOptions
87
+ }
88
+ }
89
+
90
+ export type SolanaWireSignTransactionRequestArguments = {
91
+ method: 'signTransaction'
92
+ params: {
93
+ transaction: string
94
+ }
95
+ }
96
+
97
+ export type SolanaWireRequestFn = ((
98
+ request: SolanaConnectRequestArguments,
99
+ ) => Promise<{ publicKey: string }>) &
100
+ ((request: SolanaSignMessageRequestArguments) => Promise<{
101
+ signature: string
102
+ }>) &
103
+ ((request: SolanaWireSignAndSendTransactionRequestArguments) => Promise<{
104
+ signature: string
105
+ }>) &
106
+ ((
107
+ request: SolanaWireSignTransactionRequestArguments,
108
+ ) => Promise<{ signedTransaction: string }>)
@@ -0,0 +1,118 @@
1
+ import {
2
+ Transaction as SolanaTransaction,
3
+ VersionedTransaction as SolanaVersionedTransaction,
4
+ } from '@solana/web3.js'
5
+
6
+ import type {
7
+ SolanaCombinedTransaction,
8
+ SolanaConnectRequestArguments,
9
+ SolanaRequestFn,
10
+ SolanaSignAndSendTransactionRequestArguments,
11
+ SolanaSignMessageRequestArguments,
12
+ SolanaSignTransactionRequestArguments,
13
+ SolanaWireRequestFn,
14
+ SolanaWireSignAndSendTransactionRequestArguments,
15
+ SolanaWireSignTransactionRequestArguments,
16
+ } from './solana'
17
+
18
+ function serializeTransaction(transaction: SolanaCombinedTransaction): string {
19
+ return Buffer.from(
20
+ transaction.serialize({
21
+ verifySignatures: false,
22
+ }),
23
+ ).toString('base64')
24
+ }
25
+
26
+ function unserializeTransaction(
27
+ transaction: string,
28
+ ): SolanaCombinedTransaction {
29
+ const bytes = Uint8Array.from(Buffer.from(transaction, 'base64'))
30
+ return (bytes[0] & 0x80) !== 0
31
+ ? SolanaVersionedTransaction.deserialize(bytes)
32
+ : SolanaTransaction.from(bytes)
33
+ }
34
+
35
+ export function wrapSolanaProviderRequest(
36
+ requestFn: SolanaRequestFn,
37
+ ): SolanaWireRequestFn {
38
+ const wrappedFn = async (
39
+ request:
40
+ | SolanaConnectRequestArguments
41
+ | SolanaSignMessageRequestArguments
42
+ | SolanaWireSignAndSendTransactionRequestArguments
43
+ | SolanaWireSignTransactionRequestArguments,
44
+ ) => {
45
+ if (request.method === 'connect') {
46
+ return await requestFn(request)
47
+ }
48
+ if (request.method === 'signMessage') {
49
+ return await requestFn(request)
50
+ }
51
+ if (request.method === 'signAndSendTransaction') {
52
+ const { transaction, options } = request.params
53
+ const params = {
54
+ transaction: unserializeTransaction(transaction),
55
+ options,
56
+ }
57
+ return await requestFn({
58
+ method: 'signAndSendTransaction',
59
+ params,
60
+ })
61
+ }
62
+ if (request.method === 'signTransaction') {
63
+ const { transaction } = request.params
64
+ const params = {
65
+ transaction: unserializeTransaction(transaction),
66
+ }
67
+ const { signedTransaction } = await requestFn({
68
+ method: 'signTransaction',
69
+ params,
70
+ })
71
+ return {
72
+ signedTransaction: serializeTransaction(signedTransaction),
73
+ }
74
+ }
75
+ }
76
+ return wrappedFn as SolanaWireRequestFn
77
+ }
78
+
79
+ export function unwrapSolanaProviderRequest(
80
+ wrappedRequestFn: SolanaWireRequestFn,
81
+ ): SolanaRequestFn {
82
+ const unwrappedFn = async <T extends SolanaCombinedTransaction>(
83
+ request:
84
+ | SolanaConnectRequestArguments
85
+ | SolanaSignMessageRequestArguments
86
+ | SolanaSignAndSendTransactionRequestArguments
87
+ | SolanaSignTransactionRequestArguments<T>,
88
+ ) => {
89
+ if (request.method === 'connect') {
90
+ return await wrappedRequestFn(request)
91
+ }
92
+ if (request.method === 'signMessage') {
93
+ return await wrappedRequestFn(request)
94
+ }
95
+ if (request.method === 'signAndSendTransaction') {
96
+ const { transaction, options } = request.params
97
+ const params = {
98
+ transaction: serializeTransaction(transaction),
99
+ }
100
+ return await wrappedRequestFn({
101
+ method: 'signAndSendTransaction',
102
+ params,
103
+ })
104
+ }
105
+ if (request.method === 'signTransaction') {
106
+ const { transaction } = request.params
107
+ const params = {
108
+ transaction: serializeTransaction(transaction),
109
+ }
110
+ const { signedTransaction } = await wrappedRequestFn({
111
+ method: 'signTransaction',
112
+ params,
113
+ })
114
+ return { signedTransaction: unserializeTransaction(signedTransaction) }
115
+ }
116
+ }
117
+ return unwrappedFn as SolanaRequestFn
118
+ }
package/src/types.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type {
2
- AddFrame,
2
+ AddMiniApp,
3
3
  ComposeCast,
4
4
  Ready,
5
5
  SendToken,
@@ -15,7 +15,7 @@ import type {
15
15
  EventNotificationsDisabled,
16
16
  EventNotificationsEnabled,
17
17
  } from './schemas'
18
- import type { SolanaRequestFn } from './solana'
18
+ import type { SolanaRequestFn, SolanaWireRequestFn } from './solana'
19
19
  import type { Ethereum } from './wallet'
20
20
 
21
21
  export type SetPrimaryButtonOptions = {
@@ -33,6 +33,23 @@ export type SignInOptions = SignIn.SignInOptions
33
33
 
34
34
  export type SetPrimaryButton = (options: SetPrimaryButtonOptions) => void
35
35
 
36
+ export type MiniAppHostCapability =
37
+ | 'wallet.getEvmProvider'
38
+ | 'wallet.getSolanaProvider'
39
+ | 'actions.ready'
40
+ | 'actions.openUrl'
41
+ | 'actions.close'
42
+ | 'actions.setPrimaryButton'
43
+ | 'actions.addMiniApp'
44
+ | 'actions.signIn'
45
+ | 'actions.viewProfile'
46
+ | 'actions.composeCast'
47
+ | 'actions.viewToken'
48
+ | 'actions.sendToken'
49
+ | 'actions.swapToken'
50
+
51
+ export type GetCapabilities = () => Promise<MiniAppHostCapability[]>
52
+
36
53
  export type WireFrameHost = {
37
54
  context: FrameContext
38
55
  close: () => void
@@ -43,8 +60,8 @@ export type WireFrameHost = {
43
60
  ethProviderRequest: Ethereum.EthProvideRequest
44
61
  ethProviderRequestV2: Ethereum.RpcTransport
45
62
  eip6963RequestProvider: () => void
46
- solanaProviderRequest?: SolanaRequestFn
47
- addFrame: AddFrame.WireAddFrame
63
+ solanaProviderRequest?: SolanaWireRequestFn
64
+ addFrame: AddMiniApp.WireAddMiniApp
48
65
  viewProfile: ViewProfile.ViewProfile
49
66
  viewToken: ViewToken.ViewToken
50
67
  sendToken: SendToken.SendToken
@@ -52,6 +69,7 @@ export type WireFrameHost = {
52
69
  composeCast: <close extends boolean | undefined = undefined>(
53
70
  options: ComposeCast.Options<close>,
54
71
  ) => Promise<ComposeCast.Result<close>>
72
+ getCapabilities: GetCapabilities
55
73
  }
56
74
 
57
75
  export type FrameHost = {
@@ -69,7 +87,7 @@ export type FrameHost = {
69
87
  */
70
88
  eip6963RequestProvider: () => void
71
89
  solanaProviderRequest?: SolanaRequestFn
72
- addFrame: AddFrame.AddFrame
90
+ addFrame: AddMiniApp.AddMiniApp
73
91
  viewProfile: ViewProfile.ViewProfile
74
92
  viewToken: ViewToken.ViewToken
75
93
  sendToken: SendToken.SendToken
@@ -77,11 +95,12 @@ export type FrameHost = {
77
95
  composeCast: <close extends boolean | undefined = undefined>(
78
96
  options: ComposeCast.Options<close>,
79
97
  ) => Promise<ComposeCast.Result<close>>
98
+ getCapabilities: GetCapabilities
80
99
  }
81
100
 
82
101
  export type EventFrameAddRejected = {
83
102
  event: 'frame_add_rejected'
84
- reason: AddFrame.AddFrameRejectedReason
103
+ reason: AddMiniApp.AddMiniAppRejectedReason
85
104
  }
86
105
 
87
106
  export type EventPrimaryButtonClicked = {