@joeywallet/gemwallet-compat 0.2.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.
package/src/types.ts ADDED
@@ -0,0 +1,190 @@
1
+ /**
2
+ * GemWallet's public types, restated.
3
+ *
4
+ * Copied by shape from `@gemwallet/api@3.8.0` rather than imported, so a
5
+ * migrating dapp can delete the `@gemwallet/api` dependency entirely — which is
6
+ * the whole point of this package. Field names, casing and optionality are
7
+ * deliberately identical to GemWallet's, including the parts that differ from
8
+ * XRPL's own JSON (lowercase `memos`, `{ memo: { memoData } }` instead of
9
+ * `{ Memo: { MemoData } }`); `../src/convert.ts` does the translation.
10
+ */
11
+ import type { Amount, IssuedCurrencyAmount, Path, TransactionLike } from '@joeywallet/wallet-sdk'
12
+
13
+ export type { Amount, IssuedCurrencyAmount, Path }
14
+
15
+ /** GemWallet's envelope discriminant. `reject` means the user declined. */
16
+ export type ResponseType = 'response' | 'reject'
17
+
18
+ export interface BaseResponse<T> {
19
+ type: ResponseType
20
+ result?: T
21
+ }
22
+
23
+ /** GemWallet's own `Network` enum values, as string literals. */
24
+ export type Network = 'Mainnet' | 'Testnet' | 'Devnet' | 'Custom'
25
+
26
+ export type Chain = 'XRPL' | 'XAHAU'
27
+
28
+ /** GemWallet spells memos lowercase and singular-nested. */
29
+ export interface Memo {
30
+ memo: {
31
+ memoType?: string
32
+ memoData?: string
33
+ memoFormat?: string
34
+ }
35
+ }
36
+
37
+ export interface Signer {
38
+ signer: {
39
+ account: string
40
+ txnSignature: string
41
+ signingPubKey: string
42
+ }
43
+ }
44
+
45
+ export type PaymentFlags = number | object
46
+ export type TrustSetFlags = number | object
47
+
48
+ export interface BaseTransactionRequest {
49
+ fee?: string
50
+ sequence?: number
51
+ accountTxnID?: string
52
+ lastLedgerSequence?: number
53
+ memos?: Memo[]
54
+ networkID?: number
55
+ signers?: Signer[]
56
+ sourceTag?: number
57
+ signingPubKey?: string
58
+ ticketSequence?: number
59
+ txnSignature?: string
60
+ }
61
+
62
+ export interface SendPaymentRequest extends BaseTransactionRequest {
63
+ amount: Amount
64
+ destination: string
65
+ destinationTag?: number
66
+ invoiceID?: string
67
+ paths?: Path[]
68
+ sendMax?: Amount
69
+ deliverMin?: Amount
70
+ flags?: PaymentFlags
71
+ }
72
+
73
+ export interface SetTrustlineRequest extends BaseTransactionRequest {
74
+ limitAmount: IssuedCurrencyAmount
75
+ qualityIn?: number
76
+ qualityOut?: number
77
+ flags?: TrustSetFlags
78
+ }
79
+
80
+ /**
81
+ * GemWallet types this as xrpl.js's `SubmittableTransaction`. Restated as the
82
+ * SDK's structural constraint so this package stays free of xrpl.js, and left
83
+ * generic so a caller who has xrpl.js keeps full checking on their own side.
84
+ */
85
+ export type Transaction = TransactionLike
86
+
87
+ export type TransactionWithID = TransactionLike & { ID?: string }
88
+
89
+ export interface SignTransactionRequest {
90
+ transaction: Transaction
91
+ }
92
+
93
+ export interface SubmitTransactionRequest {
94
+ transaction: Transaction
95
+ }
96
+
97
+ export type TransactionErrorHandling = 'abort' | 'continue'
98
+
99
+ export const DEFAULT_SUBMIT_TX_BULK_ON_ERROR: TransactionErrorHandling = 'abort'
100
+
101
+ export interface SubmitBulkTransactionsRequest {
102
+ transactions: TransactionWithID[]
103
+ /**
104
+ * Accepted for source compatibility. Joey always waits for the hashes it
105
+ * reports, so `false` does not make the call return early.
106
+ */
107
+ waitForHashes?: boolean
108
+ /**
109
+ * Accepted for source compatibility and ignored. Joey always aborts the batch
110
+ * at the first failure, which is GemWallet's own default and the safer of the
111
+ * two behaviours — `'continue'` would keep signing after a transaction the
112
+ * user or the ledger already refused.
113
+ */
114
+ onError?: TransactionErrorHandling
115
+ }
116
+
117
+ export interface IsInstalledResponse {
118
+ result: { isInstalled: boolean }
119
+ }
120
+
121
+ export interface GetAddressResponse extends BaseResponse<{ address: string }> {}
122
+
123
+ export interface GetPublicKeyResponse
124
+ extends BaseResponse<{ address: string; publicKey: string }> {}
125
+
126
+ export interface GetNetworkResponse
127
+ extends BaseResponse<{ chain: string; network: Network; websocket: string }> {}
128
+
129
+ export interface SignMessageResponse extends BaseResponse<{ signedMessage: string }> {}
130
+
131
+ export interface SendPaymentResponse extends BaseResponse<{ hash: string }> {}
132
+
133
+ export interface SetTrustlineResponse extends BaseResponse<{ hash: string }> {}
134
+
135
+ export interface SignTransactionResponse
136
+ extends BaseResponse<{ signature: string | null | undefined }> {}
137
+
138
+ export interface SubmitTransactionResponse extends BaseResponse<{ hash: string }> {}
139
+
140
+ export interface TransactionBulkResponse {
141
+ id?: string
142
+ accepted?: boolean
143
+ hash?: string
144
+ error?: string
145
+ }
146
+
147
+ export interface SubmitBulkTransactionsResponse
148
+ extends BaseResponse<{ transactions: TransactionBulkResponse[] }> {}
149
+
150
+ /* -------------------------------------------------------------------- events */
151
+
152
+ export interface EventLoginResponse {
153
+ loggedIn: boolean
154
+ }
155
+
156
+ export interface EventLogoutResponse {
157
+ loggedIn: boolean
158
+ }
159
+
160
+ export interface EventNetworkChangedResponse {
161
+ network: { name: string; server: string; description: string }
162
+ }
163
+
164
+ export interface EventWalletChangedResponse {
165
+ wallet: { publicAddress: string }
166
+ }
167
+
168
+ /**
169
+ * Event names.
170
+ *
171
+ * `@gemwallet/api`'s `on()` compares against the raw wire constants
172
+ * (`EVENT_LOGIN` and friends), while GemWallet's documentation and most dapp
173
+ * code use the short names. Both are accepted.
174
+ */
175
+ export type GemEventType =
176
+ | 'login'
177
+ | 'logout'
178
+ | 'networkChanged'
179
+ | 'walletChanged'
180
+ | 'EVENT_LOGIN'
181
+ | 'EVENT_LOGOUT'
182
+ | 'EVENT_NETWORK_CHANGED'
183
+ | 'EVENT_WALLET_CHANGED'
184
+
185
+ export interface GemEventPayloadMap {
186
+ login: EventLoginResponse
187
+ logout: EventLogoutResponse
188
+ networkChanged: EventNetworkChangedResponse
189
+ walletChanged: EventWalletChangedResponse
190
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * The GemWallet methods Joey will not implement.
3
+ *
4
+ * `setRegularKey`, `setHook` and `setAccount` are account-control transactions.
5
+ * `SetRegularKey` combined with `AccountSet asfDisableMaster` hands the caller
6
+ * permanent, unrevokable control of an XRPL account, and the balance looks
7
+ * untouched while it drains over later ledgers; `SetHook` installs code that
8
+ * runs on every future transaction. Exposing any of them to an arbitrary
9
+ * website is how XRPL accounts get taken over, and no approval dialog makes
10
+ * that safe, because the user cannot evaluate the consequence from the
11
+ * transaction JSON.
12
+ *
13
+ * Joey supports all three from its own UI, behind a typed confirmation and
14
+ * step-up authentication. It does not expose them to dapps at all — the
15
+ * extension hard-rejects `SetRegularKey`, `SignerListSet` and `AccountDelete`
16
+ * at the deserialisation layer, so even a hand-rolled `signTransaction` call
17
+ * carrying one of these transaction types fails.
18
+ *
19
+ * `signMessage` is here for a different reason: Joey has no raw
20
+ * message-signing method at all. See below.
21
+ *
22
+ * The three account-control functions throw synchronously rather than returning
23
+ * a rejected promise or a `{ type: 'reject' }` envelope, so a migrating dapp
24
+ * finds out at the first call in development instead of shipping a silently
25
+ * dead code path.
26
+ */
27
+ export const UNSUPPORTED_METHODS = [
28
+ 'setRegularKey',
29
+ 'setHook',
30
+ 'setAccount',
31
+ 'signMessage',
32
+ ] as const
33
+
34
+ export type UnsupportedMethod = (typeof UNSUPPORTED_METHODS)[number]
35
+
36
+ const REASONS: Record<UnsupportedMethod, string> = {
37
+ setRegularKey:
38
+ 'SetRegularKey assigns an alternate signing key to the account. Together with AccountSet asfDisableMaster it is an irreversible account takeover, so Joey never exposes it to a website. Change your account keys from the Joey Wallet UI instead.',
39
+ setHook:
40
+ 'SetHook installs code that runs on every future transaction for the account. Joey never exposes it to a website. Install hooks from the Joey Wallet UI instead.',
41
+ setAccount:
42
+ 'AccountSet can disable the master key, set an NFT minter, or change the transfer rate. Joey never exposes it to a website. Change account settings from the Joey Wallet UI instead.',
43
+ signMessage:
44
+ 'Joey does not sign arbitrary strings for a website: a bare signature carries no domain, nonce or timestamp, so it can be replayed against another site. Use signIn() from @joeywallet/wallet-sdk instead, which signs a CAIP-122 message bound to this origin.',
45
+ }
46
+
47
+ export class GemWalletUnsupportedError extends Error {
48
+ /** EIP-1193 "unsupported method". */
49
+ readonly code = 4200
50
+ readonly method: UnsupportedMethod
51
+
52
+ constructor(method: UnsupportedMethod) {
53
+ super(`@joeywallet/gemwallet-compat does not implement ${method}(). ${REASONS[method]}`)
54
+ this.name = 'GemWalletUnsupportedError'
55
+ this.method = method
56
+ Object.setPrototypeOf(this, GemWalletUnsupportedError.prototype)
57
+ }
58
+ }
59
+
60
+ export function refuse(method: UnsupportedMethod): never {
61
+ throw new GemWalletUnsupportedError(method)
62
+ }