@openzeppelin/adapter-stellar 1.0.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/README.md +272 -0
- package/dist/config.cjs +21 -0
- package/dist/config.cjs.map +1 -0
- package/dist/config.d.cts +8 -0
- package/dist/config.d.cts.map +1 -0
- package/dist/config.d.mts +8 -0
- package/dist/config.d.mts.map +1 -0
- package/dist/config.mjs +20 -0
- package/dist/config.mjs.map +1 -0
- package/dist/index.cjs +7564 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +261 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +263 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +7529 -0
- package/dist/index.mjs.map +1 -0
- package/dist/metadata.cjs +22 -0
- package/dist/metadata.cjs.map +1 -0
- package/dist/metadata.d.cts +7 -0
- package/dist/metadata.d.cts.map +1 -0
- package/dist/metadata.d.mts +7 -0
- package/dist/metadata.d.mts.map +1 -0
- package/dist/metadata.mjs +21 -0
- package/dist/metadata.mjs.map +1 -0
- package/dist/networks-BrV516-R.d.cts +15 -0
- package/dist/networks-BrV516-R.d.cts.map +1 -0
- package/dist/networks-C0MmhJcu.d.mts +15 -0
- package/dist/networks-C0MmhJcu.d.mts.map +1 -0
- package/dist/networks-DgUFSTiC.cjs +76 -0
- package/dist/networks-DgUFSTiC.cjs.map +1 -0
- package/dist/networks-QbEPbaGT.mjs +46 -0
- package/dist/networks-QbEPbaGT.mjs.map +1 -0
- package/dist/networks.cjs +8 -0
- package/dist/networks.d.cts +2 -0
- package/dist/networks.d.mts +2 -0
- package/dist/networks.mjs +3 -0
- package/dist/vite-config.cjs +43 -0
- package/dist/vite-config.cjs.map +1 -0
- package/dist/vite-config.d.cts +35 -0
- package/dist/vite-config.d.cts.map +1 -0
- package/dist/vite-config.d.mts +35 -0
- package/dist/vite-config.d.mts.map +1 -0
- package/dist/vite-config.mjs +42 -0
- package/dist/vite-config.mjs.map +1 -0
- package/package.json +114 -0
- package/src/__tests__/getDefaultServiceConfig.test.ts +105 -0
- package/src/access-control/actions.ts +214 -0
- package/src/access-control/feature-detection.ts +238 -0
- package/src/access-control/index.ts +54 -0
- package/src/access-control/indexer-client.ts +1474 -0
- package/src/access-control/onchain-reader.ts +446 -0
- package/src/access-control/service.ts +1431 -0
- package/src/access-control/validation.ts +256 -0
- package/src/adapter.ts +659 -0
- package/src/config.ts +43 -0
- package/src/configuration/__tests__/explorer.test.ts +80 -0
- package/src/configuration/__tests__/rpc.test.ts +355 -0
- package/src/configuration/execution.ts +83 -0
- package/src/configuration/explorer.ts +105 -0
- package/src/configuration/index.ts +5 -0
- package/src/configuration/network-services.ts +210 -0
- package/src/configuration/rpc.ts +270 -0
- package/src/configuration.ts +2 -0
- package/src/contract/__tests__/complete-type-coverage.test.ts +78 -0
- package/src/contract/index.ts +3 -0
- package/src/contract/loader.ts +498 -0
- package/src/contract/transformer.ts +1 -0
- package/src/contract/type.ts +65 -0
- package/src/index.ts +23 -0
- package/src/mapping/constants.ts +89 -0
- package/src/mapping/enum-metadata.ts +237 -0
- package/src/mapping/field-generator.ts +296 -0
- package/src/mapping/index.ts +5 -0
- package/src/mapping/struct-fields.ts +106 -0
- package/src/mapping/tuple-components.ts +43 -0
- package/src/mapping/type-coverage-validator.ts +151 -0
- package/src/mapping/type-mapper.ts +203 -0
- package/src/metadata.ts +16 -0
- package/src/networks/README.md +84 -0
- package/src/networks/index.ts +19 -0
- package/src/networks/mainnet.ts +20 -0
- package/src/networks/testnet.ts +20 -0
- package/src/networks.ts +2 -0
- package/src/query/handler.ts +411 -0
- package/src/query/index.ts +4 -0
- package/src/query/view-checker.ts +32 -0
- package/src/sac/spec-cache.ts +68 -0
- package/src/sac/spec-source.ts +35 -0
- package/src/sac/xdr.ts +101 -0
- package/src/transaction/components/AdvancedInfo.tsx +34 -0
- package/src/transaction/components/FeeConfiguration.tsx +41 -0
- package/src/transaction/components/StellarRelayerOptions.tsx +60 -0
- package/src/transaction/components/TransactionTiming.tsx +77 -0
- package/src/transaction/components/index.ts +5 -0
- package/src/transaction/components/useStellarRelayerOptions.ts +114 -0
- package/src/transaction/eoa.ts +229 -0
- package/src/transaction/execution-strategy.ts +33 -0
- package/src/transaction/formatter.ts +296 -0
- package/src/transaction/index.ts +4 -0
- package/src/transaction/relayer.ts +575 -0
- package/src/transaction/sender.ts +156 -0
- package/src/transform/index.ts +4 -0
- package/src/transform/input-parser.ts +9 -0
- package/src/transform/output-formatter.ts +133 -0
- package/src/transform/parsers/complex-parser.ts +157 -0
- package/src/transform/parsers/generic-parser.ts +171 -0
- package/src/transform/parsers/index.ts +86 -0
- package/src/transform/parsers/primitive-parser.ts +123 -0
- package/src/transform/parsers/scval-converter.ts +405 -0
- package/src/transform/parsers/struct-parser.ts +324 -0
- package/src/transform/parsers/types.ts +35 -0
- package/src/types/__tests__/artifacts.test.ts +89 -0
- package/src/types/artifacts.ts +19 -0
- package/src/utils/__tests__/artifacts.test.ts +77 -0
- package/src/utils/artifacts.ts +30 -0
- package/src/utils/formatting.ts +122 -0
- package/src/utils/index.ts +6 -0
- package/src/utils/input-parsing.ts +336 -0
- package/src/utils/safe-type-parser.ts +303 -0
- package/src/utils/stellar-types.ts +35 -0
- package/src/utils/type-detection.ts +163 -0
- package/src/utils/xdr-ordering.ts +36 -0
- package/src/validation/__tests__/address.test.ts +267 -0
- package/src/validation/address.ts +136 -0
- package/src/validation/eoa.ts +33 -0
- package/src/validation/index.ts +3 -0
- package/src/validation/relayer.ts +13 -0
- package/src/vite-config.ts +67 -0
- package/src/wallet/README.md +93 -0
- package/src/wallet/__tests__/connection.test.ts +72 -0
- package/src/wallet/components/StellarWalletUiRoot.tsx +161 -0
- package/src/wallet/components/account/AccountDisplay.tsx +50 -0
- package/src/wallet/components/connect/ConnectButton.tsx +100 -0
- package/src/wallet/components/connect/ConnectorDialog.tsx +125 -0
- package/src/wallet/components/index.ts +3 -0
- package/src/wallet/connection.ts +151 -0
- package/src/wallet/context/StellarWalletContext.ts +32 -0
- package/src/wallet/context/index.ts +4 -0
- package/src/wallet/context/useStellarWalletContext.ts +17 -0
- package/src/wallet/hooks/facade-hooks.ts +31 -0
- package/src/wallet/hooks/index.ts +7 -0
- package/src/wallet/hooks/useStellarAccount.ts +27 -0
- package/src/wallet/hooks/useStellarConnect.ts +60 -0
- package/src/wallet/hooks/useStellarDisconnect.ts +47 -0
- package/src/wallet/hooks/useUiKitConfig.ts +40 -0
- package/src/wallet/implementation/wallets-kit-implementation.ts +379 -0
- package/src/wallet/index.ts +11 -0
- package/src/wallet/services/__tests__/configResolutionService.test.ts +163 -0
- package/src/wallet/services/configResolutionService.ts +65 -0
- package/src/wallet/stellar-wallets-kit/StellarWalletsKitConnectButton.tsx +82 -0
- package/src/wallet/stellar-wallets-kit/__mocks__/@creit.tech/stellar-wallets-kit.ts +48 -0
- package/src/wallet/stellar-wallets-kit/__tests__/export-service.test.ts +93 -0
- package/src/wallet/stellar-wallets-kit/__tests__/stellarUiKitManager.test.ts +0 -0
- package/src/wallet/stellar-wallets-kit/config-generator.ts +75 -0
- package/src/wallet/stellar-wallets-kit/export-service.ts +19 -0
- package/src/wallet/stellar-wallets-kit/index.ts +3 -0
- package/src/wallet/stellar-wallets-kit/stellarUiKitManager.ts +235 -0
- package/src/wallet/types.ts +19 -0
- package/src/wallet/utils/__tests__/filterWalletComponents.test.ts +150 -0
- package/src/wallet/utils/__tests__/uiKitService.test.ts +189 -0
- package/src/wallet/utils/filterWalletComponents.ts +89 -0
- package/src/wallet/utils/index.ts +3 -0
- package/src/wallet/utils/stellarWalletImplementationManager.ts +118 -0
- package/src/wallet/utils/uiKitService.ts +74 -0
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Address Validation Module for Access Control
|
|
3
|
+
*
|
|
4
|
+
* Centralizes address validation for access control operations.
|
|
5
|
+
* Uses Stellar-specific validation from the validation module and
|
|
6
|
+
* shared normalization utilities from @openzeppelin/ui-utils.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { ConfigurationInvalid } from '@openzeppelin/ui-types';
|
|
10
|
+
import { normalizeAddress } from '@openzeppelin/ui-utils';
|
|
11
|
+
|
|
12
|
+
import { isValidAccountAddress, isValidContractAddress } from '../validation/address';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Validates a Stellar contract address
|
|
16
|
+
*
|
|
17
|
+
* @param address The contract address to validate
|
|
18
|
+
* @param paramName Optional parameter name for error messages (defaults to 'contractAddress')
|
|
19
|
+
* @throws ConfigurationInvalid if the address is invalid
|
|
20
|
+
*/
|
|
21
|
+
export function validateContractAddress(address: string, paramName = 'contractAddress'): void {
|
|
22
|
+
if (!address || typeof address !== 'string' || address.trim() === '') {
|
|
23
|
+
throw new ConfigurationInvalid(
|
|
24
|
+
`${paramName} is required and must be a non-empty string`,
|
|
25
|
+
address,
|
|
26
|
+
paramName
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (!isValidContractAddress(address)) {
|
|
31
|
+
throw new ConfigurationInvalid(
|
|
32
|
+
`Invalid Stellar contract address: ${address}. Contract addresses must start with 'C' and be valid StrKey format.`,
|
|
33
|
+
address,
|
|
34
|
+
paramName
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Validates a Stellar account address (for role grants, ownership transfers, etc.)
|
|
41
|
+
*
|
|
42
|
+
* @param address The account address to validate
|
|
43
|
+
* @param paramName Optional parameter name for error messages (defaults to 'account')
|
|
44
|
+
* @throws ConfigurationInvalid if the address is invalid
|
|
45
|
+
*/
|
|
46
|
+
export function validateAccountAddress(address: string, paramName = 'account'): void {
|
|
47
|
+
if (!address || typeof address !== 'string' || address.trim() === '') {
|
|
48
|
+
throw new ConfigurationInvalid(
|
|
49
|
+
`${paramName} is required and must be a non-empty string`,
|
|
50
|
+
address,
|
|
51
|
+
paramName
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (!isValidAccountAddress(address)) {
|
|
56
|
+
throw new ConfigurationInvalid(
|
|
57
|
+
`Invalid Stellar account address: ${address}. Account addresses must start with 'G' and be valid Ed25519 public keys.`,
|
|
58
|
+
address,
|
|
59
|
+
paramName
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Validates a Stellar address that can be either an account or contract address
|
|
66
|
+
* (e.g., for ownership transfers where the new owner can be either type)
|
|
67
|
+
*
|
|
68
|
+
* @param address The address to validate (account or contract)
|
|
69
|
+
* @param paramName Optional parameter name for error messages (defaults to 'address')
|
|
70
|
+
* @throws ConfigurationInvalid if the address is invalid
|
|
71
|
+
*/
|
|
72
|
+
export function validateAddress(address: string, paramName = 'address'): void {
|
|
73
|
+
if (!address || typeof address !== 'string' || address.trim() === '') {
|
|
74
|
+
throw new ConfigurationInvalid(
|
|
75
|
+
`${paramName} is required and must be a non-empty string`,
|
|
76
|
+
address,
|
|
77
|
+
paramName
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Check if it's a valid account address OR contract address
|
|
82
|
+
if (!isValidAccountAddress(address) && !isValidContractAddress(address)) {
|
|
83
|
+
throw new ConfigurationInvalid(
|
|
84
|
+
`Invalid Stellar address: ${address}. Address must be a valid account address (starts with 'G') or contract address (starts with 'C').`,
|
|
85
|
+
address,
|
|
86
|
+
paramName
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Validates both contract and account addresses for operations
|
|
93
|
+
*
|
|
94
|
+
* @param contractAddress The contract address
|
|
95
|
+
* @param accountAddress The account address
|
|
96
|
+
* @throws ConfigurationInvalid if either address is invalid
|
|
97
|
+
*/
|
|
98
|
+
export function validateAddresses(contractAddress: string, accountAddress: string): void {
|
|
99
|
+
validateContractAddress(contractAddress);
|
|
100
|
+
validateAccountAddress(accountAddress);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Normalizes a Stellar address using shared utils
|
|
105
|
+
* This is useful for case-insensitive and whitespace-insensitive comparison
|
|
106
|
+
*
|
|
107
|
+
* @param address The address to normalize
|
|
108
|
+
* @returns The normalized address
|
|
109
|
+
*/
|
|
110
|
+
export function normalizeStellarAddress(address: string): string {
|
|
111
|
+
return normalizeAddress(address);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Maximum length for a Soroban Symbol (role identifier)
|
|
116
|
+
* Soroban symbols are limited to 32 characters
|
|
117
|
+
*/
|
|
118
|
+
const MAX_ROLE_ID_LENGTH = 32;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Valid pattern for Soroban Symbol characters
|
|
122
|
+
* Symbols can contain alphanumeric characters and underscores
|
|
123
|
+
*/
|
|
124
|
+
const VALID_ROLE_ID_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Validates a role identifier (Soroban Symbol)
|
|
128
|
+
*
|
|
129
|
+
* Role IDs must be:
|
|
130
|
+
* - Non-empty strings
|
|
131
|
+
* - Max 32 characters (Soroban Symbol limit)
|
|
132
|
+
* - Start with a letter or underscore
|
|
133
|
+
* - Contain only alphanumeric characters and underscores
|
|
134
|
+
*
|
|
135
|
+
* @param roleId The role identifier to validate
|
|
136
|
+
* @param paramName Optional parameter name for error messages
|
|
137
|
+
* @throws ConfigurationInvalid if the role ID is invalid
|
|
138
|
+
*/
|
|
139
|
+
export function validateRoleId(roleId: string, paramName = 'roleId'): void {
|
|
140
|
+
if (!roleId || typeof roleId !== 'string') {
|
|
141
|
+
throw new ConfigurationInvalid(
|
|
142
|
+
`${paramName} is required and must be a non-empty string`,
|
|
143
|
+
roleId,
|
|
144
|
+
paramName
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const trimmed = roleId.trim();
|
|
149
|
+
if (trimmed === '') {
|
|
150
|
+
throw new ConfigurationInvalid(
|
|
151
|
+
`${paramName} cannot be empty or whitespace-only`,
|
|
152
|
+
roleId,
|
|
153
|
+
paramName
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (trimmed.length > MAX_ROLE_ID_LENGTH) {
|
|
158
|
+
throw new ConfigurationInvalid(
|
|
159
|
+
`${paramName} exceeds maximum length of ${MAX_ROLE_ID_LENGTH} characters: "${trimmed}" (${trimmed.length} chars)`,
|
|
160
|
+
roleId,
|
|
161
|
+
paramName
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (!VALID_ROLE_ID_PATTERN.test(trimmed)) {
|
|
166
|
+
throw new ConfigurationInvalid(
|
|
167
|
+
`${paramName} contains invalid characters: "${trimmed}". Role IDs must start with a letter or underscore and contain only alphanumeric characters and underscores.`,
|
|
168
|
+
roleId,
|
|
169
|
+
paramName
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Validates an array of role identifiers
|
|
176
|
+
*
|
|
177
|
+
* @param roleIds The array of role identifiers to validate
|
|
178
|
+
* @param paramName Optional parameter name for error messages
|
|
179
|
+
* @throws ConfigurationInvalid if any role ID is invalid or if the array is invalid
|
|
180
|
+
* @returns The validated and deduplicated array of role IDs
|
|
181
|
+
*/
|
|
182
|
+
export function validateRoleIds(roleIds: string[], paramName = 'roleIds'): string[] {
|
|
183
|
+
if (!Array.isArray(roleIds)) {
|
|
184
|
+
throw new ConfigurationInvalid(`${paramName} must be an array`, String(roleIds), paramName);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Validate each role ID
|
|
188
|
+
for (let i = 0; i < roleIds.length; i++) {
|
|
189
|
+
validateRoleId(roleIds[i], `${paramName}[${i}]`);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Deduplicate and return
|
|
193
|
+
return [...new Set(roleIds.map((r) => r.trim()))];
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Result of expiration ledger validation
|
|
198
|
+
*
|
|
199
|
+
* Returned by {@link validateExpirationLedger} to indicate whether
|
|
200
|
+
* a proposed expiration ledger is valid for a two-step ownership transfer.
|
|
201
|
+
*
|
|
202
|
+
* @example
|
|
203
|
+
* ```typescript
|
|
204
|
+
* const currentLedger = await getCurrentLedger(networkConfig);
|
|
205
|
+
* const result = validateExpirationLedger(expirationLedger, currentLedger);
|
|
206
|
+
* if (!result.valid) {
|
|
207
|
+
* throw new ConfigurationInvalid(result.error!, String(expirationLedger), 'expirationLedger');
|
|
208
|
+
* }
|
|
209
|
+
* ```
|
|
210
|
+
*/
|
|
211
|
+
export interface ExpirationValidationResult {
|
|
212
|
+
/** Whether the expiration ledger is valid (must be strictly greater than current ledger) */
|
|
213
|
+
valid: boolean;
|
|
214
|
+
/** The current ledger sequence used for comparison */
|
|
215
|
+
currentLedger: number;
|
|
216
|
+
/** Human-readable error message if validation failed */
|
|
217
|
+
error?: string;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Validates an expiration ledger against the current ledger sequence
|
|
222
|
+
*
|
|
223
|
+
* For two-step Ownable contracts, the expiration ledger must be strictly greater
|
|
224
|
+
* than the current ledger (per FR-020: expirationLedger == currentLedger is invalid).
|
|
225
|
+
*
|
|
226
|
+
* @param expirationLedger The proposed expiration ledger sequence
|
|
227
|
+
* @param currentLedger The current ledger sequence number
|
|
228
|
+
* @returns Validation result with valid flag, currentLedger, and optional error message
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* ```typescript
|
|
232
|
+
* const currentLedger = await getCurrentLedger(networkConfig);
|
|
233
|
+
* const result = validateExpirationLedger(expirationLedger, currentLedger);
|
|
234
|
+
* if (!result.valid) {
|
|
235
|
+
* throw new ConfigurationInvalid(result.error, 'expirationLedger');
|
|
236
|
+
* }
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
export function validateExpirationLedger(
|
|
240
|
+
expirationLedger: number,
|
|
241
|
+
currentLedger: number
|
|
242
|
+
): ExpirationValidationResult {
|
|
243
|
+
// Per FR-020: expirationLedger must be strictly greater than currentLedger
|
|
244
|
+
if (expirationLedger <= currentLedger) {
|
|
245
|
+
return {
|
|
246
|
+
valid: false,
|
|
247
|
+
currentLedger,
|
|
248
|
+
error: `Expiration ledger ${expirationLedger} has already passed or equals current ledger. Current ledger is ${currentLedger}. Expiration must be strictly greater than current ledger.`,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return {
|
|
253
|
+
valid: true,
|
|
254
|
+
currentLedger,
|
|
255
|
+
};
|
|
256
|
+
}
|