@farcaster/frame-core 0.0.35 → 0.0.38

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,26 @@ export type SignInOptions = SignIn.SignInOptions
33
33
 
34
34
  export type SetPrimaryButton = (options: SetPrimaryButtonOptions) => void
35
35
 
36
+ export type MiniAppHostCapability =
37
+ | 'wallet.getEthereumProvider'
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
+
53
+ // Returns a list of CAIP-2 identifiers
54
+ export type GetChains = () => Promise<string[]>
55
+
36
56
  export type WireFrameHost = {
37
57
  context: FrameContext
38
58
  close: () => void
@@ -43,8 +63,8 @@ export type WireFrameHost = {
43
63
  ethProviderRequest: Ethereum.EthProvideRequest
44
64
  ethProviderRequestV2: Ethereum.RpcTransport
45
65
  eip6963RequestProvider: () => void
46
- solanaProviderRequest?: SolanaRequestFn
47
- addFrame: AddFrame.WireAddFrame
66
+ solanaProviderRequest?: SolanaWireRequestFn
67
+ addFrame: AddMiniApp.WireAddMiniApp
48
68
  viewProfile: ViewProfile.ViewProfile
49
69
  viewToken: ViewToken.ViewToken
50
70
  sendToken: SendToken.SendToken
@@ -52,6 +72,8 @@ export type WireFrameHost = {
52
72
  composeCast: <close extends boolean | undefined = undefined>(
53
73
  options: ComposeCast.Options<close>,
54
74
  ) => Promise<ComposeCast.Result<close>>
75
+ getCapabilities: GetCapabilities
76
+ getChains: GetChains
55
77
  }
56
78
 
57
79
  export type FrameHost = {
@@ -69,7 +91,7 @@ export type FrameHost = {
69
91
  */
70
92
  eip6963RequestProvider: () => void
71
93
  solanaProviderRequest?: SolanaRequestFn
72
- addFrame: AddFrame.AddFrame
94
+ addFrame: AddMiniApp.AddMiniApp
73
95
  viewProfile: ViewProfile.ViewProfile
74
96
  viewToken: ViewToken.ViewToken
75
97
  sendToken: SendToken.SendToken
@@ -77,11 +99,13 @@ export type FrameHost = {
77
99
  composeCast: <close extends boolean | undefined = undefined>(
78
100
  options: ComposeCast.Options<close>,
79
101
  ) => Promise<ComposeCast.Result<close>>
102
+ getCapabilities: GetCapabilities
103
+ getChains: GetChains
80
104
  }
81
105
 
82
106
  export type EventFrameAddRejected = {
83
107
  event: 'frame_add_rejected'
84
- reason: AddFrame.AddFrameRejectedReason
108
+ reason: AddMiniApp.AddMiniAppRejectedReason
85
109
  }
86
110
 
87
111
  export type EventPrimaryButtonClicked = {