@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.
Files changed (183) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +251 -2
  3. package/android/build.gradle +40 -0
  4. package/android/consumer-rules.pro +10 -0
  5. package/android/src/main/AndroidManifest.xml +8 -0
  6. package/android/src/main/java/dev/authon/reactnative/wallet/AuthonWalletModule.kt +235 -0
  7. package/android/src/vendor/GENERATED.md +4 -0
  8. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/AndroidCapabilityProbe.kt +86 -0
  9. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/AuthonWallet.kt +218 -0
  10. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Bitcoin.kt +296 -0
  11. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Bytes.kt +74 -0
  12. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Chains.kt +157 -0
  13. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/CredentialManagerPasskeys.kt +192 -0
  14. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Der.kt +17 -0
  15. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/DeviceStore.kt +170 -0
  16. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/DialogWalletApprover.kt +141 -0
  17. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Eip712.kt +176 -0
  18. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Encodings.kt +133 -0
  19. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/EvmAccount.kt +45 -0
  20. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/EvmTransaction.kt +180 -0
  21. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/GfTables.kt +44 -0
  22. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/HdWallet.kt +130 -0
  23. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Http.kt +86 -0
  24. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/JsValues.kt +83 -0
  25. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/KeystoreDeviceStore.kt +236 -0
  26. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Prf.kt +111 -0
  27. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Proof.kt +134 -0
  28. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Shamir.kt +106 -0
  29. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/SignSummary.kt +335 -0
  30. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Solana.kt +195 -0
  31. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Tron.kt +184 -0
  32. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/WalletApi.kt +361 -0
  33. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/WalletCapabilities.kt +91 -0
  34. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/WalletError.kt +74 -0
  35. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/WalletOps.kt +551 -0
  36. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/WalletTypes.kt +78 -0
  37. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Xrp.kt +193 -0
  38. package/build/authonContext.d.ts +19 -0
  39. package/build/authonContext.d.ts.map +1 -0
  40. package/build/authonContext.js +20 -0
  41. package/build/authonContext.js.map +1 -0
  42. package/build/client.d.ts +92 -0
  43. package/build/client.d.ts.map +1 -0
  44. package/build/client.js +431 -0
  45. package/build/client.js.map +1 -0
  46. package/build/errors.d.ts +25 -0
  47. package/build/errors.d.ts.map +1 -0
  48. package/build/errors.js +15 -0
  49. package/build/errors.js.map +1 -0
  50. package/build/index.d.ts +7 -0
  51. package/build/index.d.ts.map +1 -0
  52. package/build/index.js +4 -0
  53. package/build/index.js.map +1 -0
  54. package/build/native.d.ts +43 -0
  55. package/build/native.d.ts.map +1 -0
  56. package/build/native.js +12 -0
  57. package/build/native.js.map +1 -0
  58. package/build/types.d.ts +167 -0
  59. package/build/types.d.ts.map +1 -0
  60. package/build/types.js +3 -0
  61. package/build/types.js.map +1 -0
  62. package/build/useAuthonWallet.d.ts +25 -0
  63. package/build/useAuthonWallet.d.ts.map +1 -0
  64. package/build/useAuthonWallet.js +77 -0
  65. package/build/useAuthonWallet.js.map +1 -0
  66. package/expo-module.config.json +9 -0
  67. package/ios/AuthonReactNativeWallet.podspec +41 -0
  68. package/ios/AuthonWalletModule.swift +233 -0
  69. package/ios/vendor/AuthonWallet/AuthonWallet.swift +232 -0
  70. package/ios/vendor/AuthonWallet/Capabilities.swift +149 -0
  71. package/ios/vendor/AuthonWallet/Chains/Bitcoin.swift +296 -0
  72. package/ios/vendor/AuthonWallet/Chains/Solana.swift +207 -0
  73. package/ios/vendor/AuthonWallet/Chains/Tron.swift +181 -0
  74. package/ios/vendor/AuthonWallet/Chains/XRP.swift +191 -0
  75. package/ios/vendor/AuthonWallet/Crypto/BIP39Wordlist.swift +262 -0
  76. package/ios/vendor/AuthonWallet/Crypto/Chains.swift +278 -0
  77. package/ios/vendor/AuthonWallet/Crypto/HDKey.swift +108 -0
  78. package/ios/vendor/AuthonWallet/Crypto/Secp256k1.swift +128 -0
  79. package/ios/vendor/AuthonWallet/Crypto/Shamir.swift +123 -0
  80. package/ios/vendor/AuthonWallet/EVM/Address.swift +57 -0
  81. package/ios/vendor/AuthonWallet/EVM/EvmAccount.swift +48 -0
  82. package/ios/vendor/AuthonWallet/EVM/Transaction.swift +165 -0
  83. package/ios/vendor/AuthonWallet/EVM/TypedData.swift +193 -0
  84. package/ios/vendor/AuthonWallet/Support/BigInteger.swift +220 -0
  85. package/ios/vendor/AuthonWallet/Support/Bytes.swift +89 -0
  86. package/ios/vendor/AuthonWallet/Support/JSONValue.swift +341 -0
  87. package/ios/vendor/AuthonWallet/UI/WalletApprover.swift +250 -0
  88. package/ios/vendor/AuthonWallet/Wallet/Backup.swift +69 -0
  89. package/ios/vendor/AuthonWallet/Wallet/DeviceStore.swift +351 -0
  90. package/ios/vendor/AuthonWallet/Wallet/Passkeys.swift +190 -0
  91. package/ios/vendor/AuthonWallet/Wallet/Proof.swift +143 -0
  92. package/ios/vendor/AuthonWallet/Wallet/Shares.swift +116 -0
  93. package/ios/vendor/AuthonWallet/Wallet/Summary.swift +342 -0
  94. package/ios/vendor/AuthonWallet/Wallet/WalletAPI.swift +361 -0
  95. package/ios/vendor/AuthonWallet/Wallet/WalletOps.swift +654 -0
  96. package/ios/vendor/AuthonWallet/WalletError.swift +84 -0
  97. package/ios/vendor/CKeccak/LICENSE +22 -0
  98. package/ios/vendor/CKeccak/README.md +30 -0
  99. package/ios/vendor/CKeccak/byte_order.h +59 -0
  100. package/ios/vendor/CKeccak/include/ckeccak.h +13 -0
  101. package/ios/vendor/CKeccak/memzero.c +75 -0
  102. package/ios/vendor/CKeccak/memzero.h +8 -0
  103. package/ios/vendor/CKeccak/options.h +99 -0
  104. package/ios/vendor/CKeccak/ripemd160.c +343 -0
  105. package/ios/vendor/CKeccak/ripemd160.h +22 -0
  106. package/ios/vendor/CKeccak/sha3.c +413 -0
  107. package/ios/vendor/CKeccak/sha3.h +89 -0
  108. package/ios/vendor/CMonocypher/LICENCE.md +173 -0
  109. package/ios/vendor/CMonocypher/README.md +27 -0
  110. package/ios/vendor/CMonocypher/include/monocypher-ed25519.h +140 -0
  111. package/ios/vendor/CMonocypher/include/monocypher.h +321 -0
  112. package/ios/vendor/CMonocypher/monocypher-ed25519.c +500 -0
  113. package/ios/vendor/CMonocypher/monocypher.c +2956 -0
  114. package/ios/vendor/CSecp256k1/COPYING +19 -0
  115. package/ios/vendor/CSecp256k1/README.md +35 -0
  116. package/ios/vendor/CSecp256k1/build/precomputed_ecmult.c +3 -0
  117. package/ios/vendor/CSecp256k1/build/precomputed_ecmult_gen.c +3 -0
  118. package/ios/vendor/CSecp256k1/build/secp256k1.c +3 -0
  119. package/ios/vendor/CSecp256k1/include/secp256k1.h +899 -0
  120. package/ios/vendor/CSecp256k1/include/secp256k1_preallocated.h +134 -0
  121. package/ios/vendor/CSecp256k1/include/secp256k1_recovery.h +113 -0
  122. package/ios/vendor/CSecp256k1/src/assumptions.h +87 -0
  123. package/ios/vendor/CSecp256k1/src/checkmem.h +102 -0
  124. package/ios/vendor/CSecp256k1/src/ecdsa.h +21 -0
  125. package/ios/vendor/CSecp256k1/src/ecdsa_impl.h +304 -0
  126. package/ios/vendor/CSecp256k1/src/eckey.h +25 -0
  127. package/ios/vendor/CSecp256k1/src/eckey_impl.h +92 -0
  128. package/ios/vendor/CSecp256k1/src/ecmult.h +61 -0
  129. package/ios/vendor/CSecp256k1/src/ecmult_const.h +38 -0
  130. package/ios/vendor/CSecp256k1/src/ecmult_const_impl.h +399 -0
  131. package/ios/vendor/CSecp256k1/src/ecmult_gen.h +143 -0
  132. package/ios/vendor/CSecp256k1/src/ecmult_gen_impl.h +341 -0
  133. package/ios/vendor/CSecp256k1/src/ecmult_impl.h +853 -0
  134. package/ios/vendor/CSecp256k1/src/field.h +350 -0
  135. package/ios/vendor/CSecp256k1/src/field_10x26.h +57 -0
  136. package/ios/vendor/CSecp256k1/src/field_10x26_impl.h +1232 -0
  137. package/ios/vendor/CSecp256k1/src/field_5x52.h +62 -0
  138. package/ios/vendor/CSecp256k1/src/field_5x52_impl.h +522 -0
  139. package/ios/vendor/CSecp256k1/src/field_5x52_int128_impl.h +274 -0
  140. package/ios/vendor/CSecp256k1/src/field_impl.h +457 -0
  141. package/ios/vendor/CSecp256k1/src/group.h +212 -0
  142. package/ios/vendor/CSecp256k1/src/group_impl.h +974 -0
  143. package/ios/vendor/CSecp256k1/src/hash.h +44 -0
  144. package/ios/vendor/CSecp256k1/src/hash_impl.h +299 -0
  145. package/ios/vendor/CSecp256k1/src/hsort.h +33 -0
  146. package/ios/vendor/CSecp256k1/src/hsort_impl.h +125 -0
  147. package/ios/vendor/CSecp256k1/src/int128.h +90 -0
  148. package/ios/vendor/CSecp256k1/src/int128_impl.h +18 -0
  149. package/ios/vendor/CSecp256k1/src/int128_native.h +19 -0
  150. package/ios/vendor/CSecp256k1/src/int128_native_impl.h +94 -0
  151. package/ios/vendor/CSecp256k1/src/int128_struct.h +14 -0
  152. package/ios/vendor/CSecp256k1/src/int128_struct_impl.h +205 -0
  153. package/ios/vendor/CSecp256k1/src/modinv32.h +43 -0
  154. package/ios/vendor/CSecp256k1/src/modinv32_impl.h +725 -0
  155. package/ios/vendor/CSecp256k1/src/modinv64.h +47 -0
  156. package/ios/vendor/CSecp256k1/src/modinv64_impl.h +780 -0
  157. package/ios/vendor/CSecp256k1/src/modules/recovery/main_impl.h +159 -0
  158. package/ios/vendor/CSecp256k1/src/precomputed_ecmult.c +16456 -0
  159. package/ios/vendor/CSecp256k1/src/precomputed_ecmult.h +38 -0
  160. package/ios/vendor/CSecp256k1/src/precomputed_ecmult_gen.c +1779 -0
  161. package/ios/vendor/CSecp256k1/src/precomputed_ecmult_gen.h +26 -0
  162. package/ios/vendor/CSecp256k1/src/scalar.h +105 -0
  163. package/ios/vendor/CSecp256k1/src/scalar_4x64.h +19 -0
  164. package/ios/vendor/CSecp256k1/src/scalar_4x64_impl.h +1000 -0
  165. package/ios/vendor/CSecp256k1/src/scalar_8x32.h +19 -0
  166. package/ios/vendor/CSecp256k1/src/scalar_8x32_impl.h +816 -0
  167. package/ios/vendor/CSecp256k1/src/scalar_impl.h +321 -0
  168. package/ios/vendor/CSecp256k1/src/scalar_low.h +24 -0
  169. package/ios/vendor/CSecp256k1/src/scalar_low_impl.h +206 -0
  170. package/ios/vendor/CSecp256k1/src/scratch.h +44 -0
  171. package/ios/vendor/CSecp256k1/src/scratch_impl.h +99 -0
  172. package/ios/vendor/CSecp256k1/src/secp256k1.c +831 -0
  173. package/ios/vendor/CSecp256k1/src/selftest.h +32 -0
  174. package/ios/vendor/CSecp256k1/src/util.h +451 -0
  175. package/ios/vendor/GENERATED.md +4 -0
  176. package/package.json +66 -3
  177. package/src/authonContext.ts +30 -0
  178. package/src/client.ts +459 -0
  179. package/src/errors.ts +58 -0
  180. package/src/index.ts +26 -0
  181. package/src/native.ts +52 -0
  182. package/src/types.ts +171 -0
  183. package/src/useAuthonWallet.ts +103 -0
@@ -0,0 +1,193 @@
1
+ // GENERATED by scripts/sync-native-wallet.mjs from swift/Sources/AuthonWallet/EVM/TypedData.swift. Do not edit: change the source and run the script.
2
+ import Foundation
3
+
4
+ /// EIP-712 v4 hashing with viem's rules (hashTypedData + validateTypedData).
5
+ struct TypedData {
6
+ struct Field {
7
+ var name: String
8
+ var type: String
9
+ }
10
+
11
+ var domain: JSONObject
12
+ var types: [String: [Field]]
13
+ var primaryType: String
14
+ var message: JSONValue
15
+
16
+ private static func bad(_ m: String) -> WalletError { WalletError(.invalidRequest, m) }
17
+
18
+ init(_ value: JSONValue) throws {
19
+ guard let obj = value.objectValue else { throw TypedData.bad("typedData must be an object") }
20
+ let domainValue = obj["domain"] ?? .null
21
+ if domainValue == .null {
22
+ domain = JSONObject()
23
+ } else {
24
+ guard let d = domainValue.objectValue else { throw TypedData.bad("domain must be an object") }
25
+ domain = d
26
+ }
27
+ guard case .string(let primary) = obj["primaryType"] ?? .null else { throw TypedData.bad("primaryType must be a string") }
28
+ primaryType = primary
29
+ message = obj["message"] ?? .null
30
+ guard let rawTypes = obj["types"]?.objectValue else { throw TypedData.bad("types must be an object") }
31
+ var parsed = [String: [Field]]()
32
+ parsed["EIP712Domain"] = TypedData.domainFields(domain)
33
+ for (name, list) in rawTypes.entries {
34
+ guard let arr = list.arrayValue else { throw TypedData.bad("types.\(name) must be an array") }
35
+ parsed[name] = try arr.map { f in
36
+ guard case .string(let n) = f["name"] ?? .null, case .string(let t) = f["type"] ?? .null else {
37
+ throw TypedData.bad("invalid field in \(name)")
38
+ }
39
+ return Field(name: n, type: t)
40
+ }
41
+ }
42
+ types = parsed
43
+ }
44
+
45
+ /// getTypesForEIP712Domain: chainId only when it is a number, the others when truthy.
46
+ private static func domainFields(_ d: JSONObject) -> [Field] {
47
+ var out = [Field]()
48
+ if case .string = d["name"] ?? .null { out.append(Field(name: "name", type: "string")) }
49
+ if d["version"]?.isTruthy == true { out.append(Field(name: "version", type: "string")) }
50
+ if case .number = d["chainId"] ?? .null { out.append(Field(name: "chainId", type: "uint256")) }
51
+ if d["verifyingContract"]?.isTruthy == true { out.append(Field(name: "verifyingContract", type: "address")) }
52
+ if d["salt"]?.isTruthy == true { out.append(Field(name: "salt", type: "bytes32")) }
53
+ return out
54
+ }
55
+
56
+ func digest() throws -> [UInt8] {
57
+ try validate()
58
+ var parts: [UInt8] = [0x19, 0x01]
59
+ parts += try hashStruct("EIP712Domain", .object(domain))
60
+ if primaryType != "EIP712Domain" { parts += try hashStruct(primaryType, message) }
61
+ return Keccak.hash256(parts)
62
+ }
63
+
64
+ // MARK: - Validation (validateTypedData)
65
+
66
+ private func validate() throws {
67
+ func validateData(_ fields: [Field], _ data: JSONValue) throws {
68
+ for f in fields {
69
+ let value = data[f.name]
70
+ let base = f.type.replacingOccurrences(of: #"(\[[0-9]*\])+$"#, with: "", options: .regularExpression)
71
+ if base == "int" || base == "uint" { throw TypedData.bad("invalid type \(f.type)") }
72
+ if let (signed, bits) = TypedData.integerType(f.type), let v = value, case .number = v {
73
+ guard let n = v.jsBigInt, n.fits(bits: bits, signed: signed) else { throw TypedData.bad("\(f.name) out of range") }
74
+ }
75
+ if f.type == "address", case .string(let s) = value ?? .null, !EvmAddress.isAddress(s) {
76
+ throw TypedData.bad("invalid address \(s)")
77
+ }
78
+ if let size = TypedData.fixedBytesSize(f.type), size > 0 {
79
+ guard case .string(let s) = value ?? .null, let b = Bytes.fromHex(s), Bytes.isHex(s), b.count == size else {
80
+ throw TypedData.bad("\(f.name) must be \(size) bytes")
81
+ }
82
+ }
83
+ if let nested = types[f.type] {
84
+ guard let v = value else { throw TypedData.bad("missing \(f.name)") }
85
+ try validateData(nested, v)
86
+ }
87
+ }
88
+ }
89
+ if let d = types["EIP712Domain"] { try validateData(d, .object(domain)) }
90
+ if primaryType != "EIP712Domain" {
91
+ guard let fields = types[primaryType] else { throw TypedData.bad("unknown primaryType \(primaryType)") }
92
+ try validateData(fields, message)
93
+ }
94
+ }
95
+
96
+ /// uint8..uint256 / int8..int256 in steps of 8.
97
+ static func integerType(_ type: String) -> (Bool, Int)? {
98
+ let signed = type.hasPrefix("int")
99
+ guard signed || type.hasPrefix("uint") else { return nil }
100
+ let digits = type.dropFirst(signed ? 3 : 4)
101
+ guard let bits = Int(digits), String(bits) == digits, bits >= 8, bits <= 256, bits % 8 == 0 else { return nil }
102
+ return (signed, bits)
103
+ }
104
+
105
+ /// bytes1..bytes32 (0 for dynamic `bytes`, nil otherwise).
106
+ static func fixedBytesSize(_ type: String) -> Int? {
107
+ guard type.hasPrefix("bytes") else { return nil }
108
+ let digits = type.dropFirst(5)
109
+ if digits.isEmpty { return 0 }
110
+ guard let n = Int(digits), String(n) == digits, n >= 1, n <= 32 else { return nil }
111
+ return n
112
+ }
113
+
114
+ // MARK: - Encoding
115
+
116
+ func encodeType(_ primary: String) -> String {
117
+ var deps = Set<String>()
118
+ findDependencies(primary, &deps)
119
+ deps.remove(primary)
120
+ let sorted = deps.sorted { $0.utf16.lexicographicallyPrecedes($1.utf16) }
121
+ return ([primary] + sorted).map { t in
122
+ "\(t)(" + (types[t] ?? []).map { "\($0.type) \($0.name)" }.joined(separator: ",") + ")"
123
+ }.joined()
124
+ }
125
+
126
+ private func findDependencies(_ type: String, _ results: inout Set<String>) {
127
+ let base = String(type.prefix { $0.isLetter || $0.isNumber || $0 == "_" })
128
+ guard !results.contains(base), let fields = types[base] else { return }
129
+ results.insert(base)
130
+ for f in fields { findDependencies(f.type, &results) }
131
+ }
132
+
133
+ func hashStruct(_ type: String, _ data: JSONValue) throws -> [UInt8] {
134
+ Keccak.hash256(try encodeData(type, data))
135
+ }
136
+
137
+ private func encodeData(_ type: String, _ data: JSONValue) throws -> [UInt8] {
138
+ guard let fields = types[type] else { throw TypedData.bad("unknown type \(type)") }
139
+ guard case .object = data else { throw TypedData.bad("\(type) value must be an object") }
140
+ var out = Keccak.hash256(Array(encodeType(type).utf8))
141
+ for f in fields { out += try encodeField(f.type, data[f.name]) }
142
+ return out
143
+ }
144
+
145
+ /// One 32-byte word per field.
146
+ private func encodeField(_ type: String, _ value: JSONValue?) throws -> [UInt8] {
147
+ if types[type] != nil {
148
+ guard let v = value else { throw TypedData.bad("missing \(type) value") }
149
+ return Keccak.hash256(try encodeData(type, v))
150
+ }
151
+ if type == "bytes" {
152
+ guard case .string(let s) = value ?? .null, Bytes.isHex(s), let b = Bytes.fromHex(s) else { throw TypedData.bad("bytes must be hex") }
153
+ return Keccak.hash256(b)
154
+ }
155
+ if type == "string" {
156
+ guard case .string(let s) = value ?? .null else { throw TypedData.bad("string expected") }
157
+ return Keccak.hash256(Array(s.utf8))
158
+ }
159
+ if type.hasSuffix("]"), let open = type.range(of: "[", options: .backwards) {
160
+ let inner = String(type[..<open.lowerBound])
161
+ guard let items = value?.arrayValue else { throw TypedData.bad("array expected for \(type)") }
162
+ var concat = [UInt8]()
163
+ for item in items { concat += try encodeField(inner, item) }
164
+ return Keccak.hash256(concat)
165
+ }
166
+ return try encodeAtomic(type, value)
167
+ }
168
+
169
+ private func encodeAtomic(_ type: String, _ value: JSONValue?) throws -> [UInt8] {
170
+ let v = value ?? .null
171
+ if type == "address" {
172
+ guard case .string(let s) = v, EvmAddress.isAddress(s), let b = EvmAddress.bytes(s) else { throw TypedData.bad("invalid address") }
173
+ return [UInt8](repeating: 0, count: 12) + b
174
+ }
175
+ if type == "bool" {
176
+ guard case .bool(let b) = v else { throw TypedData.bad("bool expected") }
177
+ return [UInt8](repeating: 0, count: 31) + [b ? 1 : 0]
178
+ }
179
+ if let (signed, bits) = TypedData.integerType(type) {
180
+ guard let n = v.jsBigInt, n.fits(bits: bits, signed: signed), let word = n.word() else {
181
+ throw TypedData.bad("\(type) value out of range")
182
+ }
183
+ return word
184
+ }
185
+ if let size = TypedData.fixedBytesSize(type), size > 0 {
186
+ guard case .string(let s) = v, Bytes.isHex(s), let b = Bytes.fromHex(s), b.count == size else {
187
+ throw TypedData.bad("\(type) size mismatch")
188
+ }
189
+ return b + [UInt8](repeating: 0, count: 32 - size)
190
+ }
191
+ throw TypedData.bad("unsupported type \(type)")
192
+ }
193
+ }
@@ -0,0 +1,220 @@
1
+ // GENERATED by scripts/sync-native-wallet.mjs from swift/Sources/AuthonWallet/Support/BigInteger.swift. Do not edit: change the source and run the script.
2
+ import Foundation
3
+
4
+ /// Unsigned arbitrary-precision integer for amounts, gas and EIP-712 integers. Only the
5
+ /// operations the wallet needs (parsing, printing, encoding, add/sub/mul, compare).
6
+ struct BigUInt: Comparable, Hashable, CustomStringConvertible {
7
+ /// Little-endian 32-bit limbs without trailing zero limbs.
8
+ private(set) var limbs: [UInt32]
9
+
10
+ init(_ value: UInt64 = 0) {
11
+ limbs = [UInt32(truncatingIfNeeded: value), UInt32(truncatingIfNeeded: value >> 32)]
12
+ normalize()
13
+ }
14
+
15
+ init(limbs: [UInt32]) {
16
+ self.limbs = limbs
17
+ normalize()
18
+ }
19
+
20
+ /// Big-endian bytes.
21
+ init(bytes: [UInt8]) {
22
+ var out = [UInt32]()
23
+ var i = bytes.count
24
+ while i > 0 {
25
+ var limb: UInt32 = 0
26
+ let start = Swift.max(0, i - 4)
27
+ for b in bytes[start..<i] { limb = limb << 8 | UInt32(b) }
28
+ out.append(limb)
29
+ i = start
30
+ }
31
+ self.init(limbs: out)
32
+ }
33
+
34
+ init?(decimal text: String) {
35
+ guard !text.isEmpty, text.utf8.allSatisfy({ $0 >= 0x30 && $0 <= 0x39 }) else { return nil }
36
+ var v = BigUInt()
37
+ for c in text.utf8 { v = v.multiplied(by: 10).adding(UInt32(c - 0x30)) }
38
+ self = v
39
+ }
40
+
41
+ init?(hexDigits text: String) {
42
+ guard !text.isEmpty, !text.contains("x"), !text.contains("X"), let bytes = Bytes.fromHex(text) else { return nil }
43
+ self.init(bytes: bytes)
44
+ }
45
+
46
+ private mutating func normalize() {
47
+ while let last = limbs.last, last == 0 { limbs.removeLast() }
48
+ }
49
+
50
+ var isZero: Bool { limbs.isEmpty }
51
+
52
+ var bitWidth: Int {
53
+ guard let last = limbs.last else { return 0 }
54
+ return (limbs.count - 1) * 32 + (32 - last.leadingZeroBitCount)
55
+ }
56
+
57
+ /// Minimal big-endian bytes; zero is empty.
58
+ var bytes: [UInt8] {
59
+ var out = [UInt8]()
60
+ for limb in limbs.reversed() {
61
+ out += [UInt8(limb >> 24), UInt8(truncatingIfNeeded: limb >> 16), UInt8(truncatingIfNeeded: limb >> 8), UInt8(truncatingIfNeeded: limb)]
62
+ }
63
+ if let first = out.firstIndex(where: { $0 != 0 }) { return Array(out[first...]) }
64
+ return []
65
+ }
66
+
67
+ /// Big-endian, left-padded to `size` bytes; nil when it does not fit.
68
+ func padded(to size: Int) -> [UInt8]? {
69
+ let b = bytes
70
+ guard b.count <= size else { return nil }
71
+ return [UInt8](repeating: 0, count: size - b.count) + b
72
+ }
73
+
74
+ var uint64: UInt64? {
75
+ guard limbs.count <= 2 else { return nil }
76
+ return limbs.enumerated().reduce(UInt64(0)) { $0 | UInt64($1.element) << (32 * UInt64($1.offset)) }
77
+ }
78
+
79
+ static func power2(_ n: Int) -> BigUInt {
80
+ var l = [UInt32](repeating: 0, count: n / 32 + 1)
81
+ l[n / 32] = 1 << UInt32(n % 32)
82
+ return BigUInt(limbs: l)
83
+ }
84
+
85
+ func adding(_ small: UInt32) -> BigUInt { self + BigUInt(UInt64(small)) }
86
+
87
+ func multiplied(by small: UInt32) -> BigUInt { self * BigUInt(UInt64(small)) }
88
+
89
+ static func + (a: BigUInt, b: BigUInt) -> BigUInt {
90
+ var out = [UInt32]()
91
+ var carry: UInt64 = 0
92
+ for i in 0..<Swift.max(a.limbs.count, b.limbs.count) {
93
+ let s = UInt64(i < a.limbs.count ? a.limbs[i] : 0) + UInt64(i < b.limbs.count ? b.limbs[i] : 0) + carry
94
+ out.append(UInt32(truncatingIfNeeded: s))
95
+ carry = s >> 32
96
+ }
97
+ if carry > 0 { out.append(UInt32(carry)) }
98
+ return BigUInt(limbs: out)
99
+ }
100
+
101
+ /// a - b for a >= b.
102
+ static func - (a: BigUInt, b: BigUInt) -> BigUInt {
103
+ precondition(a >= b)
104
+ var out = [UInt32]()
105
+ var borrow: Int64 = 0
106
+ for i in 0..<a.limbs.count {
107
+ var d = Int64(a.limbs[i]) - Int64(i < b.limbs.count ? b.limbs[i] : 0) - borrow
108
+ borrow = 0
109
+ if d < 0 { d += 1 << 32; borrow = 1 }
110
+ out.append(UInt32(d))
111
+ }
112
+ return BigUInt(limbs: out)
113
+ }
114
+
115
+ static func * (a: BigUInt, b: BigUInt) -> BigUInt {
116
+ if a.isZero || b.isZero { return BigUInt() }
117
+ var out = [UInt32](repeating: 0, count: a.limbs.count + b.limbs.count)
118
+ for i in 0..<a.limbs.count {
119
+ var carry: UInt64 = 0
120
+ for j in 0..<b.limbs.count {
121
+ let t = UInt64(a.limbs[i]) * UInt64(b.limbs[j]) + UInt64(out[i + j]) + carry
122
+ out[i + j] = UInt32(truncatingIfNeeded: t)
123
+ carry = t >> 32
124
+ }
125
+ out[i + b.limbs.count] = UInt32(carry)
126
+ }
127
+ return BigUInt(limbs: out)
128
+ }
129
+
130
+ func quotientAndRemainder(dividingBy d: UInt32) -> (BigUInt, UInt32) {
131
+ var q = [UInt32](repeating: 0, count: limbs.count)
132
+ var rem: UInt64 = 0
133
+ for i in stride(from: limbs.count - 1, through: 0, by: -1) {
134
+ let cur = rem << 32 | UInt64(limbs[i])
135
+ q[i] = UInt32(cur / UInt64(d))
136
+ rem = cur % UInt64(d)
137
+ }
138
+ return (BigUInt(limbs: q), UInt32(rem))
139
+ }
140
+
141
+ var description: String {
142
+ if isZero { return "0" }
143
+ var parts = [String]()
144
+ var v = self
145
+ while !v.isZero {
146
+ let (q, r) = v.quotientAndRemainder(dividingBy: 1_000_000_000)
147
+ parts.append(String(r))
148
+ v = q
149
+ }
150
+ var out = parts.removeLast()
151
+ for p in parts.reversed() { out += String(repeating: "0", count: 9 - p.count) + p }
152
+ return out
153
+ }
154
+
155
+ static func < (a: BigUInt, b: BigUInt) -> Bool {
156
+ if a.limbs.count != b.limbs.count { return a.limbs.count < b.limbs.count }
157
+ for i in stride(from: a.limbs.count - 1, through: 0, by: -1) where a.limbs[i] != b.limbs[i] {
158
+ return a.limbs[i] < b.limbs[i]
159
+ }
160
+ return false
161
+ }
162
+ }
163
+
164
+ /// Signed integer with JavaScript `BigInt()` parsing semantics.
165
+ struct BigInteger: Equatable, CustomStringConvertible {
166
+ var negative: Bool
167
+ var magnitude: BigUInt
168
+
169
+ init(_ magnitude: BigUInt, negative: Bool = false) {
170
+ self.magnitude = magnitude
171
+ self.negative = negative && !magnitude.isZero
172
+ }
173
+
174
+ /// `BigInt(string)`: surrounding whitespace ignored, empty is 0, 0x/0o/0b prefixes, optional sign for decimals.
175
+ init?(jsString raw: String) {
176
+ let s = raw.trimmingCharacters(in: .whitespacesAndNewlines)
177
+ if s.isEmpty { self.init(BigUInt()); return }
178
+ let lower = s.lowercased()
179
+ if lower.hasPrefix("0x") {
180
+ guard let v = BigUInt(hexDigits: String(s.dropFirst(2))) else { return nil }
181
+ self.init(v)
182
+ return
183
+ }
184
+ if lower.hasPrefix("0o") || lower.hasPrefix("0b") {
185
+ let radix: UInt32 = lower.hasPrefix("0o") ? 8 : 2
186
+ let digits = s.dropFirst(2)
187
+ guard !digits.isEmpty else { return nil }
188
+ var v = BigUInt()
189
+ for c in digits.utf8 {
190
+ let d = UInt32(c) &- 0x30
191
+ guard d < radix else { return nil }
192
+ v = v.multiplied(by: radix).adding(d)
193
+ }
194
+ self.init(v)
195
+ return
196
+ }
197
+ var body = Substring(s)
198
+ var neg = false
199
+ if body.hasPrefix("-") { neg = true; body = body.dropFirst() } else if body.hasPrefix("+") { body = body.dropFirst() }
200
+ guard let v = BigUInt(decimal: String(body)) else { return nil }
201
+ self.init(v, negative: neg)
202
+ }
203
+
204
+ var description: String { (negative ? "-" : "") + magnitude.description }
205
+
206
+ /// 32-byte two's complement.
207
+ func word() -> [UInt8]? {
208
+ if !negative { return magnitude.padded(to: 32) }
209
+ let mod = BigUInt.power2(256)
210
+ guard magnitude <= BigUInt.power2(255) else { return nil }
211
+ return (mod - magnitude).padded(to: 32)
212
+ }
213
+
214
+ /// Range check for uintN / intN.
215
+ func fits(bits: Int, signed: Bool) -> Bool {
216
+ if !signed { return !negative && magnitude.bitWidth <= bits }
217
+ if negative { return magnitude <= BigUInt.power2(bits - 1) }
218
+ return magnitude < BigUInt.power2(bits - 1)
219
+ }
220
+ }
@@ -0,0 +1,89 @@
1
+ // GENERATED by scripts/sync-native-wallet.mjs from swift/Sources/AuthonWallet/Support/Bytes.swift. Do not edit: change the source and run the script.
2
+ import CryptoKit
3
+ import Foundation
4
+ import Security
5
+
6
+ enum Bytes {
7
+ static func random(_ count: Int) throws -> [UInt8] {
8
+ var out = [UInt8](repeating: 0, count: count)
9
+ let status = out.withUnsafeMutableBytes { SecRandomCopyBytes(kSecRandomDefault, count, $0.baseAddress!) }
10
+ guard status == errSecSuccess else { throw WalletError(.internal, "random source unavailable") }
11
+ return out
12
+ }
13
+
14
+ static func sha256(_ data: [UInt8]) -> [UInt8] { Array(SHA256.hash(data: data)) }
15
+
16
+ static func wipe(_ buffers: inout [UInt8]) {
17
+ buffers.withUnsafeMutableBytes { raw in
18
+ if let base = raw.baseAddress { memset_s(base, raw.count, 0, raw.count) }
19
+ }
20
+ }
21
+
22
+ // MARK: - Hex
23
+
24
+ static func hex(_ bytes: [UInt8], prefix: Bool = false) -> String {
25
+ let digits = Array("0123456789abcdef".utf8)
26
+ var out = [UInt8]()
27
+ out.reserveCapacity(bytes.count * 2 + 2)
28
+ if prefix { out += [0x30, 0x78] }
29
+ for b in bytes {
30
+ out.append(digits[Int(b >> 4)])
31
+ out.append(digits[Int(b & 0x0f)])
32
+ }
33
+ return String(decoding: out, as: UTF8.self)
34
+ }
35
+
36
+ /// Strict hex decoding with an optional 0x prefix. An odd digit count is left-padded with 0 like viem.
37
+ static func fromHex(_ value: String, requirePrefix: Bool = false) -> [UInt8]? {
38
+ var body = Substring(value)
39
+ if body.hasPrefix("0x") || body.hasPrefix("0X") { body = body.dropFirst(2) } else if requirePrefix { return nil }
40
+ var chars = Array(body.utf8)
41
+ if chars.count % 2 == 1 { chars.insert(0x30, at: 0) }
42
+ var out = [UInt8]()
43
+ out.reserveCapacity(chars.count / 2)
44
+ var i = 0
45
+ while i < chars.count {
46
+ guard let hi = nibble(chars[i]), let lo = nibble(chars[i + 1]) else { return nil }
47
+ out.append(hi << 4 | lo)
48
+ i += 2
49
+ }
50
+ return out
51
+ }
52
+
53
+ static func isHex(_ value: String) -> Bool {
54
+ guard value.hasPrefix("0x") else { return false }
55
+ return value.utf8.dropFirst(2).allSatisfy { nibble($0) != nil }
56
+ }
57
+
58
+ private static func nibble(_ c: UInt8) -> UInt8? {
59
+ switch c {
60
+ case 0x30...0x39: return c - 0x30
61
+ case 0x61...0x66: return c - 0x61 + 10
62
+ case 0x41...0x46: return c - 0x41 + 10
63
+ default: return nil
64
+ }
65
+ }
66
+
67
+ // MARK: - Base64
68
+
69
+ static func base64(_ bytes: [UInt8]) -> String { Data(bytes).base64EncodedString() }
70
+
71
+ static func base64url(_ bytes: [UInt8]) -> String {
72
+ base64(bytes).replacingOccurrences(of: "+", with: "-").replacingOccurrences(of: "/", with: "_")
73
+ .replacingOccurrences(of: "=", with: "")
74
+ }
75
+
76
+ /// Accepts standard and URL-safe alphabets, with or without padding (like the frame's fromBase64).
77
+ static func fromBase64(_ value: String) -> [UInt8]? {
78
+ var s = value.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/")
79
+ let rem = s.count % 4
80
+ if rem == 1 { return nil }
81
+ if rem > 0 { s += String(repeating: "=", count: 4 - rem) }
82
+ guard let data = Data(base64Encoded: s) else { return nil }
83
+ return Array(data)
84
+ }
85
+ }
86
+
87
+ extension Array where Element == UInt8 {
88
+ mutating func wipe() { Bytes.wipe(&self) }
89
+ }