@capxul/sdk 4.20.0-beta.5 → 4.20.0-beta.7
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 +57 -26
- package/dist/{OAuthBearerAuthClient-BAxoi3SD.d.mts → OAuthBearerAuthClient-DOPDDSPs.d.mts} +9 -4
- package/dist/{OAuthBearerAuthClient-BqQz-bnO.mjs → OAuthBearerAuthClient-DdKYPHE0.mjs} +94 -102
- package/dist/index.d.mts +65 -17
- package/dist/index.mjs +3 -3
- package/dist/node/index.d.mts +1 -1
- package/dist/node/index.mjs +1 -1
- package/dist/{production-q0kwUWcj.mjs → production-B63Xm_fl.mjs} +3588 -2153
- package/dist/{production-DAhaxUik.d.mts → production-UMTDZSTH.d.mts} +804 -177
- package/dist/testing/index.d.mts +2 -2
- package/dist/testing/index.mjs +6 -6
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -19,51 +19,44 @@ const client = created.value;
|
|
|
19
19
|
Every public operation resolves a `Promise<CapxulResult<T>>`. Domain failures
|
|
20
20
|
are values, not thrown exceptions.
|
|
21
21
|
|
|
22
|
-
##
|
|
22
|
+
## Asset amount input and display
|
|
23
23
|
|
|
24
|
-
Use the
|
|
25
|
-
convert a
|
|
24
|
+
Use the asset helpers at Payment form and display boundaries. They keep the
|
|
25
|
+
exact AssetId and do not convert a value to a JavaScript number.
|
|
26
26
|
|
|
27
27
|
```ts
|
|
28
|
-
import {
|
|
28
|
+
import { formatAssetAmount, parseAssetAmount, requireAsset, TOKENS } from "@capxul/sdk";
|
|
29
29
|
|
|
30
|
-
const amount =
|
|
31
|
-
currency: account.available.currency,
|
|
32
|
-
decimals: account.available.decimals,
|
|
33
|
-
});
|
|
30
|
+
const amount = parseAssetAmount("1,000.25", requireAsset(TOKENS.BASE_SEPOLIA.CAPXUL_TEST_USDC));
|
|
34
31
|
|
|
35
32
|
if ("kind" in amount) {
|
|
36
33
|
console.error(amount.reason); // closed code — the app owns the sentence (ADR-0023)
|
|
37
34
|
} else {
|
|
38
|
-
console.log(
|
|
39
|
-
console.log(formatMoney(amount, { grammar: "code" })); // 1,000.25 USD
|
|
35
|
+
console.log(formatAssetAmount(amount)); // 1,000.25 USDC
|
|
40
36
|
}
|
|
41
37
|
```
|
|
42
38
|
|
|
43
|
-
`
|
|
44
|
-
|
|
39
|
+
`parseAssetAmount` returns validation errors as values. Payment, request,
|
|
40
|
+
Budget, Payroll, and activity amounts require AssetAmount. Fiat Money remains
|
|
41
|
+
separate valuation data.
|
|
45
42
|
|
|
46
|
-
##
|
|
43
|
+
## Value all asset positions
|
|
47
44
|
|
|
48
|
-
`holdings.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
stands for no supported currency is skipped, because it cannot be rendered.
|
|
45
|
+
Use `holdings.current` for raw positions. Use `valueIn` to value exact asset
|
|
46
|
+
quantities in a display currency. A token symbol does not identify an asset.
|
|
47
|
+
Quantities from different assets cannot be compared as a headline balance.
|
|
52
48
|
|
|
53
49
|
```ts
|
|
54
|
-
import { formatMoney,
|
|
55
|
-
|
|
56
|
-
const result = await client.holdings.primary();
|
|
50
|
+
import { formatMoney, valueIn } from "@capxul/sdk";
|
|
57
51
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
console.log(
|
|
61
|
-
console.log(formatMoney(holding.available, { grammar: "code" })); // e.g. "1,250.50 USD"
|
|
52
|
+
const valuation = valueIn(amounts, displayCurrency, rates);
|
|
53
|
+
if (valuation.total !== null) {
|
|
54
|
+
console.log(formatMoney(valuation.total));
|
|
62
55
|
}
|
|
63
56
|
```
|
|
64
57
|
|
|
65
|
-
`
|
|
66
|
-
|
|
58
|
+
Keep `valuation.unrated` visible beside the known subtotal. A missing rate
|
|
59
|
+
does not mean a zero balance.
|
|
67
60
|
|
|
68
61
|
## Observability
|
|
69
62
|
|
|
@@ -105,6 +98,11 @@ The backend remains the authority for reserved names and global uniqueness.
|
|
|
105
98
|
The method returns only after the client requirement reaches a ready Account.
|
|
106
99
|
The React frontend does not use this journey yet.
|
|
107
100
|
|
|
101
|
+
A Node host that keeps login outside the browser can pass `openfortSignerFactory`.
|
|
102
|
+
The factory receives only the validated Openfort and auth bootstrap fields. Its
|
|
103
|
+
browser page can use `createOpenfortBrowserSigner` with host-owned access-token
|
|
104
|
+
and encryption-session callbacks. It does not need a second login or private SDK import.
|
|
105
|
+
|
|
108
106
|
## Published entry points
|
|
109
107
|
|
|
110
108
|
The packed npm package exposes only:
|
|
@@ -173,3 +171,36 @@ operator secrets and prove only the path named by the command. See
|
|
|
173
171
|
The browser production path owns its Openfort signer when no signer is supplied.
|
|
174
172
|
Current integration recovery evidence and its published-package boundary are
|
|
175
173
|
tracked in the [#870 receipt](../../docs/receipts/issue-870-openfort-signer-recovery-RECEIPT-2026-07-19.md).
|
|
174
|
+
|
|
175
|
+
### Node session storage
|
|
176
|
+
|
|
177
|
+
A Node host can pass `nodeSessionStorage: { load, save }` to
|
|
178
|
+
`createCapxulClient`. Both methods return promises. `load` returns an opaque
|
|
179
|
+
BetterAuth credential or `null`; `save` receives the credential or `null` on
|
|
180
|
+
logout. Store it with owner-only access and isolate it by application and
|
|
181
|
+
environment. Do not print it or use a cached `AuthSession` as backend authority.
|
|
182
|
+
The SDK validates the credential and expiry with BetterAuth on process restart.
|
|
183
|
+
With durable storage, each adapter serializes session reads, OTP verification,
|
|
184
|
+
sign-out, and Convex token reads. A delayed response cannot clear or rotate a
|
|
185
|
+
credential from a later operation on that adapter. Cancellation while queued
|
|
186
|
+
returns immediately and prevents that operation from reaching the provider.
|
|
187
|
+
Hosts that share storage across clients or processes must fence writes, for
|
|
188
|
+
example with an atomic compare-and-set; the adapter cannot order other clients.
|
|
189
|
+
|
|
190
|
+
For separate OTP request and verification processes, retain the email and
|
|
191
|
+
original request timestamp. After `auth.getSession()` confirms signed-out state,
|
|
192
|
+
call `auth.resumeOtp({ email, requestedAt })`, then `auth.verifyOtp({ email,
|
|
193
|
+
code })`. Resume restores pending input only. It does not send another OTP or
|
|
194
|
+
authenticate the caller. Keep OTP values out of arguments, logs, and stored data.
|
|
195
|
+
|
|
196
|
+
### Existing financial documents
|
|
197
|
+
|
|
198
|
+
Use `paymentDocuments.verify({ documentHash, contentHash })` to verify stored
|
|
199
|
+
content. Use `paymentDocuments.render` with the same pair for safe semantic HTML.
|
|
200
|
+
Call `paymentDocuments.get` only for a deliberate download. Its `bytesBase64`
|
|
201
|
+
contains the exact stored bytes. Do not log document results or error payloads.
|
|
202
|
+
Get references from Payment or Movement activity detail. References include
|
|
203
|
+
kind, format, and role. A hash is not permission to read a document.
|
|
204
|
+
Reads check current Payment participants or current Movement actor access.
|
|
205
|
+
Missing and unauthorized pairs return the same refusal. These methods do not
|
|
206
|
+
create documents or add Payment links.
|
|
@@ -254,6 +254,7 @@ declare const Errors: {
|
|
|
254
254
|
readonly method: string;
|
|
255
255
|
readonly currentState: string;
|
|
256
256
|
readonly validStates: readonly string[];
|
|
257
|
+
readonly organizationId?: string;
|
|
257
258
|
}) => CapxulError;
|
|
258
259
|
};
|
|
259
260
|
//#endregion
|
|
@@ -311,9 +312,9 @@ type Money = {
|
|
|
311
312
|
type Account$1 = {
|
|
312
313
|
readonly id: AccountId;
|
|
313
314
|
readonly balances: readonly AccountPosition[];
|
|
314
|
-
/** Fiat valuation of `balances`.
|
|
315
|
-
readonly balance: Money;
|
|
316
|
-
readonly available: Money;
|
|
315
|
+
/** Fiat valuation of `balances`. `null` means at least one position has no rate. */
|
|
316
|
+
readonly balance: Money | null;
|
|
317
|
+
readonly available: Money | null;
|
|
317
318
|
};
|
|
318
319
|
/**
|
|
319
320
|
* One asset position on an Account. `asset` is the identity; `symbol` and
|
|
@@ -391,8 +392,12 @@ declare const SUPPORTED_CURRENCIES: readonly [{
|
|
|
391
392
|
}];
|
|
392
393
|
type SupportedCurrencyCode = (typeof SUPPORTED_CURRENCIES)[number]["code"];
|
|
393
394
|
declare function toAddress(raw: unknown): Address$1;
|
|
395
|
+
declare function toAccountId(raw: unknown): AccountId;
|
|
394
396
|
declare function toPartyId(raw: unknown): PartyId;
|
|
395
397
|
declare function toHandle(raw: unknown): Handle;
|
|
398
|
+
declare function toPermissionId(raw: unknown): PermissionId;
|
|
399
|
+
declare function toBudgetId(raw: unknown): BudgetId;
|
|
400
|
+
declare function toOrgId(raw: unknown): OrgId;
|
|
396
401
|
declare function toCountryCode(raw: unknown): CountryCode;
|
|
397
402
|
//#endregion
|
|
398
403
|
//#region ../config/src/capxul-payments-v2.d.ts
|
|
@@ -642,4 +647,4 @@ interface OAuthBearerAuthClientInput {
|
|
|
642
647
|
*/
|
|
643
648
|
declare function oauthBearerAuthClient(input: OAuthBearerAuthClientInput): AuthClientPort;
|
|
644
649
|
//#endregion
|
|
645
|
-
export { OrgId as $, Address$1 as A,
|
|
650
|
+
export { OrgId as $, Address$1 as A, ChainCause as At, BudgetId as B, AuthCachePort as C, CapxulError as Ct, Account$1 as D, Failure as Dt, CAPXUL_PAYMENTS_V2_ADDRESS as E, Errors as Et, AssetAmount as F, CurrencyCode as G, ClientGrantId as H, AssetId as I, EVM_ADDRESS_RE as J, DocumentHash as K, AuthSession as L, AllowedOrigin as M, FAILURE_MODES as Mt, AnonymousDistinctId as N, FailureMode as Nt, AccountId as O, isCapxulError as Ot, AppId as P, RevertSummary as Pt, Money as Q, AuthUserId as R, AuthCacheError as S, CAPXUL_ERROR_CODES as St, CachedJwt as T, CapxulErrorDetails as Tt, ClientRequestId as U, ChainId as V, CountryCode as W, EpochMs as X, Email as Y, Handle as Z, Session as _, toCountryCode as _t, Eip1193RequestProvider as a, PermissionId as at, AuthClientPort as b, toPartyId as bt, injectedWalletSigner as c, RoleKey as ct, AccountRequirement as d, TesterKind as dt, PartyId as et, Eip1193Provider as f, TxHash as ft, Profile as g, toBudgetId as gt, CapxulResult as h, toAddress as ht, CapxulSigner as i, PermissionAssignmentId as it, AllowanceKey as j, ChainUpstream as jt, AccountPosition as k, CHAIN_UPSTREAMS as kt, AccountProvider as l, SessionToken as lt, localPrivateKeyAccountProvider as m, toAccountId as mt, oauthBearerAuthClient as n, PayrollGroupId as nt, SignerStatus as o, Profile$1 as ot, eip1193AccountProvider as p, WeiAmount as pt, DurationMs as q, CapxulDigestSigner as r, PayrollRunId as rt, SignerStatusStore as s, PublishableKey as st, OAuthBearerAuthClientInput as t, PaymentCommandId as tt, AccountProviderSource as u, SmartAccount$1 as ut, SmartAccount as v, toHandle as vt, AuthCachePortTag as w, CapxulErrorCode as wt, CanSendOtpStatus as x, toPermissionId as xt, ClockPort as y, toOrgId as yt, BlockNumber as z };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { concat, encodeAbiParameters, encodeFunctionData, encodePacked, getContractAddress, keccak256, padHex,
|
|
1
|
+
import { concat, encodeAbiParameters, encodeFunctionData, encodePacked, getContractAddress, keccak256, padHex, toBytes, toEventSelector, toFunctionSelector, toFunctionSignature } from "viem";
|
|
2
2
|
import { Context, Data, Effect, Layer, Result } from "effect";
|
|
3
3
|
//#region ../errors/src/secret-material.ts
|
|
4
4
|
const CREDENTIAL_FIELDS = /* @__PURE__ */ new Set([
|
|
@@ -807,8 +807,10 @@ const Errors = {
|
|
|
807
807
|
* enumerates the states the method accepts.
|
|
808
808
|
*/
|
|
809
809
|
wrongState: (details) => new CapxulError("WRONG_STATE", `${details.method} called from state '${details.currentState}'; valid states: ${details.validStates.join(", ")}`, { details: {
|
|
810
|
-
|
|
811
|
-
|
|
810
|
+
method: details.method,
|
|
811
|
+
currentState: details.currentState,
|
|
812
|
+
validStates: [...details.validStates],
|
|
813
|
+
...details.organizationId === void 0 ? {} : { organizationId: details.organizationId }
|
|
812
814
|
} })
|
|
813
815
|
};
|
|
814
816
|
//#endregion
|
|
@@ -941,6 +943,12 @@ function toHandle(raw) {
|
|
|
941
943
|
if (typeof raw !== "string" || !HANDLE_RE.test(raw)) throw Errors.invalidInput("handle", invalidValueReason("must be 3-30 characters of a-z, 0-9, underscore, or hyphen", raw));
|
|
942
944
|
return raw;
|
|
943
945
|
}
|
|
946
|
+
function toPermissionId(raw) {
|
|
947
|
+
return toNonEmptyStringBrand(raw, "permissionId");
|
|
948
|
+
}
|
|
949
|
+
function toPermissionAssignmentId(raw) {
|
|
950
|
+
return toNonEmptyStringBrand(raw, "permissionAssignmentId");
|
|
951
|
+
}
|
|
944
952
|
function toBudgetId(raw) {
|
|
945
953
|
return toNonEmptyStringBrand(raw, "budgetId");
|
|
946
954
|
}
|
|
@@ -1061,33 +1069,11 @@ function invalidValueReason(prefix, raw) {
|
|
|
1061
1069
|
}
|
|
1062
1070
|
//#endregion
|
|
1063
1071
|
//#region ../config/src/tokens.ts
|
|
1064
|
-
/** `TestUSDC` ("USDX") — Base Sepolia, 6 decimals, open `mint`. (Canon §1.) */
|
|
1065
|
-
const USDX_ADDRESS_BASE_SEPOLIA = "0xf09fcbb6df9f8f918e58f9c8ab15a76ade862b77";
|
|
1066
|
-
const USDX_DEPLOYMENT_START_BLOCK = 39860173;
|
|
1067
|
-
/**
|
|
1068
|
-
* The ERC-20 `symbol()` the deployed `TestUSDC` contract returns
|
|
1069
|
-
* (`packages/contracts/src/TestUSDC.sol:10`). It travels with the address and
|
|
1070
|
-
* the decimals so a holdings row can never carry one token's address with
|
|
1071
|
-
* another token's display symbol. This is the display symbol, not the
|
|
1072
|
-
* currency: see `USDX_CURRENCY` below.
|
|
1073
|
-
*/
|
|
1074
|
-
const USDX_SYMBOL = "USDX";
|
|
1075
1072
|
const SYNTHETIC_TEST_ASSET_SOURCE = "synthetic-test-liquidity";
|
|
1076
|
-
const USDX_ASSET = {
|
|
1077
|
-
assetId: assetIdFor(84532, USDX_ADDRESS_BASE_SEPOLIA),
|
|
1078
|
-
chainId: toChainId(84532),
|
|
1079
|
-
symbol: USDX_SYMBOL,
|
|
1080
|
-
peg: toCurrencyCode("USD"),
|
|
1081
|
-
tokenAddress: USDX_ADDRESS_BASE_SEPOLIA,
|
|
1082
|
-
deploymentStartBlock: USDX_DEPLOYMENT_START_BLOCK,
|
|
1083
|
-
decimals: 6,
|
|
1084
|
-
source: "legacy"
|
|
1085
|
-
};
|
|
1086
|
-
({ ...USDX_ASSET }), USDX_ASSET.peg;
|
|
1087
1073
|
/**
|
|
1088
1074
|
* The candidate tier: five owned test assets, every field read back from Base
|
|
1089
|
-
* Sepolia after the deployment that created it (chain 84532,
|
|
1090
|
-
* 46,
|
|
1075
|
+
* Sepolia after the deployment that created it (chain 84532, block
|
|
1076
|
+
* 46,690,061). Real contracts, authored liquidity, no settlement
|
|
1091
1077
|
* admission — so rollback is removing consumers, never relabelling a
|
|
1092
1078
|
* deployed address or deleting its history.
|
|
1093
1079
|
*
|
|
@@ -1096,84 +1082,95 @@ const USDX_ASSET = {
|
|
|
1096
1082
|
* address returning the same symbol, which is why the resolvers below key on
|
|
1097
1083
|
* `assetId`, or on chain plus address, and never on a symbol.
|
|
1098
1084
|
*/
|
|
1099
|
-
const
|
|
1100
|
-
{
|
|
1101
|
-
assetId: assetIdFor(84532, "
|
|
1085
|
+
const SYNTHETIC_TEST_ASSET_FIXTURES = {
|
|
1086
|
+
usdc: {
|
|
1087
|
+
assetId: assetIdFor(84532, "0x06ba8b863ca77490b0e7008427562bdbfcff730e"),
|
|
1102
1088
|
chainId: toChainId(84532),
|
|
1103
|
-
tokenAddress: "
|
|
1089
|
+
tokenAddress: "0x06ba8b863ca77490b0e7008427562bdbfcff730e",
|
|
1104
1090
|
symbol: "USDC",
|
|
1105
1091
|
decimals: 6,
|
|
1106
1092
|
peg: toCurrencyCode("USD"),
|
|
1107
|
-
deploymentStartBlock:
|
|
1108
|
-
deploymentTransaction: "
|
|
1093
|
+
deploymentStartBlock: 46690061,
|
|
1094
|
+
deploymentTransaction: "0x2661b7af5f62b9e31c707a59746cda65b90ba4448852317ac1968162fb94ff52",
|
|
1109
1095
|
source: SYNTHETIC_TEST_ASSET_SOURCE
|
|
1110
1096
|
},
|
|
1111
|
-
{
|
|
1112
|
-
assetId: assetIdFor(84532, "
|
|
1097
|
+
usdt: {
|
|
1098
|
+
assetId: assetIdFor(84532, "0xcb5f361ae070e75d573941b8cd54995fa3876d75"),
|
|
1113
1099
|
chainId: toChainId(84532),
|
|
1114
|
-
tokenAddress: "
|
|
1100
|
+
tokenAddress: "0xcb5f361ae070e75d573941b8cd54995fa3876d75",
|
|
1115
1101
|
symbol: "USDT",
|
|
1116
1102
|
decimals: 6,
|
|
1117
1103
|
peg: toCurrencyCode("USD"),
|
|
1118
|
-
deploymentStartBlock:
|
|
1119
|
-
deploymentTransaction: "
|
|
1104
|
+
deploymentStartBlock: 46690061,
|
|
1105
|
+
deploymentTransaction: "0x98e5303f97974a31eddb61ad030072d900ce7283ce8080bfe0b9e5ea6f297749",
|
|
1120
1106
|
source: SYNTHETIC_TEST_ASSET_SOURCE
|
|
1121
1107
|
},
|
|
1122
|
-
{
|
|
1123
|
-
assetId: assetIdFor(84532, "
|
|
1108
|
+
weth: {
|
|
1109
|
+
assetId: assetIdFor(84532, "0x85b7bd39ce3df9a85135e1e307225dd435f67e47"),
|
|
1124
1110
|
chainId: toChainId(84532),
|
|
1125
|
-
tokenAddress: "
|
|
1111
|
+
tokenAddress: "0x85b7bd39ce3df9a85135e1e307225dd435f67e47",
|
|
1126
1112
|
symbol: "WETH",
|
|
1127
1113
|
decimals: 18,
|
|
1128
1114
|
peg: null,
|
|
1129
|
-
deploymentStartBlock:
|
|
1130
|
-
deploymentTransaction: "
|
|
1115
|
+
deploymentStartBlock: 46690061,
|
|
1116
|
+
deploymentTransaction: "0x48dfacc01c15adc34f6c629aec5c9ff7bb84176d448017da0d0d4fdaf8b5a68a",
|
|
1131
1117
|
source: SYNTHETIC_TEST_ASSET_SOURCE
|
|
1132
1118
|
},
|
|
1133
|
-
{
|
|
1134
|
-
assetId: assetIdFor(84532, "
|
|
1119
|
+
wbtc: {
|
|
1120
|
+
assetId: assetIdFor(84532, "0xcf433a81f507dcc88c2c404650ffafb40750b451"),
|
|
1135
1121
|
chainId: toChainId(84532),
|
|
1136
|
-
tokenAddress: "
|
|
1122
|
+
tokenAddress: "0xcf433a81f507dcc88c2c404650ffafb40750b451",
|
|
1137
1123
|
symbol: "WBTC",
|
|
1138
1124
|
decimals: 8,
|
|
1139
1125
|
peg: null,
|
|
1140
|
-
deploymentStartBlock:
|
|
1141
|
-
deploymentTransaction: "
|
|
1126
|
+
deploymentStartBlock: 46690061,
|
|
1127
|
+
deploymentTransaction: "0xa975fcda0a67509742243bbfc386032d2e0d6ca78404c255fae2e4ffae1c7f4d",
|
|
1142
1128
|
source: SYNTHETIC_TEST_ASSET_SOURCE
|
|
1143
1129
|
},
|
|
1144
|
-
{
|
|
1145
|
-
assetId: assetIdFor(84532, "
|
|
1130
|
+
cngn: {
|
|
1131
|
+
assetId: assetIdFor(84532, "0xda515a7267e190710f0003f951c62bcfd70d6b2a"),
|
|
1146
1132
|
chainId: toChainId(84532),
|
|
1147
|
-
tokenAddress: "
|
|
1133
|
+
tokenAddress: "0xda515a7267e190710f0003f951c62bcfd70d6b2a",
|
|
1148
1134
|
symbol: "cNGN",
|
|
1149
1135
|
decimals: 6,
|
|
1150
1136
|
peg: toCurrencyCode("NGN"),
|
|
1151
|
-
deploymentStartBlock:
|
|
1152
|
-
deploymentTransaction: "
|
|
1137
|
+
deploymentStartBlock: 46690061,
|
|
1138
|
+
deploymentTransaction: "0x6f6b0302448c7cd7db5c118a8250e548c6e72821df373e5a27550e5cdfa635a1",
|
|
1153
1139
|
source: SYNTHETIC_TEST_ASSET_SOURCE
|
|
1154
1140
|
}
|
|
1141
|
+
};
|
|
1142
|
+
const SYNTHETIC_TEST_ASSETS = [
|
|
1143
|
+
SYNTHETIC_TEST_ASSET_FIXTURES.usdc,
|
|
1144
|
+
SYNTHETIC_TEST_ASSET_FIXTURES.usdt,
|
|
1145
|
+
SYNTHETIC_TEST_ASSET_FIXTURES.weth,
|
|
1146
|
+
SYNTHETIC_TEST_ASSET_FIXTURES.wbtc,
|
|
1147
|
+
SYNTHETIC_TEST_ASSET_FIXTURES.cngn
|
|
1155
1148
|
];
|
|
1156
1149
|
toChainId(84532);
|
|
1157
1150
|
/**
|
|
1158
1151
|
* The settlement tier: the owned test assets admitted to the exact-transfer
|
|
1159
|
-
* path and to the treasury reads. USDC, USDT and WETH are equal assets.
|
|
1160
|
-
* is no default token
|
|
1161
|
-
* `LEGACY_MONEY_ASSETS` and is not a current treasury row.
|
|
1152
|
+
* path and to the treasury reads. USDC, USDT and WETH are equal assets.
|
|
1153
|
+
* There is no default token.
|
|
1162
1154
|
*/
|
|
1163
|
-
const
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
const CONFIGURED_MONEY_ASSETS =
|
|
1155
|
+
const SETTLEMENT_ASSETS_BASE_SEPOLIA = Object.freeze({
|
|
1156
|
+
CAPXUL_TEST_USDC: SYNTHETIC_TEST_ASSET_FIXTURES.usdc,
|
|
1157
|
+
CAPXUL_TEST_USDT: SYNTHETIC_TEST_ASSET_FIXTURES.usdt,
|
|
1158
|
+
CAPXUL_TEST_WETH: SYNTHETIC_TEST_ASSET_FIXTURES.weth
|
|
1159
|
+
});
|
|
1160
|
+
const CONFIGURED_MONEY_ASSETS = Object.freeze(Object.values(SETTLEMENT_ASSETS_BASE_SEPOLIA));
|
|
1161
|
+
/** Public AssetIds for the admitted Base Sepolia test assets. */
|
|
1162
|
+
const TOKENS = Object.freeze({ BASE_SEPOLIA: Object.freeze({
|
|
1163
|
+
CAPXUL_TEST_USDC: SETTLEMENT_ASSETS_BASE_SEPOLIA.CAPXUL_TEST_USDC.assetId,
|
|
1164
|
+
CAPXUL_TEST_USDT: SETTLEMENT_ASSETS_BASE_SEPOLIA.CAPXUL_TEST_USDT.assetId,
|
|
1165
|
+
CAPXUL_TEST_WETH: SETTLEMENT_ASSETS_BASE_SEPOLIA.CAPXUL_TEST_WETH.assetId
|
|
1166
|
+
}) });
|
|
1169
1167
|
/**
|
|
1170
1168
|
* Every known asset in ONE identity space. The tiers above declare admission;
|
|
1171
1169
|
* this is the only list an identity resolves against, so an asset is never
|
|
1172
1170
|
* two different things depending on which list a caller happened to read.
|
|
1173
1171
|
*/
|
|
1174
|
-
const MONEY_ASSET_REGISTRY = [
|
|
1172
|
+
const MONEY_ASSET_REGISTRY = [...SYNTHETIC_TEST_ASSETS];
|
|
1175
1173
|
CONFIGURED_MONEY_ASSETS.map((asset) => asset.tokenAddress.toLowerCase());
|
|
1176
|
-
USDX_ADDRESS_BASE_SEPOLIA.toLowerCase();
|
|
1177
1174
|
/** The registry row for `assetId` across every tier, or `null`. */
|
|
1178
1175
|
function configuredMoneyAssetById(assetId) {
|
|
1179
1176
|
const canonical = toAssetId(assetId);
|
|
@@ -1183,6 +1180,28 @@ function configuredMoneyAssetById(assetId) {
|
|
|
1183
1180
|
//#region ../config/src/org-payments.ts
|
|
1184
1181
|
/** Zodiac MultiSendCallOnly module on Base Sepolia. */
|
|
1185
1182
|
const MULTI_SEND_CALL_ONLY = "0x9641d764fc13c8b624c04430c7356c1c7c8102e2";
|
|
1183
|
+
/** Supported Organization permission identities, newest first. */
|
|
1184
|
+
const ORG_PERMISSION_IDENTITY_PROFILES = [{
|
|
1185
|
+
id: "zodiac-roles-2.1.1",
|
|
1186
|
+
moduleFactoryRuntimeKeccak256: "0x01623cbcf010a1c326230f1b2d5f48a66b440232ee49096102bc84967dc5f21e",
|
|
1187
|
+
mastercopy: "0xf2964ce6161ce0e75964fe7927ce114cb0b283d5",
|
|
1188
|
+
mastercopyRuntimeKeccak256: "0x471d8b3b419f1eb955230c0326c8812176df49bf3c7b414a563fda5a3c6c10b6",
|
|
1189
|
+
proxyRuntimeKeccak256: "0x248f9591f94c24c199ade3e73feb477cf02d387b2bea91f2f931a0deb094f163",
|
|
1190
|
+
multiSendUnwrapper: "0xb4cd4bb764c089f20da18700ce8bc5e49f369efd",
|
|
1191
|
+
multiSendUnwrapperRuntimeKeccak256: "0x1f6e088be5e6ef9d0fbe0547d3fa9a9e40d823433fd8a4449215b5663209a1eb"
|
|
1192
|
+
}, {
|
|
1193
|
+
id: "zodiac-roles-2.1.0",
|
|
1194
|
+
moduleFactoryRuntimeKeccak256: "0x01623cbcf010a1c326230f1b2d5f48a66b440232ee49096102bc84967dc5f21e",
|
|
1195
|
+
mastercopy: "0x9646fdad06d3e24444381f44362a3b0eb343d337",
|
|
1196
|
+
mastercopyRuntimeKeccak256: "0x87911cbc6aa0496e6bcb07dab2462b9c76daea130dede6dcc57d0adf307fa7ec",
|
|
1197
|
+
proxyRuntimeKeccak256: "0x9d4059abf46db50e4b48d9b6404b1f200cb5a1efeb3725be2de630a2a9001944",
|
|
1198
|
+
multiSendUnwrapper: "0x93b7fcbc63ed8a3a24b59e1c3e6649d50b7427c0",
|
|
1199
|
+
multiSendUnwrapperRuntimeKeccak256: "0x4d8d8608b70a6e2f40726b9dd74406bbf73e90cac58e23ee953e2b45ad7dc3df"
|
|
1200
|
+
}];
|
|
1201
|
+
const CURRENT_ORG_PERMISSION_IDENTITY = ORG_PERMISSION_IDENTITY_PROFILES[0];
|
|
1202
|
+
ORG_PERMISSION_IDENTITY_PROFILES[1];
|
|
1203
|
+
CURRENT_ORG_PERMISSION_IDENTITY.mastercopy;
|
|
1204
|
+
CURRENT_ORG_PERMISSION_IDENTITY.multiSendUnwrapper;
|
|
1186
1205
|
//#endregion
|
|
1187
1206
|
//#region ../config/src/safe.ts
|
|
1188
1207
|
const BASE_SEPOLIA_CHAIN_ID = 84532;
|
|
@@ -1226,7 +1245,7 @@ function normalizeSafeSaltEmail(email) {
|
|
|
1226
1245
|
* `keccak256(namespace + ":" + normalizeSafeSaltEmail(email))`.
|
|
1227
1246
|
*
|
|
1228
1247
|
* Namespace defaults to `CAPXUL_SAFE_SALT_NAMESPACE`
|
|
1229
|
-
* (`"capxul:staging:email:
|
|
1248
|
+
* (`"capxul:staging:email:v2"`) — the current Capxul scheme. Pass a
|
|
1230
1249
|
* different namespace only for pinned pre-v2 artifacts
|
|
1231
1250
|
* (`CAPXUL_SAFE_SALT_NAMESPACE_V1`, faucet Safe) or when bumping the scheme.
|
|
1232
1251
|
*
|
|
@@ -1235,7 +1254,7 @@ function normalizeSafeSaltEmail(email) {
|
|
|
1235
1254
|
* @returns The Capxul-namespaced salt nonce as a `bigint`
|
|
1236
1255
|
*/
|
|
1237
1256
|
function computeCapxulSafeSaltNonce(input) {
|
|
1238
|
-
const namespace = input.namespace ?? "capxul:staging:email:
|
|
1257
|
+
const namespace = input.namespace ?? "capxul:staging:email:v2";
|
|
1239
1258
|
const normalizedEmail = normalizeSafeSaltEmail(input.email);
|
|
1240
1259
|
return BigInt(keccak256(toBytes(`${namespace}:${normalizedEmail}`)));
|
|
1241
1260
|
}
|
|
@@ -1411,6 +1430,9 @@ function normalizeBindingEmail(email) {
|
|
|
1411
1430
|
return normalizeSafeSaltEmail(email);
|
|
1412
1431
|
}
|
|
1413
1432
|
//#endregion
|
|
1433
|
+
//#region ../config/src/role-dsl.ts
|
|
1434
|
+
const ADMIN_ROLE_LABEL = "Admin";
|
|
1435
|
+
//#endregion
|
|
1414
1436
|
//#region ../config/src/capxul-payments-v2.ts
|
|
1415
1437
|
/** The exact compiled CapxulPaymentsV2 ABI. */
|
|
1416
1438
|
const CAPXUL_PAYMENTS_V2_ABI = [
|
|
@@ -2056,38 +2078,6 @@ const CAPXUL_PAYMENTS_V2_ABI = [
|
|
|
2056
2078
|
];
|
|
2057
2079
|
/** Immutable CapxulPaymentsV2 deployment on Base Sepolia. */
|
|
2058
2080
|
const CAPXUL_PAYMENTS_V2_ADDRESS = "0x7a5c25aB7ce91d7a475B71cd1ec33E230291f8a4";
|
|
2059
|
-
//#endregion
|
|
2060
|
-
//#region ../config/src/route.ts
|
|
2061
|
-
/** USDX on Base Sepolia — the only settlement token in v1. */
|
|
2062
|
-
const USDX_BASE_SEPOLIA_TOKEN = {
|
|
2063
|
-
chainId: BASE_SEPOLIA_CHAIN_ID,
|
|
2064
|
-
address: USDX_ADDRESS_BASE_SEPOLIA,
|
|
2065
|
-
decimals: 6
|
|
2066
|
-
};
|
|
2067
|
-
USDX_BASE_SEPOLIA_TOKEN.chainId;
|
|
2068
|
-
USDX_BASE_SEPOLIA_TOKEN.chainId;
|
|
2069
|
-
10n ** BigInt(6);
|
|
2070
|
-
/**
|
|
2071
|
-
* The bootstrap manage role. It administers people and roles, cannot spend,
|
|
2072
|
-
* and is not a signer of the Organization Safe; "Owner" implied the latter,
|
|
2073
|
-
* so the label is Admin (ruled 2026-09-06).
|
|
2074
|
-
*/
|
|
2075
|
-
const ADMIN_ROLE_LABEL = "Admin";
|
|
2076
|
-
function normalizeOrgRoleLabel(label) {
|
|
2077
|
-
const normalized = label.trim().replace(/\s+/g, " ");
|
|
2078
|
-
if (normalized.length === 0) throw Errors.invalidInput("role.label", "must be a non-empty role label");
|
|
2079
|
-
return normalized;
|
|
2080
|
-
}
|
|
2081
|
-
function orgRoleKeyForLabel(label) {
|
|
2082
|
-
return keccak256(toBytes(normalizeOrgRoleLabel(label).toLowerCase()));
|
|
2083
|
-
}
|
|
2084
|
-
padHex(stringToHex("FM_DAILY"), {
|
|
2085
|
-
size: 32,
|
|
2086
|
-
dir: "right"
|
|
2087
|
-
}), padHex(stringToHex("TL_DAILY"), {
|
|
2088
|
-
size: 32,
|
|
2089
|
-
dir: "right"
|
|
2090
|
-
});
|
|
2091
2081
|
padHex(concat([MULTI_SEND_CALL_ONLY, "0x8d80ff0a"]), {
|
|
2092
2082
|
dir: "right",
|
|
2093
2083
|
size: 32
|
|
@@ -2100,9 +2090,9 @@ function paymentsV2Signature(name) {
|
|
|
2100
2090
|
paymentsV2Signature("send");
|
|
2101
2091
|
paymentsV2Signature("sendBatch");
|
|
2102
2092
|
paymentsV2Signature("createCommitment");
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
new Map([
|
|
2093
|
+
//#endregion
|
|
2094
|
+
//#region ../config/src/org-bootstrap.ts
|
|
2095
|
+
const ROLE_AUTHORITY_EVENT_BY_FUNCTION_SELECTOR = new Map([
|
|
2106
2096
|
["assignRoles(address,bytes32[],bool[])", "AssignRoles(address,bytes32[],bool[])"],
|
|
2107
2097
|
["allowTarget(bytes32,address,uint8)", "AllowTarget(bytes32,address,uint8)"],
|
|
2108
2098
|
["scopeTarget(bytes32,address)", "ScopeTarget(bytes32,address)"],
|
|
@@ -2112,6 +2102,8 @@ new Map([
|
|
|
2112
2102
|
["revokeFunction(bytes32,address,bytes4)", "RevokeFunction(bytes32,address,bytes4)"],
|
|
2113
2103
|
["setAllowance(bytes32,uint128,uint128,uint128,uint64,uint64)", "SetAllowance(bytes32,uint128,uint128,uint128,uint64,uint64)"]
|
|
2114
2104
|
].map(([functionSignature, eventSignature]) => [toFunctionSelector(functionSignature), toEventSelector(eventSignature)]));
|
|
2105
|
+
toEventSelector("AssignRoles(address,bytes32[],bool[])");
|
|
2106
|
+
new Set([...ROLE_AUTHORITY_EVENT_BY_FUNCTION_SELECTOR.values()].map((topic) => topic.toLowerCase()));
|
|
2115
2107
|
//#endregion
|
|
2116
2108
|
//#region src/ports/auth-client.ts
|
|
2117
2109
|
var AuthClientError = class extends Data.TaggedError("AuthClientError") {};
|
|
@@ -2489,4 +2481,4 @@ function readExchange(body) {
|
|
|
2489
2481
|
};
|
|
2490
2482
|
}
|
|
2491
2483
|
//#endregion
|
|
2492
|
-
export {
|
|
2484
|
+
export { toKycTier as $, EMAIL_RE as A, containsSensitiveMaterial as At, toAppId as B, ACCOUNT_ID_RE as C, chainCauseProperties as Ct, CLIENT_GRANT_ID_RE as D, isChainUpstream as Dt, BYTES32_RE as E, failureFingerprint as Et, assetIdFor as F, toCountryCode as G, toAuthUserId as H, currencySymbolFor as I, toEmail as J, toCurrencyCode as K, toAccountId as L, SUPPORTED_CURRENCY_CODES as M, redactSecrets as Mt, WEI_RE as N, redactUrlSecrets as Nt, CLIENT_REQUEST_ID_RE as O, isFailureMode as Ot, ZERO_BYTES32 as P, toJwtToken as Q, toAddress as R, configuredMoneyAssetById as S, boundedResponseHeaders as St, ASSET_ID_RE as T, decodeChainCause as Tt, toBudgetId as U, toAssetId as V, toChainId as W, toEpochSeconds as X, toEpochMs as Y, toHandle as Z, BASE_SEPOLIA_CHAIN_ID as _, EXPECTED_OPERATION_OUTCOMES as _t, parseAuthSession as a, toPermissionId as at, SYNTHETIC_TEST_ASSET_FIXTURES as b, CHAIN_UPSTREAMS as bt, AuthCachePortTag as c, toSessionToken as ct, authClientPortFromPromiseAdapter as d, toWeiAmount as dt, toOrgId as et, AuthClientError as f, validateHandle as ft, normalizeBindingEmail as g, CapxulError as gt, ADMIN_ROLE_LABEL as h, CAPXUL_ERROR_CODES as ht, BrowserAuthCacheAdapter as i, toPermissionAssignmentId as it, EVM_ADDRESS_RE as j, isCredentialField as jt, COUNTRY_CODE_RE as k, revertSummaryText as kt, SystemClockLayer as l, toTesterKind as lt, CAPXUL_PAYMENTS_V2_ADDRESS as m, decodeConvexError as mt, readClockNow as n, toPayrollGroupId as nt, parseCachedJwt as o, toPublishableKey as ot, AuthClientPortTag as p, HANDLE_RE as pt, toDurationMs as q, InMemoryAuthCacheAdapter as r, toPayrollRunId as rt, AuthCacheError as s, toRoleKey as st, oauthBearerAuthClient as t, toPartyId as tt, ClockPortTag as u, toTxHash as ut, deriveCapxulSafeAddress as v, Errors as vt, APP_ID_RE as w, chainEvidenceLabel as wt, TOKENS as x, FAILURE_MODES as xt, CONFIGURED_MONEY_ASSETS as y, isCapxulError as yt, toAllowedOrigin as z };
|