@authon/react-native-wallet 0.0.0-stage → 0.4.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/CHANGELOG.md +20 -0
- package/README.md +251 -2
- package/android/build.gradle +40 -0
- package/android/consumer-rules.pro +10 -0
- package/android/src/main/AndroidManifest.xml +8 -0
- package/android/src/main/java/dev/authon/reactnative/wallet/AuthonWalletModule.kt +235 -0
- package/android/src/vendor/GENERATED.md +4 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/AndroidCapabilityProbe.kt +86 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/AuthonWallet.kt +218 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Bitcoin.kt +296 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Bytes.kt +74 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Chains.kt +157 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/CredentialManagerPasskeys.kt +192 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Der.kt +17 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/DeviceStore.kt +170 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/DialogWalletApprover.kt +141 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Eip712.kt +176 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Encodings.kt +133 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/EvmAccount.kt +45 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/EvmTransaction.kt +180 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/GfTables.kt +44 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/HdWallet.kt +130 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Http.kt +86 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/JsValues.kt +83 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/KeystoreDeviceStore.kt +236 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Prf.kt +111 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Proof.kt +134 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Shamir.kt +106 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/SignSummary.kt +335 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Solana.kt +195 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Tron.kt +184 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/WalletApi.kt +361 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/WalletCapabilities.kt +91 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/WalletError.kt +74 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/WalletOps.kt +551 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/WalletTypes.kt +78 -0
- package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Xrp.kt +193 -0
- package/build/authonContext.d.ts +19 -0
- package/build/authonContext.d.ts.map +1 -0
- package/build/authonContext.js +20 -0
- package/build/authonContext.js.map +1 -0
- package/build/client.d.ts +92 -0
- package/build/client.d.ts.map +1 -0
- package/build/client.js +431 -0
- package/build/client.js.map +1 -0
- package/build/errors.d.ts +25 -0
- package/build/errors.d.ts.map +1 -0
- package/build/errors.js +15 -0
- package/build/errors.js.map +1 -0
- package/build/index.d.ts +7 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +4 -0
- package/build/index.js.map +1 -0
- package/build/native.d.ts +43 -0
- package/build/native.d.ts.map +1 -0
- package/build/native.js +12 -0
- package/build/native.js.map +1 -0
- package/build/types.d.ts +167 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +3 -0
- package/build/types.js.map +1 -0
- package/build/useAuthonWallet.d.ts +25 -0
- package/build/useAuthonWallet.d.ts.map +1 -0
- package/build/useAuthonWallet.js +77 -0
- package/build/useAuthonWallet.js.map +1 -0
- package/expo-module.config.json +9 -0
- package/ios/AuthonReactNativeWallet.podspec +41 -0
- package/ios/AuthonWalletModule.swift +233 -0
- package/ios/vendor/AuthonWallet/AuthonWallet.swift +232 -0
- package/ios/vendor/AuthonWallet/Capabilities.swift +149 -0
- package/ios/vendor/AuthonWallet/Chains/Bitcoin.swift +296 -0
- package/ios/vendor/AuthonWallet/Chains/Solana.swift +207 -0
- package/ios/vendor/AuthonWallet/Chains/Tron.swift +181 -0
- package/ios/vendor/AuthonWallet/Chains/XRP.swift +191 -0
- package/ios/vendor/AuthonWallet/Crypto/BIP39Wordlist.swift +262 -0
- package/ios/vendor/AuthonWallet/Crypto/Chains.swift +278 -0
- package/ios/vendor/AuthonWallet/Crypto/HDKey.swift +108 -0
- package/ios/vendor/AuthonWallet/Crypto/Secp256k1.swift +128 -0
- package/ios/vendor/AuthonWallet/Crypto/Shamir.swift +123 -0
- package/ios/vendor/AuthonWallet/EVM/Address.swift +57 -0
- package/ios/vendor/AuthonWallet/EVM/EvmAccount.swift +48 -0
- package/ios/vendor/AuthonWallet/EVM/Transaction.swift +165 -0
- package/ios/vendor/AuthonWallet/EVM/TypedData.swift +193 -0
- package/ios/vendor/AuthonWallet/Support/BigInteger.swift +220 -0
- package/ios/vendor/AuthonWallet/Support/Bytes.swift +89 -0
- package/ios/vendor/AuthonWallet/Support/JSONValue.swift +341 -0
- package/ios/vendor/AuthonWallet/UI/WalletApprover.swift +250 -0
- package/ios/vendor/AuthonWallet/Wallet/Backup.swift +69 -0
- package/ios/vendor/AuthonWallet/Wallet/DeviceStore.swift +351 -0
- package/ios/vendor/AuthonWallet/Wallet/Passkeys.swift +190 -0
- package/ios/vendor/AuthonWallet/Wallet/Proof.swift +143 -0
- package/ios/vendor/AuthonWallet/Wallet/Shares.swift +116 -0
- package/ios/vendor/AuthonWallet/Wallet/Summary.swift +342 -0
- package/ios/vendor/AuthonWallet/Wallet/WalletAPI.swift +361 -0
- package/ios/vendor/AuthonWallet/Wallet/WalletOps.swift +654 -0
- package/ios/vendor/AuthonWallet/WalletError.swift +84 -0
- package/ios/vendor/CKeccak/LICENSE +22 -0
- package/ios/vendor/CKeccak/README.md +30 -0
- package/ios/vendor/CKeccak/byte_order.h +59 -0
- package/ios/vendor/CKeccak/include/ckeccak.h +13 -0
- package/ios/vendor/CKeccak/memzero.c +75 -0
- package/ios/vendor/CKeccak/memzero.h +8 -0
- package/ios/vendor/CKeccak/options.h +99 -0
- package/ios/vendor/CKeccak/ripemd160.c +343 -0
- package/ios/vendor/CKeccak/ripemd160.h +22 -0
- package/ios/vendor/CKeccak/sha3.c +413 -0
- package/ios/vendor/CKeccak/sha3.h +89 -0
- package/ios/vendor/CMonocypher/LICENCE.md +173 -0
- package/ios/vendor/CMonocypher/README.md +27 -0
- package/ios/vendor/CMonocypher/include/monocypher-ed25519.h +140 -0
- package/ios/vendor/CMonocypher/include/monocypher.h +321 -0
- package/ios/vendor/CMonocypher/monocypher-ed25519.c +500 -0
- package/ios/vendor/CMonocypher/monocypher.c +2956 -0
- package/ios/vendor/CSecp256k1/COPYING +19 -0
- package/ios/vendor/CSecp256k1/README.md +35 -0
- package/ios/vendor/CSecp256k1/build/precomputed_ecmult.c +3 -0
- package/ios/vendor/CSecp256k1/build/precomputed_ecmult_gen.c +3 -0
- package/ios/vendor/CSecp256k1/build/secp256k1.c +3 -0
- package/ios/vendor/CSecp256k1/include/secp256k1.h +899 -0
- package/ios/vendor/CSecp256k1/include/secp256k1_preallocated.h +134 -0
- package/ios/vendor/CSecp256k1/include/secp256k1_recovery.h +113 -0
- package/ios/vendor/CSecp256k1/src/assumptions.h +87 -0
- package/ios/vendor/CSecp256k1/src/checkmem.h +102 -0
- package/ios/vendor/CSecp256k1/src/ecdsa.h +21 -0
- package/ios/vendor/CSecp256k1/src/ecdsa_impl.h +304 -0
- package/ios/vendor/CSecp256k1/src/eckey.h +25 -0
- package/ios/vendor/CSecp256k1/src/eckey_impl.h +92 -0
- package/ios/vendor/CSecp256k1/src/ecmult.h +61 -0
- package/ios/vendor/CSecp256k1/src/ecmult_const.h +38 -0
- package/ios/vendor/CSecp256k1/src/ecmult_const_impl.h +399 -0
- package/ios/vendor/CSecp256k1/src/ecmult_gen.h +143 -0
- package/ios/vendor/CSecp256k1/src/ecmult_gen_impl.h +341 -0
- package/ios/vendor/CSecp256k1/src/ecmult_impl.h +853 -0
- package/ios/vendor/CSecp256k1/src/field.h +350 -0
- package/ios/vendor/CSecp256k1/src/field_10x26.h +57 -0
- package/ios/vendor/CSecp256k1/src/field_10x26_impl.h +1232 -0
- package/ios/vendor/CSecp256k1/src/field_5x52.h +62 -0
- package/ios/vendor/CSecp256k1/src/field_5x52_impl.h +522 -0
- package/ios/vendor/CSecp256k1/src/field_5x52_int128_impl.h +274 -0
- package/ios/vendor/CSecp256k1/src/field_impl.h +457 -0
- package/ios/vendor/CSecp256k1/src/group.h +212 -0
- package/ios/vendor/CSecp256k1/src/group_impl.h +974 -0
- package/ios/vendor/CSecp256k1/src/hash.h +44 -0
- package/ios/vendor/CSecp256k1/src/hash_impl.h +299 -0
- package/ios/vendor/CSecp256k1/src/hsort.h +33 -0
- package/ios/vendor/CSecp256k1/src/hsort_impl.h +125 -0
- package/ios/vendor/CSecp256k1/src/int128.h +90 -0
- package/ios/vendor/CSecp256k1/src/int128_impl.h +18 -0
- package/ios/vendor/CSecp256k1/src/int128_native.h +19 -0
- package/ios/vendor/CSecp256k1/src/int128_native_impl.h +94 -0
- package/ios/vendor/CSecp256k1/src/int128_struct.h +14 -0
- package/ios/vendor/CSecp256k1/src/int128_struct_impl.h +205 -0
- package/ios/vendor/CSecp256k1/src/modinv32.h +43 -0
- package/ios/vendor/CSecp256k1/src/modinv32_impl.h +725 -0
- package/ios/vendor/CSecp256k1/src/modinv64.h +47 -0
- package/ios/vendor/CSecp256k1/src/modinv64_impl.h +780 -0
- package/ios/vendor/CSecp256k1/src/modules/recovery/main_impl.h +159 -0
- package/ios/vendor/CSecp256k1/src/precomputed_ecmult.c +16456 -0
- package/ios/vendor/CSecp256k1/src/precomputed_ecmult.h +38 -0
- package/ios/vendor/CSecp256k1/src/precomputed_ecmult_gen.c +1779 -0
- package/ios/vendor/CSecp256k1/src/precomputed_ecmult_gen.h +26 -0
- package/ios/vendor/CSecp256k1/src/scalar.h +105 -0
- package/ios/vendor/CSecp256k1/src/scalar_4x64.h +19 -0
- package/ios/vendor/CSecp256k1/src/scalar_4x64_impl.h +1000 -0
- package/ios/vendor/CSecp256k1/src/scalar_8x32.h +19 -0
- package/ios/vendor/CSecp256k1/src/scalar_8x32_impl.h +816 -0
- package/ios/vendor/CSecp256k1/src/scalar_impl.h +321 -0
- package/ios/vendor/CSecp256k1/src/scalar_low.h +24 -0
- package/ios/vendor/CSecp256k1/src/scalar_low_impl.h +206 -0
- package/ios/vendor/CSecp256k1/src/scratch.h +44 -0
- package/ios/vendor/CSecp256k1/src/scratch_impl.h +99 -0
- package/ios/vendor/CSecp256k1/src/secp256k1.c +831 -0
- package/ios/vendor/CSecp256k1/src/selftest.h +32 -0
- package/ios/vendor/CSecp256k1/src/util.h +451 -0
- package/ios/vendor/GENERATED.md +4 -0
- package/package.json +66 -3
- package/src/authonContext.ts +30 -0
- package/src/client.ts +459 -0
- package/src/errors.ts +58 -0
- package/src/index.ts +26 -0
- package/src/native.ts +52 -0
- package/src/types.ts +171 -0
- package/src/useAuthonWallet.ts +103 -0
package/build/types.d.ts
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/** Names and shapes follow `@authon/js` (WalletClient) so web and app code read the same. */
|
|
2
|
+
export type Hex = `0x${string}`;
|
|
3
|
+
export interface EmbeddedWalletDevice {
|
|
4
|
+
id: string;
|
|
5
|
+
label: string | null;
|
|
6
|
+
createdAt: string | null;
|
|
7
|
+
lastUsedAt: string | null;
|
|
8
|
+
/** This app install. */
|
|
9
|
+
current: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface EmbeddedWallet {
|
|
12
|
+
/** Account 0 (m/44'/60'/0'/0/0), the same address the web wallet shows for this user. */
|
|
13
|
+
address: string;
|
|
14
|
+
/**
|
|
15
|
+
* True once the wallet has a passkey backup (`protect()`). An unprotected wallet exists only
|
|
16
|
+
* as this install's device share plus the server share: deleting the app or losing the device
|
|
17
|
+
* makes it unrecoverable. Do not let users receive funds until `protected` is true.
|
|
18
|
+
*/
|
|
19
|
+
protected: boolean;
|
|
20
|
+
/** True when the server has a wallet but this install holds no device share (call `restore()`). */
|
|
21
|
+
needsRestore: boolean;
|
|
22
|
+
/** A legacy backup without a passkey public key; call `upgradeBackup()` on a device that holds the wallet. */
|
|
23
|
+
backupUpgradeRecommended: boolean;
|
|
24
|
+
devices: EmbeddedWalletDevice[];
|
|
25
|
+
}
|
|
26
|
+
/** Chains whose account addresses the wallet derives from the same seed (NATIVE.md section 11). */
|
|
27
|
+
export type WalletChain = 'evm' | 'tron' | 'xrp' | 'bitcoin' | 'bitcoin-testnet' | 'solana';
|
|
28
|
+
/**
|
|
29
|
+
* One HD account. EVM: `m/44'/60'/0'/0/{index}` (account 0 is `EmbeddedWallet.address`); other chains
|
|
30
|
+
* use their standard paths (TRON `m/44'/195'/n'/0/0`, XRP `m/44'/144'/n'/0/0`, Bitcoin
|
|
31
|
+
* `m/84'/0'/n'/0/0`, Bitcoin testnet `m/84'/1'/n'/0/0`, Solana `m/44'/501'/n'/0'`).
|
|
32
|
+
*/
|
|
33
|
+
export interface WalletAccount {
|
|
34
|
+
index: number;
|
|
35
|
+
path: string;
|
|
36
|
+
address: string;
|
|
37
|
+
/** Set when `getAccounts` was asked for a chain. */
|
|
38
|
+
chain?: WalletChain;
|
|
39
|
+
/** Public key (hex) when the chain needs it to build a transaction (XRP SigningPubKey). */
|
|
40
|
+
publicKey?: string;
|
|
41
|
+
}
|
|
42
|
+
/** `signChainTransaction` input (NATIVE.md section 12). The app builds the unsigned transaction. */
|
|
43
|
+
export interface WalletChainSignRequest {
|
|
44
|
+
chain: Exclude<WalletChain, 'evm'>;
|
|
45
|
+
/** Account index (default 0). */
|
|
46
|
+
account?: number;
|
|
47
|
+
/** The account's address on `chain`, from getAccounts. Signing fails (ADDRESS_MISMATCH) if it differs. */
|
|
48
|
+
address: string;
|
|
49
|
+
/**
|
|
50
|
+
* Chain-specific unsigned transaction: Solana `{ message }` (base64 Message, legacy or v0),
|
|
51
|
+
* TRON `{ rawDataHex }`, Bitcoin `{ psbt }` (base64), XRP `{ txBlobHex }` (encodeForSigning output).
|
|
52
|
+
*/
|
|
53
|
+
payload: Record<string, unknown>;
|
|
54
|
+
}
|
|
55
|
+
/** Signs with another account of the same wallet. Omitted or 0 = the wallet address. */
|
|
56
|
+
export interface WalletSignOptions {
|
|
57
|
+
account?: number;
|
|
58
|
+
}
|
|
59
|
+
/** A personal_sign payload: UTF-8 text, or raw bytes as 0x hex. */
|
|
60
|
+
export type WalletMessage = string | {
|
|
61
|
+
raw: string;
|
|
62
|
+
};
|
|
63
|
+
export interface TypedDataPayload {
|
|
64
|
+
domain: Record<string, unknown>;
|
|
65
|
+
types: Record<string, Array<{
|
|
66
|
+
name: string;
|
|
67
|
+
type: string;
|
|
68
|
+
}>>;
|
|
69
|
+
primaryType: string;
|
|
70
|
+
message: Record<string, unknown>;
|
|
71
|
+
}
|
|
72
|
+
export interface WalletTransactionRequest {
|
|
73
|
+
to?: string;
|
|
74
|
+
from?: string;
|
|
75
|
+
value?: string | number | bigint;
|
|
76
|
+
data?: string;
|
|
77
|
+
nonce?: string | number;
|
|
78
|
+
gas?: string | number | bigint;
|
|
79
|
+
gasLimit?: string | number | bigint;
|
|
80
|
+
gasPrice?: string | number | bigint;
|
|
81
|
+
maxFeePerGas?: string | number | bigint;
|
|
82
|
+
maxPriorityFeePerGas?: string | number | bigint;
|
|
83
|
+
chainId?: string | number;
|
|
84
|
+
type?: string | number;
|
|
85
|
+
accessList?: Array<{
|
|
86
|
+
address: string;
|
|
87
|
+
storageKeys: string[];
|
|
88
|
+
}>;
|
|
89
|
+
}
|
|
90
|
+
export type WalletChangeListener = (wallet: EmbeddedWallet | null) => void;
|
|
91
|
+
/** `GET /v1/wallet/app-config` for this app (public, no session needed). */
|
|
92
|
+
export interface WalletAppConfig {
|
|
93
|
+
projectId: string | null;
|
|
94
|
+
/** The app is registered for the project (bundle ID / package name). */
|
|
95
|
+
allowed: boolean;
|
|
96
|
+
/** An Authon administrator approved the registration; passkey backup and restore need it. */
|
|
97
|
+
approved: boolean;
|
|
98
|
+
enabled: boolean;
|
|
99
|
+
chainIds: number[];
|
|
100
|
+
/** Project setting: show the native approval UI before every signature. */
|
|
101
|
+
confirmSigning: boolean;
|
|
102
|
+
/** Passkey relying party (`wallet.authon.dev`). */
|
|
103
|
+
rpId: string;
|
|
104
|
+
minFrameProtocol: number | null;
|
|
105
|
+
}
|
|
106
|
+
export type CapabilityStatus = 'available' | 'unavailable' | 'unknown';
|
|
107
|
+
export interface CapabilityCheck {
|
|
108
|
+
status: CapabilityStatus;
|
|
109
|
+
/** Reason code (see the README table); null when available. */
|
|
110
|
+
reason: string | null;
|
|
111
|
+
}
|
|
112
|
+
/** `capabilities()`: can this device and app use the wallet? Asked before sign-in, no session. */
|
|
113
|
+
export interface WalletCapabilities {
|
|
114
|
+
/** unavailable if any check is unavailable, else unknown if any is unknown, else available. */
|
|
115
|
+
ready: CapabilityStatus;
|
|
116
|
+
/** App registration and approval (APP_NOT_REGISTERED, APP_SIGNATURE_MISMATCH, APP_NOT_APPROVED, NETWORK_ERROR, API_ERROR). */
|
|
117
|
+
app: CapabilityCheck;
|
|
118
|
+
/** Embedded wallet enabled for the project (WALLET_DISABLED, NETWORK_ERROR). */
|
|
119
|
+
wallet: CapabilityCheck;
|
|
120
|
+
/** Hardware-protected key storage (HARDWARE_KEYSTORE_UNAVAILABLE, SIMULATOR, CHECK_FAILED). */
|
|
121
|
+
secureStorage: CapabilityCheck;
|
|
122
|
+
/** A device passcode / biometrics is set (DEVICE_LOCK_NOT_SET, CHECK_FAILED). */
|
|
123
|
+
deviceLock: CapabilityCheck;
|
|
124
|
+
/** Passkey PRF backup, static OS/API support only (OS_UNSUPPORTED, PASSKEY_API_UNAVAILABLE, PRF_PROVIDER_UNVERIFIED). */
|
|
125
|
+
passkeyBackup: CapabilityCheck;
|
|
126
|
+
/** X-Request-Id of the app-config response. */
|
|
127
|
+
diagnosticId: string | null;
|
|
128
|
+
}
|
|
129
|
+
export interface EIP1193RequestArguments {
|
|
130
|
+
method: string;
|
|
131
|
+
params?: unknown[] | Record<string, unknown>;
|
|
132
|
+
}
|
|
133
|
+
export interface EIP1193Provider {
|
|
134
|
+
request(args: EIP1193RequestArguments): Promise<unknown>;
|
|
135
|
+
}
|
|
136
|
+
export type TokenGetter = () => Promise<string | null | undefined> | string | null | undefined;
|
|
137
|
+
export interface AuthonWalletOptions {
|
|
138
|
+
publishableKey: string;
|
|
139
|
+
/** Defaults to https://api.authon.dev. */
|
|
140
|
+
apiUrl?: string;
|
|
141
|
+
/**
|
|
142
|
+
* Returns the current Authon session (access) token, refreshed when needed. Called before
|
|
143
|
+
* every wallet call; the token is handed to the native wallet for that call only.
|
|
144
|
+
*/
|
|
145
|
+
getToken: TokenGetter;
|
|
146
|
+
/**
|
|
147
|
+
* The app as registered in the Authon console: `TEAMID.bundleId` on iOS, the package name on
|
|
148
|
+
* Android. Detected when omitted (iOS: from the keychain access group; Android: package name).
|
|
149
|
+
*/
|
|
150
|
+
appId?: string | {
|
|
151
|
+
ios?: string;
|
|
152
|
+
android?: string;
|
|
153
|
+
};
|
|
154
|
+
/** Also require Face ID / Touch ID / device credential (iOS) or BiometricPrompt (Android) before each signature. */
|
|
155
|
+
requireDeviceAuthentication?: boolean;
|
|
156
|
+
/**
|
|
157
|
+
* TEST ONLY. Refused by the native module outside debug builds.
|
|
158
|
+
* - `allowSoftwareKeys`: software device keys when there is no Secure Enclave / StrongBox / TEE
|
|
159
|
+
* (simulator, emulator).
|
|
160
|
+
* - `autoApprove`: approve every signature without UI, for automated smoke tests.
|
|
161
|
+
*/
|
|
162
|
+
testing?: {
|
|
163
|
+
allowSoftwareKeys?: boolean;
|
|
164
|
+
autoApprove?: boolean;
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/build/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,6FAA6F"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { AuthonWalletClient } from './client';
|
|
2
|
+
import { AuthonWalletError } from './errors';
|
|
3
|
+
import type { AuthonWalletOptions, EmbeddedWallet, TokenGetter } from './types';
|
|
4
|
+
export interface UseAuthonWalletOptions extends Omit<AuthonWalletOptions, 'getToken'> {
|
|
5
|
+
/** Defaults to the session of the surrounding `<AuthonProvider>` from @authon/react-native. */
|
|
6
|
+
getToken?: TokenGetter;
|
|
7
|
+
}
|
|
8
|
+
export interface UseAuthonWalletResult {
|
|
9
|
+
/** The client; call ensure(), signMessage(), protect() etc. on it. */
|
|
10
|
+
wallet: AuthonWalletClient;
|
|
11
|
+
/** The signed-in user's wallet, null when signed out or before it is created. */
|
|
12
|
+
current: EmbeddedWallet | null;
|
|
13
|
+
/** False until the first status check finished (or while signed out and the auth SDK is loading). */
|
|
14
|
+
isLoaded: boolean;
|
|
15
|
+
error: AuthonWalletError | null;
|
|
16
|
+
/** Reloads `current`. */
|
|
17
|
+
refresh: () => Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Wallet of the signed-in user. Inside `<AuthonProvider>` (@authon/react-native) the session token
|
|
21
|
+
* comes from the provider and the wallet follows sign-in and sign-out; elsewhere pass `getToken`.
|
|
22
|
+
* The client is recreated only when publishableKey, apiUrl or appId change.
|
|
23
|
+
*/
|
|
24
|
+
export declare function useAuthonWallet(options: UseAuthonWalletOptions): UseAuthonWalletResult;
|
|
25
|
+
//# sourceMappingURL=useAuthonWallet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAuthonWallet.d.ts","sourceRoot":"","sources":["../src/useAuthonWallet.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEhF,MAAM,WAAW,sBAAuB,SAAQ,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC;IACnF,+FAA+F;IAC/F,QAAQ,CAAC,EAAE,WAAW,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,sEAAsE;IACtE,MAAM,EAAE,kBAAkB,CAAC;IAC3B,iFAAiF;IACjF,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IAC/B,qGAAqG;IACrG,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAChC,yBAAyB;IACzB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,qBAAqB,CA0EtF"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
|
+
import { getAuthonContext } from './authonContext';
|
|
3
|
+
import { AuthonWalletClient } from './client';
|
|
4
|
+
import { AuthonWalletError } from './errors';
|
|
5
|
+
/**
|
|
6
|
+
* Wallet of the signed-in user. Inside `<AuthonProvider>` (@authon/react-native) the session token
|
|
7
|
+
* comes from the provider and the wallet follows sign-in and sign-out; elsewhere pass `getToken`.
|
|
8
|
+
* The client is recreated only when publishableKey, apiUrl or appId change.
|
|
9
|
+
*/
|
|
10
|
+
export function useAuthonWallet(options) {
|
|
11
|
+
const session = useContext(getAuthonContext());
|
|
12
|
+
const latest = useRef({ options, session });
|
|
13
|
+
latest.current = { options, session };
|
|
14
|
+
if (!options.getToken && !session) {
|
|
15
|
+
throw new AuthonWalletError('NOT_CONFIGURED', 'useAuthonWallet needs getToken, or must be used inside <AuthonProvider> from @authon/react-native');
|
|
16
|
+
}
|
|
17
|
+
const appIdKey = typeof options.appId === 'string' ? options.appId : JSON.stringify(options.appId ?? null);
|
|
18
|
+
const testingKey = JSON.stringify(options.testing ?? null);
|
|
19
|
+
const wallet = useMemo(() => new AuthonWalletClient({
|
|
20
|
+
...latest.current.options,
|
|
21
|
+
getToken: async () => {
|
|
22
|
+
const { options: o, session: s } = latest.current;
|
|
23
|
+
if (o.getToken)
|
|
24
|
+
return o.getToken();
|
|
25
|
+
if (!s?.isSignedIn)
|
|
26
|
+
return null;
|
|
27
|
+
const token = s.getToken?.();
|
|
28
|
+
if (token)
|
|
29
|
+
return token;
|
|
30
|
+
return (await s.client?.refreshToken?.())?.accessToken ?? null;
|
|
31
|
+
},
|
|
32
|
+
}),
|
|
33
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
34
|
+
[options.publishableKey, options.apiUrl, appIdKey, options.requireDeviceAuthentication, testingKey]);
|
|
35
|
+
// dispose() only resets the client, so this is safe under StrictMode's double effects.
|
|
36
|
+
useEffect(() => () => wallet.dispose(), [wallet]);
|
|
37
|
+
const [current, setCurrent] = useState(null);
|
|
38
|
+
const [isLoaded, setLoaded] = useState(false);
|
|
39
|
+
const [error, setError] = useState(null);
|
|
40
|
+
useEffect(() => wallet.onChange(setCurrent), [wallet]);
|
|
41
|
+
const signedIn = options.getToken ? true : session?.isSignedIn === true;
|
|
42
|
+
const sessionUser = options.getToken ? null : session?.userId ?? null;
|
|
43
|
+
const authLoaded = options.getToken ? true : session?.isLoaded !== false;
|
|
44
|
+
const lastUser = useRef(undefined);
|
|
45
|
+
const refresh = useCallback(async () => {
|
|
46
|
+
try {
|
|
47
|
+
setCurrent(await wallet.get());
|
|
48
|
+
setError(null);
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
setError(e instanceof AuthonWalletError ? e : new AuthonWalletError('UNKNOWN', String(e)));
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
setLoaded(true);
|
|
55
|
+
}
|
|
56
|
+
}, [wallet]);
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
if (!authLoaded)
|
|
59
|
+
return;
|
|
60
|
+
if (!signedIn) {
|
|
61
|
+
wallet.dispose();
|
|
62
|
+
lastUser.current = undefined;
|
|
63
|
+
setCurrent(null);
|
|
64
|
+
setError(null);
|
|
65
|
+
setLoaded(true);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
// Another user signed in: drop the previous user's cached accounts and in-flight calls.
|
|
69
|
+
if (lastUser.current !== undefined && lastUser.current !== sessionUser)
|
|
70
|
+
wallet.dispose();
|
|
71
|
+
lastUser.current = sessionUser;
|
|
72
|
+
setLoaded(false);
|
|
73
|
+
void refresh();
|
|
74
|
+
}, [authLoaded, signedIn, sessionUser, refresh, wallet]);
|
|
75
|
+
return { wallet, current, isLoaded, error, refresh };
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=useAuthonWallet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAuthonWallet.js","sourceRoot":"","sources":["../src/useAuthonWallet.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, '..', 'package.json')))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = 'AuthonReactNativeWallet'
|
|
7
|
+
s.version = package['version']
|
|
8
|
+
s.summary = package['description']
|
|
9
|
+
s.license = { :type => 'MIT' }
|
|
10
|
+
s.author = 'Authon'
|
|
11
|
+
s.homepage = 'https://authon.dev'
|
|
12
|
+
# AuthonWallet needs iOS 16 (the Swift package's minimum); PRF passkeys need iOS 18 at run time.
|
|
13
|
+
s.platforms = { :ios => '16.0' }
|
|
14
|
+
s.source = { :git => 'https://github.com/mikusnuz/authon-sdk.git', :tag => "react-native-wallet@#{s.version}" }
|
|
15
|
+
s.static_framework = true
|
|
16
|
+
s.swift_version = '5.9'
|
|
17
|
+
s.dependency 'ExpoModulesCore'
|
|
18
|
+
s.frameworks = 'Security', 'CryptoKit', 'LocalAuthentication', 'AuthenticationServices', 'SwiftUI'
|
|
19
|
+
|
|
20
|
+
# vendor/ is generated from swift/Sources by scripts/sync-native-wallet.mjs.
|
|
21
|
+
# CSecp256k1: compile only build/*.c (they include src/*.c); CKeccak: sha3.c, ripemd160.c and memzero.c;
|
|
22
|
+
# CMonocypher (Ed25519, deterministic like the web wallet): both .c files, no flags.
|
|
23
|
+
s.source_files = [
|
|
24
|
+
'*.swift',
|
|
25
|
+
'vendor/AuthonWallet/**/*.swift',
|
|
26
|
+
'vendor/CSecp256k1/build/*.c',
|
|
27
|
+
'vendor/CSecp256k1/include/*.h',
|
|
28
|
+
'vendor/CKeccak/sha3.c',
|
|
29
|
+
'vendor/CKeccak/ripemd160.c',
|
|
30
|
+
'vendor/CKeccak/memzero.c',
|
|
31
|
+
'vendor/CKeccak/include/ckeccak.h',
|
|
32
|
+
'vendor/CMonocypher/*.c',
|
|
33
|
+
'vendor/CMonocypher/include/*.h',
|
|
34
|
+
]
|
|
35
|
+
s.public_header_files = ['vendor/CSecp256k1/include/*.h', 'vendor/CKeccak/include/ckeccak.h', 'vendor/CMonocypher/include/*.h']
|
|
36
|
+
s.preserve_paths = ['vendor/CSecp256k1/src/**/*', 'vendor/CKeccak/*.h']
|
|
37
|
+
s.pod_target_xcconfig = {
|
|
38
|
+
'DEFINES_MODULE' => 'YES',
|
|
39
|
+
'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) ENABLE_MODULE_RECOVERY=1',
|
|
40
|
+
}
|
|
41
|
+
end
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import ExpoModulesCore
|
|
2
|
+
import Foundation
|
|
3
|
+
|
|
4
|
+
/// Bridges the AuthonWallet core (vendor/AuthonWallet, generated from swift/Sources) to JS.
|
|
5
|
+
///
|
|
6
|
+
/// Only public data crosses the bridge: addresses, signatures, status and devices. The device
|
|
7
|
+
/// share, the company share, the key and passkey PRF output stay inside the core. Every
|
|
8
|
+
/// function resolves an envelope `{ ok: true, value }` or `{ ok: false, code, message }` with
|
|
9
|
+
/// the web wallet's error codes, so JS never parses native exception text.
|
|
10
|
+
public final class AuthonWalletModule: Module {
|
|
11
|
+
private let lock = NSLock()
|
|
12
|
+
private var wallets: [String: AuthonWallet] = [:]
|
|
13
|
+
|
|
14
|
+
public func definition() -> ModuleDefinition {
|
|
15
|
+
Name("AuthonWallet")
|
|
16
|
+
|
|
17
|
+
AsyncFunction("configure") { (id: String, config: [String: Any]) -> [String: Any] in
|
|
18
|
+
self.envelope { try self.configure(id, config); return NSNull() }
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
AsyncFunction("release") { (id: String) -> [String: Any] in
|
|
22
|
+
self.lock.withLock { self.wallets[id] = nil }
|
|
23
|
+
return ["ok": true, "value": NSNull()]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
AsyncFunction("appConfig") { (id: String) async -> [String: Any] in
|
|
27
|
+
await self.call(id, token: nil) { try Self.appConfig(await $0.appConfig()) }
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
AsyncFunction("capabilities") { (id: String) async -> [String: Any] in
|
|
31
|
+
await self.call(id, token: nil) { Self.capabilities(await $0.capabilities()) }
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
AsyncFunction("status") { (id: String, token: String) async -> [String: Any] in
|
|
35
|
+
await self.call(id, token: token) { try Self.wallet(await $0.status()) }
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
AsyncFunction("create") { (id: String, token: String) async -> [String: Any] in
|
|
39
|
+
await self.call(id, token: token) { try Self.wallet(await $0.create()) }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
AsyncFunction("accounts") { (id: String, token: String, start: Int, count: Int, chain: String) async -> [String: Any] in
|
|
43
|
+
await self.call(id, token: token) { w in
|
|
44
|
+
guard let walletChain = WalletChain(rawValue: chain) else {
|
|
45
|
+
throw WalletError(.invalidRequest, "chain must be one of \(WalletChain.allCases.map(\.rawValue).joined(separator: ", "))")
|
|
46
|
+
}
|
|
47
|
+
return try await w.accounts(start: start, count: count, chain: walletChain).map {
|
|
48
|
+
["index": $0.index, "path": $0.path, "address": $0.address, "chain": $0.chain.rawValue, "publicKey": Self.orNull($0.publicKey)] as [String: Any]
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
AsyncFunction("signMessage") { (id: String, token: String, kind: String, message: String, account: Int, address: String?) async -> [String: Any] in
|
|
54
|
+
await self.call(id, token: token) { w in
|
|
55
|
+
let payload: WalletMessage = kind == "raw" ? .raw(message) : .text(message)
|
|
56
|
+
return try await w.signMessage(payload, account: account, address: address)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
AsyncFunction("signTypedData") { (id: String, token: String, typedDataJson: String, account: Int, address: String?) async -> [String: Any] in
|
|
61
|
+
await self.call(id, token: token) { try await $0.signTypedData(typedDataJson, account: account, address: address) }
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
AsyncFunction("signTransaction") { (id: String, token: String, transactionJson: String, account: Int, address: String?) async -> [String: Any] in
|
|
65
|
+
await self.call(id, token: token) { try await $0.signTransaction(transactionJson, account: account, address: address) }
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
AsyncFunction("signChainTransaction") { (id: String, token: String, chain: String, account: Int, address: String, payloadJson: String) async -> [String: Any] in
|
|
69
|
+
await self.call(id, token: token) { w in
|
|
70
|
+
guard let walletChain = WalletChain(rawValue: chain) else {
|
|
71
|
+
throw WalletError(.invalidRequest, "unknown chain")
|
|
72
|
+
}
|
|
73
|
+
guard let data = payloadJson.data(using: .utf8),
|
|
74
|
+
let payload = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else {
|
|
75
|
+
throw WalletError(.invalidRequest, "payload must be a JSON object")
|
|
76
|
+
}
|
|
77
|
+
return try await w.signChainTransaction(chain: walletChain, account: account, address: address, payload: payload)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
AsyncFunction("protect") { (id: String, token: String) async -> [String: Any] in
|
|
82
|
+
await self.call(id, token: token) { ["shareVersion": try await $0.protect().shareVersion] }
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
AsyncFunction("upgradeBackup") { (id: String, token: String) async -> [String: Any] in
|
|
86
|
+
await self.call(id, token: token) { ["shareVersion": try await $0.upgradeBackup().shareVersion] }
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
AsyncFunction("restore") { (id: String, token: String, reset: Bool) async -> [String: Any] in
|
|
90
|
+
await self.call(id, token: token) { w in
|
|
91
|
+
let r = try await w.restore(mode: reset ? .reset : .add)
|
|
92
|
+
return ["shareVersion": r.shareVersion, "backupUpgradeRecommended": r.backupUpgradeRecommended]
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
AsyncFunction("revokeDevice") { (id: String, token: String, deviceId: String) async -> [String: Any] in
|
|
97
|
+
await self.call(id, token: token) { try await $0.revokeDevice(deviceId); return NSNull() }
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// MARK: - Instances
|
|
102
|
+
|
|
103
|
+
private static var isDebugBuild: Bool {
|
|
104
|
+
#if DEBUG
|
|
105
|
+
return true
|
|
106
|
+
#else
|
|
107
|
+
return false
|
|
108
|
+
#endif
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
private func configure(_ id: String, _ config: [String: Any]) throws {
|
|
112
|
+
guard let publishableKey = config["publishableKey"] as? String, !publishableKey.isEmpty else {
|
|
113
|
+
throw WalletError(.invalidRequest, "publishableKey required")
|
|
114
|
+
}
|
|
115
|
+
let apiUrl = (config["apiUrl"] as? String).flatMap { $0.isEmpty ? nil : $0 } ?? "https://api.authon.dev"
|
|
116
|
+
let appId = (config["appId"] as? String).flatMap { $0.isEmpty ? nil : $0 }
|
|
117
|
+
let testing = config["testing"] as? [String: Any] ?? [:]
|
|
118
|
+
let softwareKeys = testing["allowSoftwareKeys"] as? Bool ?? false
|
|
119
|
+
let autoApprove = testing["autoApprove"] as? Bool ?? false
|
|
120
|
+
if (softwareKeys || autoApprove) && !Self.isDebugBuild {
|
|
121
|
+
throw WalletError(.invalidRequest, "testing options are only available in debug builds")
|
|
122
|
+
}
|
|
123
|
+
let wallet = AuthonWallet(
|
|
124
|
+
publishableKey: publishableKey,
|
|
125
|
+
apiURL: apiUrl,
|
|
126
|
+
sessionProvider: { CallToken.value ?? "" },
|
|
127
|
+
appId: appId,
|
|
128
|
+
approver: autoApprove ? TestAutoApprover() : SheetWalletApprover(),
|
|
129
|
+
requireDeviceAuthentication: config["requireDeviceAuthentication"] as? Bool ?? false,
|
|
130
|
+
allowSoftwareKeys: softwareKeys
|
|
131
|
+
)
|
|
132
|
+
lock.withLock { wallets[id] = wallet }
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
private func call(_ id: String, token: String?, _ body: @escaping (AuthonWallet) async throws -> Any) async -> [String: Any] {
|
|
136
|
+
guard let wallet = lock.withLock({ wallets[id] }) else {
|
|
137
|
+
return Self.failure(WalletError(.invalidRequest, "wallet not configured"))
|
|
138
|
+
}
|
|
139
|
+
do {
|
|
140
|
+
// The token is the Authon session token for this call, not a wallet secret.
|
|
141
|
+
let value = try await CallToken.$value.withValue(token) { try await body(wallet) }
|
|
142
|
+
return ["ok": true, "value": value]
|
|
143
|
+
} catch {
|
|
144
|
+
return Self.failure(error)
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
private func envelope(_ body: () throws -> Any) -> [String: Any] {
|
|
149
|
+
do {
|
|
150
|
+
return ["ok": true, "value": try body()]
|
|
151
|
+
} catch {
|
|
152
|
+
return Self.failure(error)
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
private static func failure(_ error: Error) -> [String: Any] {
|
|
157
|
+
let e: WalletError
|
|
158
|
+
if let w = error as? WalletError {
|
|
159
|
+
e = w
|
|
160
|
+
} else if error is CancellationError {
|
|
161
|
+
e = WalletError(.userCancelled)
|
|
162
|
+
} else {
|
|
163
|
+
e = WalletError(.internal, "unexpected error")
|
|
164
|
+
}
|
|
165
|
+
return [
|
|
166
|
+
"ok": false,
|
|
167
|
+
"code": e.code.rawValue,
|
|
168
|
+
"message": e.message,
|
|
169
|
+
"diagnosticId": orNull(e.diagnosticId),
|
|
170
|
+
"retryable": e.retryable,
|
|
171
|
+
]
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// MARK: - Public data only
|
|
175
|
+
|
|
176
|
+
private static func orNull(_ value: Any?) -> Any { value ?? NSNull() }
|
|
177
|
+
|
|
178
|
+
private static func wallet(_ w: PublicWallet) -> [String: Any] {
|
|
179
|
+
[
|
|
180
|
+
"address": w.address,
|
|
181
|
+
"protected": w.isProtected,
|
|
182
|
+
"needsRestore": w.needsRestore,
|
|
183
|
+
"backupUpgradeRecommended": w.backupUpgradeRecommended,
|
|
184
|
+
"devices": w.devices.map {
|
|
185
|
+
[
|
|
186
|
+
"id": $0.id,
|
|
187
|
+
"label": orNull($0.label),
|
|
188
|
+
"createdAt": orNull($0.createdAt),
|
|
189
|
+
"lastUsedAt": orNull($0.lastUsedAt),
|
|
190
|
+
"current": $0.current,
|
|
191
|
+
] as [String: Any]
|
|
192
|
+
},
|
|
193
|
+
]
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
private static func capabilities(_ c: WalletCapabilities) -> [String: Any] {
|
|
197
|
+
func check(_ k: WalletCapabilities.Check) -> [String: Any] {
|
|
198
|
+
["status": k.status.rawValue, "reason": orNull(k.reason)]
|
|
199
|
+
}
|
|
200
|
+
return [
|
|
201
|
+
"ready": c.ready.rawValue,
|
|
202
|
+
"app": check(c.app),
|
|
203
|
+
"wallet": check(c.wallet),
|
|
204
|
+
"secureStorage": check(c.secureStorage),
|
|
205
|
+
"deviceLock": check(c.deviceLock),
|
|
206
|
+
"passkeyBackup": check(c.passkeyBackup),
|
|
207
|
+
"diagnosticId": orNull(c.diagnosticId),
|
|
208
|
+
]
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
private static func appConfig(_ c: WalletAppConfig) -> [String: Any] {
|
|
212
|
+
[
|
|
213
|
+
"projectId": orNull(c.projectId),
|
|
214
|
+
"allowed": c.allowed,
|
|
215
|
+
"approved": c.approved,
|
|
216
|
+
"enabled": c.enabled,
|
|
217
|
+
"chainIds": c.chainIds,
|
|
218
|
+
"confirmSigning": c.confirmSigning,
|
|
219
|
+
"rpId": c.rpId,
|
|
220
|
+
"minFrameProtocol": orNull(c.minFrameProtocol),
|
|
221
|
+
]
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
private enum CallToken {
|
|
226
|
+
@TaskLocal static var value: String?
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/// Debug builds only (checked in configure): approves every request without UI, so automated
|
|
230
|
+
/// smoke tests on the simulator can sign. Never used unless the app passes `testing.autoApprove`.
|
|
231
|
+
private struct TestAutoApprover: WalletApprover {
|
|
232
|
+
func approveSignature(_ summary: SignSummary) async throws {}
|
|
233
|
+
}
|