@capxul/mcp 4.2.0-rc.1 → 4.2.0-rc.10
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/dist/capxul-source.json +3 -3
- package/dist/main.mjs +1034 -47
- package/package.json +2 -2
package/dist/main.mjs
CHANGED
|
@@ -852,6 +852,7 @@ const COUNTRY_CODE_RE = /^[A-Z]{2}$/;
|
|
|
852
852
|
const ACCOUNT_ID_RE = /^account_[0-9A-Za-z]+$/;
|
|
853
853
|
const PARTY_ID_RE$1 = /^party_[0-9A-Za-z]+$/;
|
|
854
854
|
const APP_ID_RE = /^app_[0-7][0-9A-HJKMNP-TV-Z]{25}$/;
|
|
855
|
+
const TX_HASH_RE = /^0x[0-9a-f]{64}$/i;
|
|
855
856
|
const WEI_RE = /^[0-9]+$/;
|
|
856
857
|
Math.floor(Number.MAX_SAFE_INTEGER / 1e3);
|
|
857
858
|
function toAddress(raw) {
|
|
@@ -903,6 +904,10 @@ function toPublishableKey(raw) {
|
|
|
903
904
|
if (typeof raw !== "string" || !PUBLISHABLE_KEY_PATTERN.test(raw)) throw Errors.invalidInput("publishableKey", invalidValueReason("must match cap_pk_(test|live) plus 32 Crockford base32 chars", raw));
|
|
904
905
|
return raw;
|
|
905
906
|
}
|
|
907
|
+
function toTxHash(raw) {
|
|
908
|
+
if (typeof raw !== "string" || !TX_HASH_RE.test(raw)) throw Errors.invalidInput("txHash", invalidValueReason("must be 0x + 64 hex chars", raw));
|
|
909
|
+
return raw.toLowerCase();
|
|
910
|
+
}
|
|
906
911
|
function toEpochMs(raw) {
|
|
907
912
|
assertSafeNonNegativeInteger(raw, "epochMs");
|
|
908
913
|
return raw;
|
|
@@ -982,19 +987,108 @@ function invalidValueReason(prefix, raw) {
|
|
|
982
987
|
//#region ../../packages/config/src/tokens.ts
|
|
983
988
|
/** `TestUSDC` ("USDX") — Base Sepolia, 6 decimals, open `mint`. (Canon §1.) */
|
|
984
989
|
const USDX_ADDRESS_BASE_SEPOLIA = "0xf09fcbb6df9f8f918e58f9c8ab15a76ade862b77";
|
|
990
|
+
const USDX_DEPLOYMENT_START_BLOCK = 39860173;
|
|
991
|
+
/**
|
|
992
|
+
* The ERC-20 `symbol()` the deployed `TestUSDC` contract returns
|
|
993
|
+
* (`packages/contracts/src/TestUSDC.sol:10`). It travels with the address and
|
|
994
|
+
* the decimals so a holdings row can never carry one token's address with
|
|
995
|
+
* another token's display symbol. This is the display symbol, not the
|
|
996
|
+
* currency: see `USDX_CURRENCY` below.
|
|
997
|
+
*/
|
|
998
|
+
const USDX_SYMBOL = "USDX";
|
|
999
|
+
const SYNTHETIC_TEST_ASSET_SOURCE = "synthetic-test-liquidity";
|
|
985
1000
|
const USDX_ASSET = {
|
|
986
1001
|
assetId: assetIdFor(84532, USDX_ADDRESS_BASE_SEPOLIA),
|
|
987
1002
|
chainId: toChainId(84532),
|
|
988
|
-
symbol:
|
|
1003
|
+
symbol: USDX_SYMBOL,
|
|
989
1004
|
peg: toCurrencyCode("USD"),
|
|
990
1005
|
tokenAddress: USDX_ADDRESS_BASE_SEPOLIA,
|
|
991
|
-
deploymentStartBlock:
|
|
992
|
-
decimals: 6
|
|
1006
|
+
deploymentStartBlock: USDX_DEPLOYMENT_START_BLOCK,
|
|
1007
|
+
decimals: 6,
|
|
1008
|
+
source: "settlement"
|
|
993
1009
|
};
|
|
994
|
-
|
|
1010
|
+
/**
|
|
1011
|
+
* The settlement tier: rows the exact-transfer path and the Movement scanner
|
|
1012
|
+
* admit, each carrying the legacy `currency` projection those readers expect.
|
|
1013
|
+
* Adding an owned test asset here would put candidate liquidity on the
|
|
1014
|
+
* money-write path, so M03's rows go to the candidate tier below instead.
|
|
1015
|
+
*/
|
|
1016
|
+
const CONFIGURED_MONEY_ASSETS = [{
|
|
995
1017
|
...USDX_ASSET,
|
|
996
1018
|
currency: USDX_ASSET.peg
|
|
997
|
-
}]
|
|
1019
|
+
}];
|
|
1020
|
+
/**
|
|
1021
|
+
* The candidate tier: five owned test assets, every field read back from Base
|
|
1022
|
+
* Sepolia after the deployment that created it (chain 84532, blocks
|
|
1023
|
+
* 46,465,978–46,465,982). Real contracts, authored liquidity, no settlement
|
|
1024
|
+
* admission — so rollback is removing consumers, never relabelling a
|
|
1025
|
+
* deployed address or deleting its history.
|
|
1026
|
+
*
|
|
1027
|
+
* `symbol` is the display string the owned contract returns. A
|
|
1028
|
+
* provider-supported USDC would be a different contract at a different
|
|
1029
|
+
* address returning the same symbol, which is why the resolvers below key on
|
|
1030
|
+
* `assetId`, or on chain plus address, and never on a symbol.
|
|
1031
|
+
*/
|
|
1032
|
+
const SYNTHETIC_TEST_ASSETS = [
|
|
1033
|
+
{
|
|
1034
|
+
assetId: assetIdFor(84532, "0xb3d8566fb90f7df939f4bc08a09b19047117f549"),
|
|
1035
|
+
chainId: toChainId(84532),
|
|
1036
|
+
tokenAddress: "0xb3d8566fb90f7df939f4bc08a09b19047117f549",
|
|
1037
|
+
symbol: "USDC",
|
|
1038
|
+
decimals: 6,
|
|
1039
|
+
peg: toCurrencyCode("USD"),
|
|
1040
|
+
deploymentStartBlock: 46465978,
|
|
1041
|
+
deploymentTransaction: "0xa7fb8bb9d1fd1cc5fe2fc42fa4cdccace7742efae8ea99f091a283e5709343de",
|
|
1042
|
+
source: SYNTHETIC_TEST_ASSET_SOURCE
|
|
1043
|
+
},
|
|
1044
|
+
{
|
|
1045
|
+
assetId: assetIdFor(84532, "0x7ddcfb6aaffb9908c4c2db308b784c269eec8a01"),
|
|
1046
|
+
chainId: toChainId(84532),
|
|
1047
|
+
tokenAddress: "0x7ddcfb6aaffb9908c4c2db308b784c269eec8a01",
|
|
1048
|
+
symbol: "USDT",
|
|
1049
|
+
decimals: 6,
|
|
1050
|
+
peg: toCurrencyCode("USD"),
|
|
1051
|
+
deploymentStartBlock: 46465979,
|
|
1052
|
+
deploymentTransaction: "0xa17ad76fe8b24cdf1fbcff245c3eb022444710cf9fa7b5ee59818be654f4ae10",
|
|
1053
|
+
source: SYNTHETIC_TEST_ASSET_SOURCE
|
|
1054
|
+
},
|
|
1055
|
+
{
|
|
1056
|
+
assetId: assetIdFor(84532, "0x1d93d525f73453fe18eebf044e8a3954bfe3721e"),
|
|
1057
|
+
chainId: toChainId(84532),
|
|
1058
|
+
tokenAddress: "0x1d93d525f73453fe18eebf044e8a3954bfe3721e",
|
|
1059
|
+
symbol: "WETH",
|
|
1060
|
+
decimals: 18,
|
|
1061
|
+
peg: null,
|
|
1062
|
+
deploymentStartBlock: 46465980,
|
|
1063
|
+
deploymentTransaction: "0xcb9b2d024686fac93ec1243ccf02d3567fd531da46176115660cba2ba644b09d",
|
|
1064
|
+
source: SYNTHETIC_TEST_ASSET_SOURCE
|
|
1065
|
+
},
|
|
1066
|
+
{
|
|
1067
|
+
assetId: assetIdFor(84532, "0x8fe52c70aa9f7b6d74d8bb26eca33d87413cb624"),
|
|
1068
|
+
chainId: toChainId(84532),
|
|
1069
|
+
tokenAddress: "0x8fe52c70aa9f7b6d74d8bb26eca33d87413cb624",
|
|
1070
|
+
symbol: "WBTC",
|
|
1071
|
+
decimals: 8,
|
|
1072
|
+
peg: null,
|
|
1073
|
+
deploymentStartBlock: 46465981,
|
|
1074
|
+
deploymentTransaction: "0x728ba7b430ffd141f83d0ed5ce429d050049d7b097c936fd11e9c572d1243854",
|
|
1075
|
+
source: SYNTHETIC_TEST_ASSET_SOURCE
|
|
1076
|
+
},
|
|
1077
|
+
{
|
|
1078
|
+
assetId: assetIdFor(84532, "0x5865fe9787ac214feb5facaebaec06969ac0a9a3"),
|
|
1079
|
+
chainId: toChainId(84532),
|
|
1080
|
+
tokenAddress: "0x5865fe9787ac214feb5facaebaec06969ac0a9a3",
|
|
1081
|
+
symbol: "cNGN",
|
|
1082
|
+
decimals: 6,
|
|
1083
|
+
peg: toCurrencyCode("NGN"),
|
|
1084
|
+
deploymentStartBlock: 46465982,
|
|
1085
|
+
deploymentTransaction: "0xcedf254bcef57fc64189261a5ab1161bc4fde370e470933f627c4d8ddb5a2e26",
|
|
1086
|
+
source: SYNTHETIC_TEST_ASSET_SOURCE
|
|
1087
|
+
}
|
|
1088
|
+
];
|
|
1089
|
+
toChainId(84532);
|
|
1090
|
+
[...CONFIGURED_MONEY_ASSETS, ...SYNTHETIC_TEST_ASSETS];
|
|
1091
|
+
CONFIGURED_MONEY_ASSETS.map((asset) => asset.tokenAddress.toLowerCase());
|
|
998
1092
|
//#endregion
|
|
999
1093
|
//#region ../../node_modules/.pnpm/abitype@1.2.3_typescript@7.0.2_zod@4.4.3/node_modules/abitype/dist/esm/regex.js
|
|
1000
1094
|
function execTyped(regex, string) {
|
|
@@ -3738,6 +3832,12 @@ const USDX_BASE_SEPOLIA_TOKEN = {
|
|
|
3738
3832
|
USDX_BASE_SEPOLIA_TOKEN.chainId;
|
|
3739
3833
|
USDX_BASE_SEPOLIA_TOKEN.chainId;
|
|
3740
3834
|
10n ** BigInt(6);
|
|
3835
|
+
/**
|
|
3836
|
+
* The bootstrap manage role. It administers people and roles, cannot spend,
|
|
3837
|
+
* and is not a signer of the Organization Safe; "Owner" implied the latter,
|
|
3838
|
+
* so the label is Admin (ruled 2026-09-06).
|
|
3839
|
+
*/
|
|
3840
|
+
const ADMIN_ROLE_LABEL = "Admin";
|
|
3741
3841
|
function normalizeOrgRoleLabel(label) {
|
|
3742
3842
|
const normalized = label.trim().replace(/\s+/g, " ");
|
|
3743
3843
|
if (normalized.length === 0) throw Errors.invalidInput("role.label", "must be a non-empty role label");
|
|
@@ -6788,6 +6888,8 @@ const CAPXUL_OPERATIONS = {
|
|
|
6788
6888
|
emitAnnotationSaved: "activity.emitAnnotationSaved",
|
|
6789
6889
|
get: "activity.get",
|
|
6790
6890
|
list: "activity.list",
|
|
6891
|
+
/** The SDK's live Activity read over the indexer's SSE stream. */
|
|
6892
|
+
subscribe: "activity.subscribe",
|
|
6791
6893
|
summary: "activity.summary"
|
|
6792
6894
|
},
|
|
6793
6895
|
addressBook: {
|
|
@@ -7271,6 +7373,17 @@ const AuthFailedProps = Schema.Struct({
|
|
|
7271
7373
|
auth_type: OptionalString,
|
|
7272
7374
|
reason: OptionalString
|
|
7273
7375
|
});
|
|
7376
|
+
const IdentityRefusedProps = Schema.Struct({
|
|
7377
|
+
...TelemetryEnvelopeProps,
|
|
7378
|
+
/** The refused identity event tag, for example CreateOrganization. */
|
|
7379
|
+
event: OptionalString,
|
|
7380
|
+
/** The machine's refusal code: WRONG_STATE, SUPERSEDED or STALE_EPOCH. */
|
|
7381
|
+
refusal_code: OptionalString,
|
|
7382
|
+
/** The machine slot the request targeted, for example identity:org. */
|
|
7383
|
+
slot: OptionalString,
|
|
7384
|
+
/** The machine state at refusal, for example authenticated:claiming. */
|
|
7385
|
+
state: OptionalString
|
|
7386
|
+
});
|
|
7274
7387
|
const AuthSignedOutProps = Schema.Struct(TelemetryEnvelopeProps);
|
|
7275
7388
|
const ProvisioningSafeCreatedProps = Schema.Struct({
|
|
7276
7389
|
...TelemetryEnvelopeProps,
|
|
@@ -7658,10 +7771,24 @@ const DepositSettledProps = Schema.Struct({
|
|
|
7658
7771
|
});
|
|
7659
7772
|
const PermissionMirrorVerificationProps = Schema.Struct({
|
|
7660
7773
|
...TelemetryEnvelopeProps,
|
|
7774
|
+
/** The RECEIPT verification outcome. What the mirror then did is separate. */
|
|
7661
7775
|
outcome: Schema.String,
|
|
7662
7776
|
reason: Schema.String,
|
|
7663
7777
|
chain_id: Schema.Number,
|
|
7664
|
-
retry_count: Schema.Number
|
|
7778
|
+
retry_count: Schema.Number,
|
|
7779
|
+
/**
|
|
7780
|
+
* #1960 R02, consumed by R03. A verified receipt is not an applied Permission:
|
|
7781
|
+
* these two optional fields let the producer say what the applying mutation
|
|
7782
|
+
* actually returned, and which command it was, without either fact rewriting
|
|
7783
|
+
* the receipt outcome above. Absent when application has not happened yet.
|
|
7784
|
+
*/
|
|
7785
|
+
application_result: Schema.optional(Schema.Literals([
|
|
7786
|
+
"applied",
|
|
7787
|
+
"replayed",
|
|
7788
|
+
"conflicting_replay",
|
|
7789
|
+
"revision_mismatch"
|
|
7790
|
+
])),
|
|
7791
|
+
command_id: OptionalString
|
|
7665
7792
|
});
|
|
7666
7793
|
const MovementScanWindowProps = Schema.Struct({
|
|
7667
7794
|
...TelemetryEnvelopeProps,
|
|
@@ -7707,6 +7834,10 @@ Schema.Struct({
|
|
|
7707
7834
|
name: Schema.Literal("auth_failed"),
|
|
7708
7835
|
props: AuthFailedProps
|
|
7709
7836
|
});
|
|
7837
|
+
Schema.Struct({
|
|
7838
|
+
name: Schema.Literal("identity_refused"),
|
|
7839
|
+
props: IdentityRefusedProps
|
|
7840
|
+
});
|
|
7710
7841
|
Schema.Struct({
|
|
7711
7842
|
name: Schema.Literal("auth_signed_out"),
|
|
7712
7843
|
props: AuthSignedOutProps
|
|
@@ -7887,6 +8018,10 @@ Schema.Struct({
|
|
|
7887
8018
|
name: Schema.Literal("movement_scan_incident"),
|
|
7888
8019
|
props: MovementScanIncidentProps
|
|
7889
8020
|
});
|
|
8021
|
+
/** The one spelling of "whose scope did this happen in" across every surface. */
|
|
8022
|
+
const ScopeKindSchema = Schema.Literals(["account", "organization"]);
|
|
8023
|
+
const AccountKindSchema = Schema.Literals(["personalSafe", "orgTreasury"]);
|
|
8024
|
+
const OptionalReasonCode = Schema.optional(Schema.Literals(CAPXUL_ERROR_CODES));
|
|
7890
8025
|
const ActivityReferenceProps = {
|
|
7891
8026
|
reference_kind: Schema.Literals(["payment", "movement"]),
|
|
7892
8027
|
reference_id: Schema.String
|
|
@@ -7917,8 +8052,8 @@ const ActivityFilterProps = {
|
|
|
7917
8052
|
};
|
|
7918
8053
|
const ActivityActionProps = {
|
|
7919
8054
|
...TelemetryEnvelopeProps,
|
|
7920
|
-
scope_kind:
|
|
7921
|
-
reason_code:
|
|
8055
|
+
scope_kind: ScopeKindSchema,
|
|
8056
|
+
reason_code: OptionalReasonCode
|
|
7922
8057
|
};
|
|
7923
8058
|
Schema.Struct({
|
|
7924
8059
|
name: Schema.Literal("contact_relationship_changed"),
|
|
@@ -7930,7 +8065,7 @@ Schema.Struct({
|
|
|
7930
8065
|
"hidden",
|
|
7931
8066
|
"restored"
|
|
7932
8067
|
]),
|
|
7933
|
-
scope_kind:
|
|
8068
|
+
scope_kind: ScopeKindSchema,
|
|
7934
8069
|
scope_id: Schema.String,
|
|
7935
8070
|
owner_party_id: Schema.String,
|
|
7936
8071
|
party_id: Schema.String,
|
|
@@ -7946,9 +8081,9 @@ Schema.Struct({
|
|
|
7946
8081
|
});
|
|
7947
8082
|
const ContactActionProps = {
|
|
7948
8083
|
...TelemetryEnvelopeProps,
|
|
7949
|
-
scope_kind:
|
|
8084
|
+
scope_kind: ScopeKindSchema,
|
|
7950
8085
|
party_id: OptionalString,
|
|
7951
|
-
reason_code:
|
|
8086
|
+
reason_code: OptionalReasonCode
|
|
7952
8087
|
};
|
|
7953
8088
|
Schema.Struct({
|
|
7954
8089
|
name: Schema.Literal("ui_contact_action_completed"),
|
|
@@ -7975,7 +8110,7 @@ Schema.Struct({
|
|
|
7975
8110
|
props: Schema.Struct({
|
|
7976
8111
|
...TelemetryEnvelopeProps,
|
|
7977
8112
|
...ActivityReferenceProps,
|
|
7978
|
-
scope_kind:
|
|
8113
|
+
scope_kind: ScopeKindSchema,
|
|
7979
8114
|
scope_id: Schema.String,
|
|
7980
8115
|
occurred_at: Schema.Number
|
|
7981
8116
|
})
|
|
@@ -8030,6 +8165,193 @@ Schema.Struct({
|
|
|
8030
8165
|
})
|
|
8031
8166
|
])
|
|
8032
8167
|
});
|
|
8168
|
+
/**
|
|
8169
|
+
* Reliability closeout (#1960 R02) — the shape every explicit UI observation
|
|
8170
|
+
* below shares. `scope_kind` says whose surface the person was looking at,
|
|
8171
|
+
* `organization_id` is the verified Organization the producer resolved (absent
|
|
8172
|
+
* on a personal action), and `reason_code` is a catalog error code, never copy.
|
|
8173
|
+
*/
|
|
8174
|
+
const UiStepProps = {
|
|
8175
|
+
...TelemetryEnvelopeProps,
|
|
8176
|
+
scope_kind: ScopeKindSchema,
|
|
8177
|
+
organization_id: OptionalOrgId,
|
|
8178
|
+
reason_code: OptionalReasonCode
|
|
8179
|
+
};
|
|
8180
|
+
const AccessRecoveryCompletedProps = Schema.Union([Schema.Struct({
|
|
8181
|
+
...TelemetryEnvelopeProps,
|
|
8182
|
+
recovery: Schema.Literal("session_restoration"),
|
|
8183
|
+
outcome: Schema.Literals([
|
|
8184
|
+
"restored",
|
|
8185
|
+
"absent",
|
|
8186
|
+
"failed"
|
|
8187
|
+
]),
|
|
8188
|
+
reason_code: OptionalReasonCode,
|
|
8189
|
+
organization_id: OptionalOrgId
|
|
8190
|
+
}), Schema.Struct({
|
|
8191
|
+
...TelemetryEnvelopeProps,
|
|
8192
|
+
recovery: Schema.Literal("signer_readiness"),
|
|
8193
|
+
outcome: Schema.Literals(["ready", "unavailable"]),
|
|
8194
|
+
reason_code: OptionalReasonCode,
|
|
8195
|
+
organization_id: OptionalOrgId
|
|
8196
|
+
})]);
|
|
8197
|
+
Schema.Struct({
|
|
8198
|
+
name: Schema.Literal("access_recovery_completed"),
|
|
8199
|
+
props: AccessRecoveryCompletedProps
|
|
8200
|
+
});
|
|
8201
|
+
Schema.Struct({
|
|
8202
|
+
name: Schema.Literal("ui_access_step_completed"),
|
|
8203
|
+
props: Schema.Struct({
|
|
8204
|
+
...UiStepProps,
|
|
8205
|
+
step: Schema.Literals([
|
|
8206
|
+
"dashboard_granted",
|
|
8207
|
+
"redirect_completed",
|
|
8208
|
+
"gate_error_displayed",
|
|
8209
|
+
"retry_selected",
|
|
8210
|
+
"capability_refusal_displayed",
|
|
8211
|
+
"signer_refusal_displayed"
|
|
8212
|
+
]),
|
|
8213
|
+
capability: Schema.optional(Schema.Literals(["spend", "managePeople"])),
|
|
8214
|
+
probe: Schema.optional(Schema.Literals([
|
|
8215
|
+
"session",
|
|
8216
|
+
"membership",
|
|
8217
|
+
"lifecycle"
|
|
8218
|
+
])),
|
|
8219
|
+
reason: Schema.optional(Schema.Literals([
|
|
8220
|
+
"loading",
|
|
8221
|
+
"no-permission",
|
|
8222
|
+
"org-unavailable"
|
|
8223
|
+
]))
|
|
8224
|
+
})
|
|
8225
|
+
});
|
|
8226
|
+
Schema.Struct({
|
|
8227
|
+
name: Schema.Literal("org_invite_progressed"),
|
|
8228
|
+
props: Schema.Struct({
|
|
8229
|
+
...TelemetryEnvelopeProps,
|
|
8230
|
+
organization_id: OrgIdTelemetrySchema,
|
|
8231
|
+
progress: Schema.Literals([
|
|
8232
|
+
"account_ready",
|
|
8233
|
+
"permission_applied",
|
|
8234
|
+
"membership_activated",
|
|
8235
|
+
"revoked"
|
|
8236
|
+
]),
|
|
8237
|
+
/** The invited Party. The initiating actor stays on the envelope's identity. */
|
|
8238
|
+
member_party_id: Schema.String,
|
|
8239
|
+
occurred_at: Schema.Number
|
|
8240
|
+
})
|
|
8241
|
+
});
|
|
8242
|
+
Schema.Struct({
|
|
8243
|
+
name: Schema.Literal("invoice_issued"),
|
|
8244
|
+
props: Schema.Struct({
|
|
8245
|
+
...TelemetryEnvelopeProps,
|
|
8246
|
+
request_id: Schema.String,
|
|
8247
|
+
issuer_scope_kind: ScopeKindSchema,
|
|
8248
|
+
issuer_scope_id: Schema.String,
|
|
8249
|
+
payer_party_id: OptionalString,
|
|
8250
|
+
occurred_at: Schema.Number
|
|
8251
|
+
})
|
|
8252
|
+
});
|
|
8253
|
+
Schema.Struct({
|
|
8254
|
+
name: Schema.Literal("invoice_request_transitioned"),
|
|
8255
|
+
props: Schema.Struct({
|
|
8256
|
+
...TelemetryEnvelopeProps,
|
|
8257
|
+
request_id: Schema.String,
|
|
8258
|
+
transition: Schema.Literals([
|
|
8259
|
+
"approval_prepared",
|
|
8260
|
+
"declined",
|
|
8261
|
+
"cancelled"
|
|
8262
|
+
]),
|
|
8263
|
+
actor_scope_kind: ScopeKindSchema,
|
|
8264
|
+
actor_scope_id: Schema.String,
|
|
8265
|
+
occurred_at: Schema.Number
|
|
8266
|
+
})
|
|
8267
|
+
});
|
|
8268
|
+
Schema.Struct({
|
|
8269
|
+
name: Schema.Literal("ui_invoice_step_completed"),
|
|
8270
|
+
props: Schema.Struct({
|
|
8271
|
+
...UiStepProps,
|
|
8272
|
+
step: Schema.Literals([
|
|
8273
|
+
"opened",
|
|
8274
|
+
"previewed",
|
|
8275
|
+
"dismissed",
|
|
8276
|
+
"submitted",
|
|
8277
|
+
"result_displayed",
|
|
8278
|
+
"refusal_displayed",
|
|
8279
|
+
"retry_selected"
|
|
8280
|
+
]),
|
|
8281
|
+
request_id: OptionalString
|
|
8282
|
+
})
|
|
8283
|
+
});
|
|
8284
|
+
Schema.Struct({
|
|
8285
|
+
name: Schema.Literal("ui_treasury_step_completed"),
|
|
8286
|
+
props: Schema.Struct({
|
|
8287
|
+
...UiStepProps,
|
|
8288
|
+
step: Schema.Literals([
|
|
8289
|
+
"balance_displayed",
|
|
8290
|
+
"read_refusal_displayed",
|
|
8291
|
+
"retry_selected",
|
|
8292
|
+
"recovery_completed"
|
|
8293
|
+
]),
|
|
8294
|
+
account_kind: Schema.optional(AccountKindSchema)
|
|
8295
|
+
})
|
|
8296
|
+
});
|
|
8297
|
+
Schema.Struct({
|
|
8298
|
+
name: Schema.Literal("ui_receive_step_completed"),
|
|
8299
|
+
props: Schema.Struct({
|
|
8300
|
+
...UiStepProps,
|
|
8301
|
+
step: Schema.Literals([
|
|
8302
|
+
"instructions_displayed",
|
|
8303
|
+
"address_copied",
|
|
8304
|
+
"copy_failed",
|
|
8305
|
+
"refusal_displayed",
|
|
8306
|
+
"retry_selected"
|
|
8307
|
+
]),
|
|
8308
|
+
account_kind: Schema.optional(AccountKindSchema)
|
|
8309
|
+
})
|
|
8310
|
+
});
|
|
8311
|
+
Schema.Struct({
|
|
8312
|
+
name: Schema.Literal("payroll_group_changed"),
|
|
8313
|
+
props: Schema.Struct({
|
|
8314
|
+
...TelemetryEnvelopeProps,
|
|
8315
|
+
organization_id: OrgIdTelemetrySchema,
|
|
8316
|
+
change: Schema.Literals([
|
|
8317
|
+
"created",
|
|
8318
|
+
"updated",
|
|
8319
|
+
"deleted"
|
|
8320
|
+
]),
|
|
8321
|
+
group_id: Schema.String,
|
|
8322
|
+
member_count: Schema.Number,
|
|
8323
|
+
occurred_at: Schema.Number
|
|
8324
|
+
})
|
|
8325
|
+
});
|
|
8326
|
+
Schema.Struct({
|
|
8327
|
+
name: Schema.Literal("payroll_run_transitioned"),
|
|
8328
|
+
props: Schema.Struct({
|
|
8329
|
+
...TelemetryEnvelopeProps,
|
|
8330
|
+
organization_id: OrgIdTelemetrySchema,
|
|
8331
|
+
transition: Schema.Literals([
|
|
8332
|
+
"prepared",
|
|
8333
|
+
"authorized",
|
|
8334
|
+
"settled"
|
|
8335
|
+
]),
|
|
8336
|
+
run_id: Schema.String,
|
|
8337
|
+
payment_count: Schema.optional(Schema.Number),
|
|
8338
|
+
occurred_at: Schema.Number
|
|
8339
|
+
})
|
|
8340
|
+
});
|
|
8341
|
+
Schema.Struct({
|
|
8342
|
+
name: Schema.Literal("ui_payroll_action_completed"),
|
|
8343
|
+
props: Schema.Struct({
|
|
8344
|
+
...UiStepProps,
|
|
8345
|
+
action: Schema.Literals([
|
|
8346
|
+
"opened",
|
|
8347
|
+
"refusal_displayed",
|
|
8348
|
+
"recovery_completed",
|
|
8349
|
+
"cancelled",
|
|
8350
|
+
"submitted_displayed"
|
|
8351
|
+
]),
|
|
8352
|
+
run_id: OptionalString
|
|
8353
|
+
})
|
|
8354
|
+
});
|
|
8033
8355
|
function redactTelemetryProps(name, props, options = {}) {
|
|
8034
8356
|
if (props === void 0) return void 0;
|
|
8035
8357
|
const clone = cloneProps$1(props);
|
|
@@ -8325,6 +8647,10 @@ const BootstrapEnvelope = Schema.Struct({
|
|
|
8325
8647
|
siteBaseUrl: Schema.String,
|
|
8326
8648
|
openfortPublishableKey: Schema.String,
|
|
8327
8649
|
shieldPublishableKey: Schema.String,
|
|
8650
|
+
/** Which Openfort third-party auth provider the signer presents; absent means better-auth. */
|
|
8651
|
+
openfortAuthProvider: Schema.optional(Schema.Literals(["better-auth", "oidc"])),
|
|
8652
|
+
/** Origin of the Ponder indexer the SDK reads directly; absent means no indexer reads. */
|
|
8653
|
+
indexerUrl: Schema.optional(Schema.String),
|
|
8328
8654
|
engineeringTelemetry: Schema.optional(EngineeringTelemetryBootstrapPolicy)
|
|
8329
8655
|
})
|
|
8330
8656
|
});
|
|
@@ -8399,6 +8725,7 @@ const CAPXUL_FUNCTIONS = {
|
|
|
8399
8725
|
prepareOrganizationPaymentExecution: "moneyExecution/paymentCommandActions:prepareOrganizationPaymentExecution",
|
|
8400
8726
|
submitPaymentCommandExecution: "moneyExecution/paymentCommandActions:submitPaymentCommandExecution"
|
|
8401
8727
|
},
|
|
8728
|
+
"moneyExecution/providerSendWitness": { read: "moneyExecution/providerSendWitness:read" },
|
|
8402
8729
|
media: {
|
|
8403
8730
|
generateUploadUrl: "media:generateUploadUrl",
|
|
8404
8731
|
setOrgLogo: "media:setOrgLogo",
|
|
@@ -8458,6 +8785,11 @@ const CAPXUL_FUNCTIONS = {
|
|
|
8458
8785
|
loadByAuthUserId: "smartAccount/queries:loadByAuthUserId",
|
|
8459
8786
|
loadBySmartAccountAddress: "smartAccount/queries:loadBySmartAccountAddress"
|
|
8460
8787
|
},
|
|
8788
|
+
e2eControls: {
|
|
8789
|
+
holdUserOperationReceipt: "e2eControls:holdUserOperationReceipt",
|
|
8790
|
+
isUserOperationReceiptHeld: "e2eControls:isUserOperationReceiptHeld",
|
|
8791
|
+
releaseUserOperationReceipt: "e2eControls:releaseUserOperationReceipt"
|
|
8792
|
+
},
|
|
8461
8793
|
system: { health: "system:health" }
|
|
8462
8794
|
};
|
|
8463
8795
|
//#endregion
|
|
@@ -12046,7 +12378,7 @@ const moneyExecutionContract = {
|
|
|
12046
12378
|
};
|
|
12047
12379
|
//#endregion
|
|
12048
12380
|
//#region ../../packages/sdk/package.json
|
|
12049
|
-
var version$1 = "4.2.0-rc.
|
|
12381
|
+
var version$1 = "4.2.0-rc.10";
|
|
12050
12382
|
//#endregion
|
|
12051
12383
|
//#region ../../packages/sdk/src/telemetry/exception-projection.ts
|
|
12052
12384
|
/** Fixed fallback for failures that have no safe message. */
|
|
@@ -12143,6 +12475,17 @@ function observeFailedResult(result, adapter, operation, origin) {
|
|
|
12143
12475
|
return result;
|
|
12144
12476
|
}
|
|
12145
12477
|
/**
|
|
12478
|
+
* @internal Reports a failure that can never become a method result.
|
|
12479
|
+
*
|
|
12480
|
+
* A reactive stream is torn down after its call already returned, so nothing
|
|
12481
|
+
* downstream observes it. `captureException` is the right kind: the caller did
|
|
12482
|
+
* not ask for the end, so it is not an expected product outcome.
|
|
12483
|
+
*/
|
|
12484
|
+
function observeStreamFailure(adapter, operation, cause) {
|
|
12485
|
+
if (adapter === void 0) return;
|
|
12486
|
+
report(adapter, "exception", operation, cause, resolveAdapterSnapshot(adapter));
|
|
12487
|
+
}
|
|
12488
|
+
/**
|
|
12146
12489
|
* One failure, one event. The identity machine reports a failed transition
|
|
12147
12490
|
* first; when the same `CapxulError` then surfaces as a public method result
|
|
12148
12491
|
* (directly or down its `cause` chain), the boundary drops that second report.
|
|
@@ -12219,6 +12562,34 @@ function ignoreDeliveryFailure(delivery) {
|
|
|
12219
12562
|
Promise.resolve(delivery).catch(() => void 0);
|
|
12220
12563
|
} catch {}
|
|
12221
12564
|
}
|
|
12565
|
+
/**
|
|
12566
|
+
* Fold a caller-captured attempt identity into the host's resolved context.
|
|
12567
|
+
*
|
|
12568
|
+
* The host's `resolveContext` runs at the moment an SDK method is entered, so a
|
|
12569
|
+
* host that mints a correlation per resolve gives every operation of one user
|
|
12570
|
+
* attempt a different identity — and a user or Organization switch between the
|
|
12571
|
+
* click and the reply relabels an action that already started. When the caller
|
|
12572
|
+
* captured `correlation_id`/`journey_id` BEFORE the action started, that is the
|
|
12573
|
+
* attempt, and it replaces what the resolver returned for this one call. The
|
|
12574
|
+
* result is what the SDK span/Log, the failure envelope and the backend carrier
|
|
12575
|
+
* all read, so the three agree by construction rather than by convention.
|
|
12576
|
+
*
|
|
12577
|
+
* A caller that captured nothing gets the resolver's context unchanged, so
|
|
12578
|
+
* automatic reads keep their own invocation context.
|
|
12579
|
+
*/
|
|
12580
|
+
function withCapturedAttemptContext(context, controls) {
|
|
12581
|
+
const correlationId = controls?.correlation_id;
|
|
12582
|
+
const journeyId = controls?.journey_id;
|
|
12583
|
+
if (correlationId === void 0 && journeyId === void 0) return context;
|
|
12584
|
+
const captured = sanitizeObservationContext({
|
|
12585
|
+
...correlationId === void 0 ? {} : { correlationId },
|
|
12586
|
+
...journeyId === void 0 ? {} : { journeyId }
|
|
12587
|
+
});
|
|
12588
|
+
return captured === void 0 ? context : {
|
|
12589
|
+
...context,
|
|
12590
|
+
...captured
|
|
12591
|
+
};
|
|
12592
|
+
}
|
|
12222
12593
|
const MAX_EVIDENCE_TEXT = 4e3;
|
|
12223
12594
|
const MAX_CAUSE_DEPTH = 8;
|
|
12224
12595
|
function evidenceText(value) {
|
|
@@ -14445,7 +14816,8 @@ var BetterAuthBrowserAdapter = class {
|
|
|
14445
14816
|
try {
|
|
14446
14817
|
const res = await this.fetchImpl(this.url("/api/auth/get-session"), withSignal$1({
|
|
14447
14818
|
method: "GET",
|
|
14448
|
-
credentials: "include"
|
|
14819
|
+
credentials: "include",
|
|
14820
|
+
cache: "no-store"
|
|
14449
14821
|
}, options?.signal));
|
|
14450
14822
|
if (options?.signal?.aborted) return {
|
|
14451
14823
|
ok: false,
|
|
@@ -14517,7 +14889,8 @@ var BetterAuthBrowserAdapter = class {
|
|
|
14517
14889
|
try {
|
|
14518
14890
|
const res = await this.fetchImpl(this.url("/api/auth/convex/token"), withSignal$1({
|
|
14519
14891
|
method: "GET",
|
|
14520
|
-
credentials: "include"
|
|
14892
|
+
credentials: "include",
|
|
14893
|
+
cache: "no-store"
|
|
14521
14894
|
}, options?.signal));
|
|
14522
14895
|
if (options?.signal?.aborted) return {
|
|
14523
14896
|
ok: false,
|
|
@@ -15030,7 +15403,7 @@ function isTransientBootstrapFailure(error) {
|
|
|
15030
15403
|
const status = error.details?.httpStatus;
|
|
15031
15404
|
return typeof status === "number" && isTransientHttpStatus(status);
|
|
15032
15405
|
}
|
|
15033
|
-
async function safeText(res) {
|
|
15406
|
+
async function safeText$1(res) {
|
|
15034
15407
|
try {
|
|
15035
15408
|
return await res.text();
|
|
15036
15409
|
} catch {
|
|
@@ -15103,6 +15476,8 @@ var HttpBootstrapAdapter = class {
|
|
|
15103
15476
|
siteBaseUrl: normalizeRuntimeUrl("siteBaseUrl", decodedState.siteBaseUrl),
|
|
15104
15477
|
openfortPublishableKey: decodedState.openfortPublishableKey,
|
|
15105
15478
|
shieldPublishableKey: decodedState.shieldPublishableKey,
|
|
15479
|
+
...decodedState.openfortAuthProvider === void 0 ? {} : { openfortAuthProvider: decodedState.openfortAuthProvider },
|
|
15480
|
+
...decodedState.indexerUrl === void 0 ? {} : { indexerUrl: decodedState.indexerUrl },
|
|
15106
15481
|
...decodedEngineeringTelemetry !== void 0 && Result.isSuccess(decodedEngineeringTelemetry) ? { engineeringTelemetry: decodedEngineeringTelemetry.success } : {}
|
|
15107
15482
|
};
|
|
15108
15483
|
},
|
|
@@ -15111,7 +15486,7 @@ var HttpBootstrapAdapter = class {
|
|
|
15111
15486
|
return bootstrapErrorFromCapxul("malformedBody", Errors.providerError("convex", "bootstrap", cause instanceof Error ? cause : new Error(String(cause))));
|
|
15112
15487
|
}
|
|
15113
15488
|
});
|
|
15114
|
-
return Effect.promise(() => safeText(res)).pipe(Effect.flatMap((body) => {
|
|
15489
|
+
return Effect.promise(() => safeText$1(res)).pipe(Effect.flatMap((body) => {
|
|
15115
15490
|
if (res.status === 401 || body.startsWith("NOT_AUTHENTICATED")) return Effect.fail(bootstrapErrorFromCapxul("notAuthenticated", Errors.notAuthenticated()));
|
|
15116
15491
|
if (res.status === 400 || body.startsWith("INVALID_INPUT")) return Effect.fail(bootstrapErrorFromCapxul("invalidInput", Errors.invalidInput("publishableKey", "rejected by bootstrap")));
|
|
15117
15492
|
const responseBody = body.slice(0, 300);
|
|
@@ -18294,6 +18669,12 @@ function makeConnectionId() {
|
|
|
18294
18669
|
}
|
|
18295
18670
|
//#endregion
|
|
18296
18671
|
//#region ../../packages/sdk/src/adapters/convex-call/ConvexCallAdapter.ts
|
|
18672
|
+
/**
|
|
18673
|
+
* A socket that has not emitted `close` within this window is not going to.
|
|
18674
|
+
* ponytail: one fixed bound; `closeTimeoutMs` is the knob if a slow runtime
|
|
18675
|
+
* ever needs a different one.
|
|
18676
|
+
*/
|
|
18677
|
+
const DEFAULT_CLOSE_TIMEOUT_MS = 5e3;
|
|
18297
18678
|
/** Exact floor-first allowlist; every additional handler must migrate its validator first. */
|
|
18298
18679
|
const OBSERVED_CONVEX_ACTIONS = /* @__PURE__ */ new Set([
|
|
18299
18680
|
"payroll/actions:authorizeRun",
|
|
@@ -18362,7 +18743,9 @@ var ConvexCallAdapter = class {
|
|
|
18362
18743
|
#applicationId;
|
|
18363
18744
|
#observation;
|
|
18364
18745
|
#connectionMonitor;
|
|
18746
|
+
#closeTimeoutMs;
|
|
18365
18747
|
constructor(deps) {
|
|
18748
|
+
this.#closeTimeoutMs = deps.closeTimeoutMs ?? DEFAULT_CLOSE_TIMEOUT_MS;
|
|
18366
18749
|
this.#connectionMonitor = new ConvexConnectionMonitor();
|
|
18367
18750
|
const webSocketConstructor = this.#connectionMonitor.observedWebSocketConstructor();
|
|
18368
18751
|
this.#client = deps.client ?? new ConvexClient(deps.convexUrl, webSocketConstructor === void 0 ? {} : { webSocketConstructor });
|
|
@@ -18461,11 +18844,33 @@ var ConvexCallAdapter = class {
|
|
|
18461
18844
|
callback({ status: "loading" });
|
|
18462
18845
|
})));
|
|
18463
18846
|
}
|
|
18847
|
+
/**
|
|
18848
|
+
* Teardown always completes. `ConvexClient.close()` resolves only when the
|
|
18849
|
+
* socket emits `close`, and `WebSocketManager.close()` in the `connecting`
|
|
18850
|
+
* state arms `ws.onopen = () => ws.close()` without ever closing the socket
|
|
18851
|
+
* itself — so a handshake that stalls right after a server-initiated close
|
|
18852
|
+
* (code 1012, which is what a Convex deploy sends) leaves that promise
|
|
18853
|
+
* pending for as long as the page lives. Convex marks the client closed and
|
|
18854
|
+
* terminates the socket manager synchronously before returning it, so
|
|
18855
|
+
* abandoning it drops nothing. A rejection is dropped for the same reason —
|
|
18856
|
+
* the layer release turns it into a defect that fails the whole scope close,
|
|
18857
|
+
* and teardown has no caller who can act on it.
|
|
18858
|
+
*/
|
|
18464
18859
|
async close() {
|
|
18465
18860
|
this.#connectionMonitor.close();
|
|
18466
|
-
await this.#client.close();
|
|
18861
|
+
await settledWithin(this.#client.close(), this.#closeTimeoutMs);
|
|
18467
18862
|
}
|
|
18468
18863
|
};
|
|
18864
|
+
function settledWithin(promise, timeoutMs) {
|
|
18865
|
+
return new Promise((resolve) => {
|
|
18866
|
+
const timer = setTimeout(resolve, timeoutMs);
|
|
18867
|
+
const finish = () => {
|
|
18868
|
+
clearTimeout(timer);
|
|
18869
|
+
resolve();
|
|
18870
|
+
};
|
|
18871
|
+
promise.then(finish, finish);
|
|
18872
|
+
});
|
|
18873
|
+
}
|
|
18469
18874
|
function ConvexCallLayer(deps) {
|
|
18470
18875
|
return Layer.effect(ConvexCallPortTag, Effect.acquireRelease(Effect.sync(() => new ConvexCallAdapter(deps)), (adapter) => Effect.promise(() => adapter.close()).pipe(Effect.orDie)));
|
|
18471
18876
|
}
|
|
@@ -19418,6 +19823,32 @@ var ConsoleDiagnosticAdapter = class {
|
|
|
19418
19823
|
}
|
|
19419
19824
|
};
|
|
19420
19825
|
//#endregion
|
|
19826
|
+
//#region ../../packages/sdk/src/adapters/diagnostic/EffectLogDiagnosticAdapter.ts
|
|
19827
|
+
/**
|
|
19828
|
+
* Diagnostic breadcrumbs as SDK log records. The signer's readiness cycle
|
|
19829
|
+
* traces (`openfort.*`) used to reach only the browser console; through this
|
|
19830
|
+
* adapter they run in the client's own Effect context, so the engineering
|
|
19831
|
+
* telemetry layer ships them to PostHog Logs beside `identity.transition`.
|
|
19832
|
+
* Logging never throws back into the cycle that emitted it.
|
|
19833
|
+
*/
|
|
19834
|
+
var EffectLogDiagnosticAdapter = class {
|
|
19835
|
+
#runPromise;
|
|
19836
|
+
#console;
|
|
19837
|
+
constructor(context, consoleFallback) {
|
|
19838
|
+
this.#runPromise = Effect.runPromiseWith(context);
|
|
19839
|
+
this.#console = consoleFallback;
|
|
19840
|
+
}
|
|
19841
|
+
trace(scope, detail) {
|
|
19842
|
+
this.#console?.trace(scope, detail);
|
|
19843
|
+
try {
|
|
19844
|
+
this.#runPromise(Effect.logInfo(scope).pipe(Effect.annotateLogs({
|
|
19845
|
+
...detail,
|
|
19846
|
+
diagnostic_scope: scope
|
|
19847
|
+
}), Effect.catchCause(() => Effect.void))).catch(() => void 0);
|
|
19848
|
+
} catch {}
|
|
19849
|
+
}
|
|
19850
|
+
};
|
|
19851
|
+
//#endregion
|
|
19421
19852
|
//#region ../../node_modules/.pnpm/axios@1.17.0/node_modules/axios/lib/helpers/bind.js
|
|
19422
19853
|
/**
|
|
19423
19854
|
* Create a bound version of a function with a specified `this` context
|
|
@@ -42496,15 +42927,35 @@ function createOpenfortBrowserSignerFromBootstrap(bootstrap, options = {}) {
|
|
|
42496
42927
|
});
|
|
42497
42928
|
throw failOpenfort("configure", "no-secure-context", /* @__PURE__ */ new Error("Web Crypto unavailable: browser is not a secure context"));
|
|
42498
42929
|
}
|
|
42499
|
-
|
|
42500
|
-
|
|
42930
|
+
const authProvider = bootstrap.openfortAuthProvider ?? "better-auth";
|
|
42931
|
+
function accessTokenUrl() {
|
|
42932
|
+
return authProvider === "oidc" ? `${authBaseUrl}/convex/token` : `${authBaseUrl}/get-session`;
|
|
42501
42933
|
}
|
|
42502
42934
|
function encryptionSessionUrl() {
|
|
42503
42935
|
return `${authBaseUrl}/encryption-session`;
|
|
42504
42936
|
}
|
|
42937
|
+
let cycleStartedAt = null;
|
|
42938
|
+
let stepStartedAt = 0;
|
|
42939
|
+
let tokenCalls = 0;
|
|
42940
|
+
const sinceCycleStart = () => cycleStartedAt === null ? void 0 : Date.now() - cycleStartedAt;
|
|
42941
|
+
const step = (name, extra = {}) => {
|
|
42942
|
+
const now = Date.now();
|
|
42943
|
+
diagnostic?.trace("openfort.step", {
|
|
42944
|
+
step: name,
|
|
42945
|
+
duration_ms: now - stepStartedAt,
|
|
42946
|
+
elapsed_ms: sinceCycleStart(),
|
|
42947
|
+
...extra
|
|
42948
|
+
});
|
|
42949
|
+
stepStartedAt = now;
|
|
42950
|
+
};
|
|
42505
42951
|
async function fetchBetterAuthAccessToken() {
|
|
42952
|
+
tokenCalls += 1;
|
|
42953
|
+
const tokenStartedAt = Date.now();
|
|
42506
42954
|
try {
|
|
42507
|
-
const response = await fetch(
|
|
42955
|
+
const response = await fetch(accessTokenUrl(), {
|
|
42956
|
+
credentials: "include",
|
|
42957
|
+
cache: "no-store"
|
|
42958
|
+
});
|
|
42508
42959
|
if (!response.ok) {
|
|
42509
42960
|
diagnostic?.trace("openfort.token", {
|
|
42510
42961
|
ok: false,
|
|
@@ -42514,7 +42965,8 @@ function createOpenfortBrowserSignerFromBootstrap(bootstrap, options = {}) {
|
|
|
42514
42965
|
});
|
|
42515
42966
|
return null;
|
|
42516
42967
|
}
|
|
42517
|
-
const
|
|
42968
|
+
const body = await response.json();
|
|
42969
|
+
const token = (authProvider === "oidc" ? body.token : body.session?.token)?.trim();
|
|
42518
42970
|
if (token === void 0 || token.length === 0) {
|
|
42519
42971
|
diagnostic?.trace("openfort.token", {
|
|
42520
42972
|
ok: false,
|
|
@@ -42525,7 +42977,11 @@ function createOpenfortBrowserSignerFromBootstrap(bootstrap, options = {}) {
|
|
|
42525
42977
|
}
|
|
42526
42978
|
diagnostic?.trace("openfort.token", {
|
|
42527
42979
|
ok: true,
|
|
42528
|
-
tokenPresent: true
|
|
42980
|
+
tokenPresent: true,
|
|
42981
|
+
provider: authProvider,
|
|
42982
|
+
call: tokenCalls,
|
|
42983
|
+
duration_ms: Date.now() - tokenStartedAt,
|
|
42984
|
+
elapsed_ms: sinceCycleStart()
|
|
42529
42985
|
});
|
|
42530
42986
|
return token;
|
|
42531
42987
|
} catch (cause) {
|
|
@@ -42541,7 +42997,7 @@ function createOpenfortBrowserSignerFromBootstrap(bootstrap, options = {}) {
|
|
|
42541
42997
|
baseConfiguration: { publishableKey: bootstrap.openfortPublishableKey },
|
|
42542
42998
|
shieldConfiguration: { shieldPublishableKey: bootstrap.shieldPublishableKey },
|
|
42543
42999
|
thirdPartyAuth: {
|
|
42544
|
-
provider: o$13.BETTER_AUTH,
|
|
43000
|
+
provider: authProvider === "oidc" ? o$13.OIDC : o$13.BETTER_AUTH,
|
|
42545
43001
|
getAccessToken: fetchBetterAuthAccessToken
|
|
42546
43002
|
}
|
|
42547
43003
|
});
|
|
@@ -42581,10 +43037,16 @@ function createOpenfortBrowserSignerFromBootstrap(bootstrap, options = {}) {
|
|
|
42581
43037
|
let walletReadyPromise = null;
|
|
42582
43038
|
function startWalletReady() {
|
|
42583
43039
|
return (async () => {
|
|
43040
|
+
const startedAt = Date.now();
|
|
43041
|
+
cycleStartedAt = startedAt;
|
|
43042
|
+
stepStartedAt = startedAt;
|
|
43043
|
+
tokenCalls = 0;
|
|
42584
43044
|
if (isInsecureBrowserContext()) failNoSecureContext();
|
|
42585
43045
|
await openfort.waitForInitialization();
|
|
43046
|
+
step("initialize");
|
|
42586
43047
|
const accessToken = await fetchBetterAuthAccessToken();
|
|
42587
43048
|
if (accessToken === null) throw openfortProviderError("token", /* @__PURE__ */ new Error("Better Auth access token unavailable for Openfort"));
|
|
43049
|
+
step("token");
|
|
42588
43050
|
let encryptionResponse;
|
|
42589
43051
|
try {
|
|
42590
43052
|
encryptionResponse = await fetch(encryptionSessionUrl(), {
|
|
@@ -42627,10 +43089,12 @@ function createOpenfortBrowserSignerFromBootstrap(bootstrap, options = {}) {
|
|
|
42627
43089
|
ok: true,
|
|
42628
43090
|
httpStatus: encryptionResponse.status
|
|
42629
43091
|
});
|
|
43092
|
+
step("encryptionSession", { httpStatus: encryptionResponse.status });
|
|
42630
43093
|
let embeddedState;
|
|
42631
43094
|
try {
|
|
42632
43095
|
embeddedState = await openfort.embeddedWallet.getEmbeddedState();
|
|
42633
43096
|
diagnostic?.trace("openfort.embeddedState", { state: embeddedState });
|
|
43097
|
+
step("embeddedState", { state: embeddedState });
|
|
42634
43098
|
} catch (cause) {
|
|
42635
43099
|
diagnostic?.trace("openfort.embeddedState", {
|
|
42636
43100
|
ok: false,
|
|
@@ -42644,6 +43108,7 @@ function createOpenfortBrowserSignerFromBootstrap(bootstrap, options = {}) {
|
|
|
42644
43108
|
try {
|
|
42645
43109
|
await configureEmbeddedWallet(encryptionBody.sessionId);
|
|
42646
43110
|
diagnostic?.trace("openfort.configure", { ok: true });
|
|
43111
|
+
step("configure");
|
|
42647
43112
|
} catch (cause) {
|
|
42648
43113
|
const error = openfortProviderError("configure", cause);
|
|
42649
43114
|
diagnostic?.trace("openfort.configure", {
|
|
@@ -42656,6 +43121,7 @@ function createOpenfortBrowserSignerFromBootstrap(bootstrap, options = {}) {
|
|
|
42656
43121
|
try {
|
|
42657
43122
|
await openfort.embeddedWallet.get();
|
|
42658
43123
|
diagnostic?.trace("openfort.get", { ok: true });
|
|
43124
|
+
step("get");
|
|
42659
43125
|
} catch (cause) {
|
|
42660
43126
|
if (!isStaleUserSignal(cause)) {
|
|
42661
43127
|
diagnostic?.trace("openfort.get", {
|
|
@@ -42669,7 +43135,13 @@ function createOpenfortBrowserSignerFromBootstrap(bootstrap, options = {}) {
|
|
|
42669
43135
|
failure_mode: "stale-openfort-cache"
|
|
42670
43136
|
});
|
|
42671
43137
|
await healStaleOpenfortCache(encryptionBody.sessionId);
|
|
43138
|
+
step("healStaleCache");
|
|
42672
43139
|
}
|
|
43140
|
+
step("walletReady", {
|
|
43141
|
+
ok: true,
|
|
43142
|
+
total_ms: Date.now() - startedAt,
|
|
43143
|
+
token_calls: tokenCalls
|
|
43144
|
+
});
|
|
42673
43145
|
})();
|
|
42674
43146
|
}
|
|
42675
43147
|
async function ensureOpenfortWalletReady() {
|
|
@@ -42752,9 +43224,13 @@ function createOpenfortBrowserSignerFromBootstrap(bootstrap, options = {}) {
|
|
|
42752
43224
|
statusStore,
|
|
42753
43225
|
ensureWalletReady: ensureOpenfortWalletReady,
|
|
42754
43226
|
getAddress: async () => {
|
|
43227
|
+
const addressStartedAt = Date.now();
|
|
42755
43228
|
try {
|
|
42756
43229
|
const address = await signer.getAddress();
|
|
42757
|
-
diagnostic?.trace("openfort.address", {
|
|
43230
|
+
diagnostic?.trace("openfort.address", {
|
|
43231
|
+
ok: true,
|
|
43232
|
+
duration_ms: Date.now() - addressStartedAt
|
|
43233
|
+
});
|
|
42758
43234
|
return address;
|
|
42759
43235
|
} catch (cause) {
|
|
42760
43236
|
diagnostic?.trace("openfort.address", {
|
|
@@ -43856,14 +44332,66 @@ function organizationWrongState(currentState, validStates) {
|
|
|
43856
44332
|
function requestCancelled(options) {
|
|
43857
44333
|
return options?.signal?.aborted === true;
|
|
43858
44334
|
}
|
|
44335
|
+
function accountInFlight(state) {
|
|
44336
|
+
return state.phase === "authenticated" && (state.account.at === "deriving" || state.account.at === "claiming");
|
|
44337
|
+
}
|
|
44338
|
+
function settledAccount(deps, options) {
|
|
44339
|
+
return new Promise((resolve) => {
|
|
44340
|
+
let done = false;
|
|
44341
|
+
let unsubscribe = null;
|
|
44342
|
+
const onAbort = () => finish({
|
|
44343
|
+
ok: false,
|
|
44344
|
+
error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.onboarding.completeOrganization })
|
|
44345
|
+
});
|
|
44346
|
+
const finish = (result) => {
|
|
44347
|
+
if (done) return;
|
|
44348
|
+
done = true;
|
|
44349
|
+
unsubscribe?.();
|
|
44350
|
+
options?.signal?.removeEventListener("abort", onAbort);
|
|
44351
|
+
resolve(result);
|
|
44352
|
+
};
|
|
44353
|
+
if (options?.signal?.aborted) {
|
|
44354
|
+
onAbort();
|
|
44355
|
+
return;
|
|
44356
|
+
}
|
|
44357
|
+
options?.signal?.addEventListener("abort", onAbort, { once: true });
|
|
44358
|
+
const stop = deps.subscribeIdentity((state) => {
|
|
44359
|
+
if (!accountInFlight(state)) finish({
|
|
44360
|
+
ok: true,
|
|
44361
|
+
value: state
|
|
44362
|
+
});
|
|
44363
|
+
});
|
|
44364
|
+
if (done) {
|
|
44365
|
+
stop();
|
|
44366
|
+
return;
|
|
44367
|
+
}
|
|
44368
|
+
unsubscribe = stop;
|
|
44369
|
+
const current = deps.snapshotIdentity();
|
|
44370
|
+
if (!accountInFlight(current)) finish({
|
|
44371
|
+
ok: true,
|
|
44372
|
+
value: current
|
|
44373
|
+
});
|
|
44374
|
+
});
|
|
44375
|
+
}
|
|
43859
44376
|
async function reachClaimedAccount(deps, options) {
|
|
43860
44377
|
let state = deps.snapshotIdentity();
|
|
44378
|
+
if (accountInFlight(state)) {
|
|
44379
|
+
const settled = await settledAccount(deps, options);
|
|
44380
|
+
if (!settled.ok) return settled;
|
|
44381
|
+
state = settled.value;
|
|
44382
|
+
}
|
|
43861
44383
|
if (state.phase !== "authenticated" || state.account.at === "unknown") {
|
|
43862
44384
|
const ensured = await deps.sendIdentity({ _tag: "EnsureAccount" }, options);
|
|
43863
44385
|
if (!ensured.ok) return ensured;
|
|
43864
44386
|
state = ensured.value;
|
|
43865
44387
|
}
|
|
43866
44388
|
if (state.phase !== "authenticated") return organizationWrongState(state.phase, ["authenticated:claimed"]);
|
|
44389
|
+
if (accountInFlight(state)) {
|
|
44390
|
+
const settled = await settledAccount(deps, options);
|
|
44391
|
+
if (!settled.ok) return settled;
|
|
44392
|
+
state = settled.value;
|
|
44393
|
+
if (state.phase !== "authenticated") return organizationWrongState(state.phase, ["authenticated:claimed"]);
|
|
44394
|
+
}
|
|
43867
44395
|
if (state.account.at !== "claimed") {
|
|
43868
44396
|
const event = state.account.at === "failed" ? { _tag: "RetryAccount" } : state.account.at === "counterfactual" ? { _tag: "ClaimAccount" } : { _tag: "EnsureAccount" };
|
|
43869
44397
|
const claimed = await deps.sendIdentity(event, options);
|
|
@@ -44215,6 +44743,25 @@ const permissionContract = { read: makeFunctionReference(CAPXUL_FUNCTIONS["permi
|
|
|
44215
44743
|
function isAborted(signal) {
|
|
44216
44744
|
return signal?.aborted === true;
|
|
44217
44745
|
}
|
|
44746
|
+
/**
|
|
44747
|
+
* One owning operation per public Permission method. The compound command
|
|
44748
|
+
* (prepare, equality checks, sign, submit) keeps owning its own cancellation;
|
|
44749
|
+
* the observed runner around it is what gives the attempt its
|
|
44750
|
+
* `capxul_sdk_operation` record, its span and its failure capture, so a signer
|
|
44751
|
+
* refusal or an unexpected provider error joins to the operation like every
|
|
44752
|
+
* other public surface.
|
|
44753
|
+
*/
|
|
44754
|
+
function observed(deps, operation, options, run) {
|
|
44755
|
+
const controls = deps.invocationControls?.(options) ?? options;
|
|
44756
|
+
return runCapxulEffect(Effect.gen(function* () {
|
|
44757
|
+
if (controls?.signal?.aborted === true) return yield* Effect.fail(Errors.cancelled({ operation }));
|
|
44758
|
+
const result = yield* Effect.tryPromise({
|
|
44759
|
+
try: () => run(controls?.signal),
|
|
44760
|
+
catch: (cause) => cause instanceof CapxulError ? cause : Errors.unknown(cause)
|
|
44761
|
+
});
|
|
44762
|
+
return yield* result.ok ? Effect.succeed(result.value) : Effect.fail(result.error);
|
|
44763
|
+
}), observationOnlyControls(controls), operation, deps.runPromise);
|
|
44764
|
+
}
|
|
44218
44765
|
async function execute(deps, orgId, command, signal) {
|
|
44219
44766
|
if (isAborted(signal)) return {
|
|
44220
44767
|
ok: false,
|
|
@@ -44274,36 +44821,37 @@ async function execute(deps, orgId, command, signal) {
|
|
|
44274
44821
|
}
|
|
44275
44822
|
function makePermissionMethods(deps, orgId) {
|
|
44276
44823
|
const reads = deps.permissionFunctions ?? permissionContract;
|
|
44824
|
+
const ops = CAPXUL_OPERATIONS.org.permissions;
|
|
44277
44825
|
return {
|
|
44278
|
-
create: (input, options) => execute(deps, orgId, {
|
|
44826
|
+
create: (input, options) => observed(deps, ops.create, options, (signal) => execute(deps, orgId, {
|
|
44279
44827
|
operation: "create",
|
|
44280
44828
|
...input
|
|
44281
|
-
},
|
|
44282
|
-
change: (input, options) => execute(deps, orgId, {
|
|
44829
|
+
}, signal)),
|
|
44830
|
+
change: (input, options) => observed(deps, ops.change, options, (signal) => execute(deps, orgId, {
|
|
44283
44831
|
operation: "change",
|
|
44284
44832
|
...input
|
|
44285
|
-
},
|
|
44286
|
-
assign: (input, options) => execute(deps, orgId, {
|
|
44833
|
+
}, signal)),
|
|
44834
|
+
assign: (input, options) => observed(deps, ops.assign, options, (signal) => execute(deps, orgId, {
|
|
44287
44835
|
operation: "assign",
|
|
44288
44836
|
...input
|
|
44289
|
-
},
|
|
44290
|
-
revoke: (input, options) => execute(deps, orgId, {
|
|
44837
|
+
}, signal)),
|
|
44838
|
+
revoke: (input, options) => observed(deps, ops.revoke, options, (signal) => execute(deps, orgId, {
|
|
44291
44839
|
operation: "revoke",
|
|
44292
44840
|
...input
|
|
44293
|
-
},
|
|
44294
|
-
replace: (input, options) => execute(deps, orgId, {
|
|
44841
|
+
}, signal)),
|
|
44842
|
+
replace: (input, options) => observed(deps, ops.replace, options, (signal) => execute(deps, orgId, {
|
|
44295
44843
|
operation: "replace",
|
|
44296
44844
|
...input
|
|
44297
|
-
},
|
|
44298
|
-
list: (options) =>
|
|
44299
|
-
get:
|
|
44300
|
-
const listed = await runIfActive(
|
|
44845
|
+
}, signal)),
|
|
44846
|
+
list: (options) => observed(deps, ops.list, options, (signal) => runIfActive(signal, CAPXUL_OPERATIONS.permissions.list, () => deps.convexCall.query(reads.read, { orgId }))),
|
|
44847
|
+
get: (permissionId, options) => observed(deps, ops.get, options, async (signal) => {
|
|
44848
|
+
const listed = await runIfActive(signal, CAPXUL_OPERATIONS.permissions.get, () => deps.convexCall.query(reads.read, { orgId }));
|
|
44301
44849
|
if (!listed.ok) return listed;
|
|
44302
44850
|
return {
|
|
44303
44851
|
ok: true,
|
|
44304
44852
|
value: listed.value.permissions.find((row) => row.permissionId === permissionId) ?? null
|
|
44305
44853
|
};
|
|
44306
|
-
}
|
|
44854
|
+
})
|
|
44307
44855
|
};
|
|
44308
44856
|
}
|
|
44309
44857
|
//#endregion
|
|
@@ -44865,7 +45413,7 @@ function hermeticOrgView(input) {
|
|
|
44865
45413
|
name: input.name,
|
|
44866
45414
|
handle: input.handle,
|
|
44867
45415
|
safeAddress: toAddress(placeholder),
|
|
44868
|
-
role:
|
|
45416
|
+
role: ADMIN_ROLE_LABEL,
|
|
44869
45417
|
treasury: zeroTreasury(orgId),
|
|
44870
45418
|
bio: null,
|
|
44871
45419
|
size: null,
|
|
@@ -45111,6 +45659,13 @@ function isRetryableOrganizationSetupFailure(error) {
|
|
|
45111
45659
|
* constructed for each `org(orgId)` call. It has no shared mutable active-Org
|
|
45112
45660
|
* state. The closed-over `orgId` is its only entity reference.
|
|
45113
45661
|
*/
|
|
45662
|
+
/** The observed-runner pair a method bundle needs to own its operation records. */
|
|
45663
|
+
function observedRunnerDeps(deps) {
|
|
45664
|
+
return {
|
|
45665
|
+
...deps.runPromise === void 0 ? {} : { runPromise: deps.runPromise },
|
|
45666
|
+
...deps.invocationControls === void 0 ? {} : { invocationControls: deps.invocationControls }
|
|
45667
|
+
};
|
|
45668
|
+
}
|
|
45114
45669
|
function makeOrgMethods(deps) {
|
|
45115
45670
|
const orgDeps = {
|
|
45116
45671
|
...deps.orgPort === void 0 ? {} : { orgPort: deps.orgPort },
|
|
@@ -45278,6 +45833,7 @@ function makeOrgMethods(deps) {
|
|
|
45278
45833
|
},
|
|
45279
45834
|
permissions: convexCall === void 0 ? makeNotImplementedPermissionMethods() : makePermissionMethods({
|
|
45280
45835
|
convexCall,
|
|
45836
|
+
...observedRunnerDeps(deps),
|
|
45281
45837
|
...deps.actor === void 0 ? {} : { actor: deps.actor },
|
|
45282
45838
|
...deps.chainId === void 0 ? {} : { chainId: Number(deps.chainId) },
|
|
45283
45839
|
...deps.signer === void 0 ? {} : { signer: deps.signer }
|
|
@@ -45578,11 +46134,28 @@ const authFailure = (record, reason, mode) => ({
|
|
|
45578
46134
|
...linkage(record)
|
|
45579
46135
|
}
|
|
45580
46136
|
});
|
|
46137
|
+
const REFUSAL_EVENTS = /* @__PURE__ */ new Set([
|
|
46138
|
+
"ClaimAccount",
|
|
46139
|
+
"RetryAccount",
|
|
46140
|
+
"CreateOrganization",
|
|
46141
|
+
"AttachOrganization",
|
|
46142
|
+
"RetryOrganization"
|
|
46143
|
+
]);
|
|
45581
46144
|
function mapIdentityProductObservation(record, state) {
|
|
45582
46145
|
if (record.machine !== "identity" || !IDENTITY_EVENT_TAG_SET.has(record.event)) return NONE;
|
|
45583
46146
|
if (record.outcome === "cancelled") return NONE;
|
|
45584
46147
|
if (record.slot === "identity:auth" && record.outcome === "refused") return authFailure(record, record.refusal_code, void 0);
|
|
45585
46148
|
if (record.slot === "identity:auth" && record.outcome === "failed") return authFailure(record, record.error_code, record.failure?.mode);
|
|
46149
|
+
if (record.outcome === "refused" && REFUSAL_EVENTS.has(record.event)) return {
|
|
46150
|
+
name: "identity_refused",
|
|
46151
|
+
props: {
|
|
46152
|
+
event: record.event,
|
|
46153
|
+
refusal_code: record.refusal_code,
|
|
46154
|
+
slot: record.slot,
|
|
46155
|
+
state: record.state,
|
|
46156
|
+
...linkage(record)
|
|
46157
|
+
}
|
|
46158
|
+
};
|
|
45586
46159
|
if (record.outcome !== "applied") return NONE;
|
|
45587
46160
|
switch (APPLIED_ACTION_BY_EVENT[record.event]) {
|
|
45588
46161
|
case "none": return NONE;
|
|
@@ -45741,10 +46314,13 @@ function assembleCapxulClient(input) {
|
|
|
45741
46314
|
...input.invokeTimeoutMs === void 0 ? {} : { invokeTimeoutMs: input.invokeTimeoutMs },
|
|
45742
46315
|
afterVerifyOtp: async () => {
|
|
45743
46316
|
const browserSigner = input.signer;
|
|
45744
|
-
if (browserSigner !== void 0 && "resetSession" in browserSigner && typeof browserSigner.resetSession === "function")
|
|
45745
|
-
|
|
45746
|
-
|
|
45747
|
-
|
|
46317
|
+
if (browserSigner !== void 0 && "resetSession" in browserSigner && typeof browserSigner.resetSession === "function") {
|
|
46318
|
+
try {
|
|
46319
|
+
browserSigner.resetSession();
|
|
46320
|
+
} catch (cause) {
|
|
46321
|
+
throw signerFailure(browserSigner.source, "resetSession", cause);
|
|
46322
|
+
}
|
|
46323
|
+
if (browserSigner.statusStore?.status() === "unknown" && typeof browserSigner.ensureWalletReady === "function") browserSigner.ensureWalletReady().catch(() => {});
|
|
45748
46324
|
}
|
|
45749
46325
|
await detectPendingOrgInvitations?.();
|
|
45750
46326
|
kickProvisioning?.();
|
|
@@ -45771,6 +46347,7 @@ function assembleCapxulClient(input) {
|
|
|
45771
46347
|
ensureAccount: account._internal.ensureReady,
|
|
45772
46348
|
getLifecycle: account.getLifecycle,
|
|
45773
46349
|
snapshotIdentity: actor.snapshot,
|
|
46350
|
+
subscribeIdentity: actor.subscribe,
|
|
45774
46351
|
sendIdentity: (event, options) => runCapxulEffect(askIdentity(actor, event, options), options, CAPXUL_OPERATIONS._internal.identity.send, effectRunner.runPromise)
|
|
45775
46352
|
});
|
|
45776
46353
|
const system = makeSystemMethods({ convexCall: input.ports.convexCall });
|
|
@@ -45904,6 +46481,7 @@ function assembleCapxulClient(input) {
|
|
|
45904
46481
|
identity: identityRuntime,
|
|
45905
46482
|
bootstrap: input.bootstrap,
|
|
45906
46483
|
accounts: { fund: accounts.fund },
|
|
46484
|
+
...input.ports.indexerRead === void 0 ? {} : { indexer: input.ports.indexerRead },
|
|
45907
46485
|
organizationSetup: { getProofReceipt: (orgId) => runPortEffect(input.ports.convexCall.query(organizationSetupProofReceiptQuery, { orgId })) },
|
|
45908
46486
|
telemetry: input.ports.telemetry,
|
|
45909
46487
|
captureExternalAddressAcknowledged: (address, organizationId) => {
|
|
@@ -45962,8 +46540,10 @@ function withHostObservationControls(snapshot, input, actorId) {
|
|
|
45962
46540
|
const previous = readInvocationObservation(input);
|
|
45963
46541
|
if (previous !== void 0) return attachInvocationObservation({ ...input }, previous);
|
|
45964
46542
|
const captured = snapshot?.() ?? { active: true };
|
|
46543
|
+
const context = captured.active ? withCapturedAttemptContext(captured.context, input) : captured.context;
|
|
45965
46544
|
return attachInvocationObservation({ ...input }, {
|
|
45966
46545
|
...captured,
|
|
46546
|
+
...context === void 0 ? {} : { context },
|
|
45967
46547
|
...actorId === void 0 ? {} : { actorId }
|
|
45968
46548
|
});
|
|
45969
46549
|
}
|
|
@@ -45983,6 +46563,382 @@ function snapshotHostObservability(observability) {
|
|
|
45983
46563
|
};
|
|
45984
46564
|
}
|
|
45985
46565
|
//#endregion
|
|
46566
|
+
//#region ../../packages/sdk/src/ports/indexer-read.ts
|
|
46567
|
+
/** The indexer's own page bound. Exceeding it is a caller defect, not a refusal. */
|
|
46568
|
+
const INDEXER_MAX_LIMIT = 1e3;
|
|
46569
|
+
const LOWER_CASE_ADDRESS = /^0x[0-9a-f]{40}$/;
|
|
46570
|
+
/**
|
|
46571
|
+
* Refuse a page the indexer would refuse, before any implementation spends a
|
|
46572
|
+
* round trip on it. Every implementation calls this, so a consumer test written
|
|
46573
|
+
* against the hermetic adapter cannot pass on input production rejects. Throws
|
|
46574
|
+
* a `CapxulError`; callers convert it to an `IndexerReadError`.
|
|
46575
|
+
*/
|
|
46576
|
+
function assertIndexerPage(input) {
|
|
46577
|
+
const safe = String(input.safe).toLowerCase();
|
|
46578
|
+
if (!LOWER_CASE_ADDRESS.test(safe)) throw Errors.invalidInput("safe", "must be a lower-case EVM address");
|
|
46579
|
+
if (!Number.isSafeInteger(input.limit) || input.limit < 1 || input.limit > 1e3) throw Errors.invalidInput("limit", `must be an integer from 1 to ${INDEXER_MAX_LIMIT}`);
|
|
46580
|
+
const offset = input.offset ?? 0;
|
|
46581
|
+
if (!Number.isSafeInteger(offset) || offset < 0) throw Errors.invalidInput("offset", "must be a non-negative integer");
|
|
46582
|
+
return safe;
|
|
46583
|
+
}
|
|
46584
|
+
var IndexerReadError = class extends Data.TaggedError("IndexerReadError") {};
|
|
46585
|
+
function indexerReadErrorFromCapxul(operation, error, cause = error) {
|
|
46586
|
+
return new IndexerReadError({
|
|
46587
|
+
operation,
|
|
46588
|
+
publicCode: error.code,
|
|
46589
|
+
publicError: error,
|
|
46590
|
+
cause,
|
|
46591
|
+
...error.details === void 0 ? {} : { details: error.details }
|
|
46592
|
+
});
|
|
46593
|
+
}
|
|
46594
|
+
Context.Service()("@capxul/sdk/ports/IndexerReadPort");
|
|
46595
|
+
//#endregion
|
|
46596
|
+
//#region ../../packages/sdk/src/adapters/ponder/decode.ts
|
|
46597
|
+
/**
|
|
46598
|
+
* Decode the indexer's rows at the trust boundary.
|
|
46599
|
+
*
|
|
46600
|
+
* Ponder returns the raw PostgreSQL result: `integer` arrives as a number,
|
|
46601
|
+
* `numeric(78)` and `text` arrive as strings. Amounts, block numbers and
|
|
46602
|
+
* timestamps are `numeric(78)`, so they become `bigint` here and never pass
|
|
46603
|
+
* through `Number`. Every decoder throws a `CapxulError`; the adapter turns
|
|
46604
|
+
* that into a typed `IndexerReadError`.
|
|
46605
|
+
*/
|
|
46606
|
+
const HEX = /^0x[0-9a-fA-F]+$/;
|
|
46607
|
+
function field(row, key) {
|
|
46608
|
+
if (!(key in row)) throw Errors.invalidInput(key, "missing from the indexer row");
|
|
46609
|
+
return row[key];
|
|
46610
|
+
}
|
|
46611
|
+
function text(row, key) {
|
|
46612
|
+
const value = field(row, key);
|
|
46613
|
+
if (typeof value !== "string") throw Errors.invalidInput(key, "must be a string");
|
|
46614
|
+
return value;
|
|
46615
|
+
}
|
|
46616
|
+
function hex(row, key) {
|
|
46617
|
+
const value = text(row, key);
|
|
46618
|
+
if (!HEX.test(value)) throw Errors.invalidInput(key, "must be a hex string");
|
|
46619
|
+
return value.toLowerCase();
|
|
46620
|
+
}
|
|
46621
|
+
function integer(row, key) {
|
|
46622
|
+
const value = field(row, key);
|
|
46623
|
+
const parsed = typeof value === "string" ? Number(value) : value;
|
|
46624
|
+
if (typeof parsed !== "number" || !Number.isSafeInteger(parsed)) throw Errors.invalidInput(key, "must be an integer");
|
|
46625
|
+
return parsed;
|
|
46626
|
+
}
|
|
46627
|
+
/** `numeric(78)` crosses the wire as a decimal string; keep every digit. */
|
|
46628
|
+
function big(row, key) {
|
|
46629
|
+
const value = field(row, key);
|
|
46630
|
+
if (typeof value === "bigint") return value;
|
|
46631
|
+
const raw = typeof value === "number" ? String(value) : value;
|
|
46632
|
+
if (typeof raw !== "string" || !/^-?[0-9]+$/.test(raw)) throw Errors.invalidInput(key, "must be an exact integer amount");
|
|
46633
|
+
return BigInt(raw);
|
|
46634
|
+
}
|
|
46635
|
+
function asRow(value) {
|
|
46636
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) throw Errors.invalidInput("row", "must be an object");
|
|
46637
|
+
return value;
|
|
46638
|
+
}
|
|
46639
|
+
function identity(row) {
|
|
46640
|
+
return {
|
|
46641
|
+
id: text(row, "id"),
|
|
46642
|
+
chainId: toChainId(integer(row, "chain_id")),
|
|
46643
|
+
txHash: toTxHash(hex(row, "tx_hash")),
|
|
46644
|
+
transactionLogOrdinal: integer(row, "transaction_log_ordinal"),
|
|
46645
|
+
blockNumber: big(row, "block_number"),
|
|
46646
|
+
blockHash: hex(row, "block_hash"),
|
|
46647
|
+
timestamp: big(row, "timestamp")
|
|
46648
|
+
};
|
|
46649
|
+
}
|
|
46650
|
+
function decodeTransfer(value) {
|
|
46651
|
+
const row = asRow(value);
|
|
46652
|
+
return {
|
|
46653
|
+
...identity(row),
|
|
46654
|
+
assetId: toAssetId(text(row, "asset_id")),
|
|
46655
|
+
token: toAddress(hex(row, "token")),
|
|
46656
|
+
from: toAddress(hex(row, "from")),
|
|
46657
|
+
to: toAddress(hex(row, "to")),
|
|
46658
|
+
amount: big(row, "amount")
|
|
46659
|
+
};
|
|
46660
|
+
}
|
|
46661
|
+
function decodePayment(value) {
|
|
46662
|
+
const row = asRow(value);
|
|
46663
|
+
return {
|
|
46664
|
+
...identity(row),
|
|
46665
|
+
contract: toAddress(hex(row, "contract")),
|
|
46666
|
+
settlementId: hex(row, "settlement_id"),
|
|
46667
|
+
sender: toAddress(hex(row, "sender")),
|
|
46668
|
+
recipient: toAddress(hex(row, "recipient")),
|
|
46669
|
+
assetId: toAssetId(text(row, "asset_id")),
|
|
46670
|
+
token: toAddress(hex(row, "token")),
|
|
46671
|
+
amount: big(row, "amount"),
|
|
46672
|
+
kind: integer(row, "kind"),
|
|
46673
|
+
documentHash: hex(row, "document_hash")
|
|
46674
|
+
};
|
|
46675
|
+
}
|
|
46676
|
+
/** The `balance` view exposes the signed sum under the underlying column name `to`. */
|
|
46677
|
+
function decodeBalance(value) {
|
|
46678
|
+
const row = asRow(value);
|
|
46679
|
+
return {
|
|
46680
|
+
chainId: toChainId(integer(row, "chain_id")),
|
|
46681
|
+
assetId: toAssetId(text(row, "asset_id")),
|
|
46682
|
+
address: toAddress(hex(row, "to")),
|
|
46683
|
+
amount: big(row, "amount")
|
|
46684
|
+
};
|
|
46685
|
+
}
|
|
46686
|
+
const DECODERS = {
|
|
46687
|
+
transfer: decodeTransfer,
|
|
46688
|
+
payment: decodePayment,
|
|
46689
|
+
balance: decodeBalance
|
|
46690
|
+
};
|
|
46691
|
+
/** Decode one `/sql/db` or `/sql/live` payload. Ponder returns `{ rows: [...] }`. */
|
|
46692
|
+
function decodeRows(table, body) {
|
|
46693
|
+
const rows = asRow(body).rows;
|
|
46694
|
+
if (!Array.isArray(rows)) throw Errors.invalidInput("rows", "must be an array");
|
|
46695
|
+
const decode = DECODERS[table];
|
|
46696
|
+
return rows.map(decode);
|
|
46697
|
+
}
|
|
46698
|
+
/** Decode Ponder's native `/status`: `{ [chainName]: { id, block: { number, timestamp } } }`. */
|
|
46699
|
+
function decodeStatus(body) {
|
|
46700
|
+
const chains = asRow(body);
|
|
46701
|
+
return Object.entries(chains).map(([chain, value]) => {
|
|
46702
|
+
const entry = asRow(value);
|
|
46703
|
+
const block = asRow(field(entry, "block"));
|
|
46704
|
+
return {
|
|
46705
|
+
chain,
|
|
46706
|
+
chainId: toChainId(integer(entry, "id")),
|
|
46707
|
+
blockNumber: big(block, "number"),
|
|
46708
|
+
blockTimestamp: big(block, "timestamp")
|
|
46709
|
+
};
|
|
46710
|
+
});
|
|
46711
|
+
}
|
|
46712
|
+
//#endregion
|
|
46713
|
+
//#region ../../packages/sdk/src/adapters/ponder/statements.ts
|
|
46714
|
+
/**
|
|
46715
|
+
* The exact statements the indexer accepts.
|
|
46716
|
+
*
|
|
46717
|
+
* `apps/indexer/src/queries.ts` compiles its allowlist with `@ponder/client`
|
|
46718
|
+
* and compares `sql`, `params` and `typings` byte for byte against the caller's
|
|
46719
|
+
* statement. Anything else gets 403. The SDK therefore reproduces the compiled
|
|
46720
|
+
* text here rather than pulling Ponder and Drizzle into a published browser
|
|
46721
|
+
* bundle to regenerate three fixed statements.
|
|
46722
|
+
*
|
|
46723
|
+
* `statements.test.ts` pins the text. When the indexer schema or a query in
|
|
46724
|
+
* that allowlist changes, this file changes with it or every read fails 403.
|
|
46725
|
+
*/
|
|
46726
|
+
const HEADS = {
|
|
46727
|
+
transfer: "select \"id\", \"chain_id\", \"tx_hash\", \"transaction_log_ordinal\", \"block_number\", \"block_hash\", \"timestamp\", \"asset_id\", \"token\", \"from\", \"to\", \"amount\" from \"transfer\" where (\"transfer\".\"from\" = $1 or \"transfer\".\"to\" = $2) order by \"transfer\".\"block_number\" desc, \"transfer\".\"id\" desc",
|
|
46728
|
+
payment: "select \"id\", \"chain_id\", \"tx_hash\", \"transaction_log_ordinal\", \"block_number\", \"block_hash\", \"timestamp\", \"contract\", \"settlement_id\", \"sender\", \"recipient\", \"asset_id\", \"token\", \"amount\", \"kind\", \"document_hash\" from \"payment\" where (\"payment\".\"sender\" = $1 or \"payment\".\"recipient\" = $2) order by \"payment\".\"block_number\" desc, \"payment\".\"id\" desc",
|
|
46729
|
+
balance: "select \"chain_id\", \"asset_id\", \"to\", \"amount\" from \"balance\" where \"balance\".\"to\" = $1"
|
|
46730
|
+
};
|
|
46731
|
+
/** How many times the statement binds the Safe address. */
|
|
46732
|
+
const ACTOR_PARAMS = {
|
|
46733
|
+
transfer: 2,
|
|
46734
|
+
payment: 2,
|
|
46735
|
+
balance: 1
|
|
46736
|
+
};
|
|
46737
|
+
/**
|
|
46738
|
+
* Build the compiled query for one table and page. Throws a `CapxulError` for
|
|
46739
|
+
* a page or address the indexer would refuse, so the caller never spends a
|
|
46740
|
+
* round trip to learn it built the request wrong.
|
|
46741
|
+
*/
|
|
46742
|
+
function ponderQuery(table, input) {
|
|
46743
|
+
const safe = assertIndexerPage(input);
|
|
46744
|
+
const offset = input.offset ?? 0;
|
|
46745
|
+
const actors = ACTOR_PARAMS[table];
|
|
46746
|
+
const params = [];
|
|
46747
|
+
for (let i = 0; i < actors; i++) params.push(safe);
|
|
46748
|
+
params.push(input.limit);
|
|
46749
|
+
let sql = `${HEADS[table]} limit $${actors + 1}`;
|
|
46750
|
+
if (offset > 0) {
|
|
46751
|
+
params.push(offset);
|
|
46752
|
+
sql = `${sql} offset $${actors + 2}`;
|
|
46753
|
+
}
|
|
46754
|
+
return {
|
|
46755
|
+
sql,
|
|
46756
|
+
params,
|
|
46757
|
+
typings: params.map(() => "none")
|
|
46758
|
+
};
|
|
46759
|
+
}
|
|
46760
|
+
/**
|
|
46761
|
+
* The `?sql=` value. `@ponder/client` sends `superjson.stringify(query)`; for a
|
|
46762
|
+
* payload of strings and numbers superjson emits no `meta`, so the wire form is
|
|
46763
|
+
* exactly this envelope.
|
|
46764
|
+
*/
|
|
46765
|
+
function ponderQueryParam(query) {
|
|
46766
|
+
return JSON.stringify({ json: query });
|
|
46767
|
+
}
|
|
46768
|
+
//#endregion
|
|
46769
|
+
//#region ../../packages/sdk/src/adapters/ponder/sse.ts
|
|
46770
|
+
/**
|
|
46771
|
+
* The smallest SSE reader that can carry an `Authorization` header.
|
|
46772
|
+
*
|
|
46773
|
+
* `@ponder/client` opens its live query with `EventSource`, which accepts no
|
|
46774
|
+
* headers, so it cannot reach the guarded indexer at all. The indexer's CORS
|
|
46775
|
+
* policy allows exactly one request header (`Authorization`), so this reader
|
|
46776
|
+
* sends nothing else. Ponder writes one `data:` line per frame.
|
|
46777
|
+
*/
|
|
46778
|
+
async function readEventStream(body, onData, stopped) {
|
|
46779
|
+
const reader = body.getReader();
|
|
46780
|
+
const decoder = new TextDecoder();
|
|
46781
|
+
let buffer = "";
|
|
46782
|
+
try {
|
|
46783
|
+
for (;;) {
|
|
46784
|
+
const { done, value } = await reader.read();
|
|
46785
|
+
if (done || stopped()) return;
|
|
46786
|
+
buffer += decoder.decode(value, { stream: true });
|
|
46787
|
+
let split = buffer.indexOf("\n\n");
|
|
46788
|
+
while (split !== -1) {
|
|
46789
|
+
const frame = buffer.slice(0, split);
|
|
46790
|
+
buffer = buffer.slice(split + 2);
|
|
46791
|
+
const data = frameData(frame);
|
|
46792
|
+
if (data !== void 0) onData(data);
|
|
46793
|
+
if (stopped()) return;
|
|
46794
|
+
split = buffer.indexOf("\n\n");
|
|
46795
|
+
}
|
|
46796
|
+
}
|
|
46797
|
+
} finally {
|
|
46798
|
+
await reader.cancel().catch(() => void 0);
|
|
46799
|
+
}
|
|
46800
|
+
}
|
|
46801
|
+
function frameData(frame) {
|
|
46802
|
+
const lines = [];
|
|
46803
|
+
for (const line of frame.split("\n")) {
|
|
46804
|
+
if (!line.startsWith("data:")) continue;
|
|
46805
|
+
lines.push(line.slice(line.startsWith("data: ") ? 6 : 5));
|
|
46806
|
+
}
|
|
46807
|
+
return lines.length === 0 ? void 0 : lines.join("\n");
|
|
46808
|
+
}
|
|
46809
|
+
//#endregion
|
|
46810
|
+
//#region ../../packages/sdk/src/adapters/ponder/PonderIndexerAdapter.ts
|
|
46811
|
+
var PonderIndexerAdapter = class {
|
|
46812
|
+
#baseUrl;
|
|
46813
|
+
#token;
|
|
46814
|
+
#fetch;
|
|
46815
|
+
#observation;
|
|
46816
|
+
constructor(deps) {
|
|
46817
|
+
this.#baseUrl = deps.baseUrl.replace(/\/$/, "");
|
|
46818
|
+
this.#token = deps.token;
|
|
46819
|
+
this.#observation = deps.observation;
|
|
46820
|
+
this.#fetch = deps.fetch ?? ((input, init) => globalThis.fetch(input, init));
|
|
46821
|
+
}
|
|
46822
|
+
read(table, input) {
|
|
46823
|
+
const operation = `indexer.read.${table}`;
|
|
46824
|
+
return Effect.tryPromise({
|
|
46825
|
+
try: async () => {
|
|
46826
|
+
return decodeRows(table, await (await this.#request("db", table, input, operation)).json());
|
|
46827
|
+
},
|
|
46828
|
+
catch: (cause) => toIndexerReadError(operation, cause)
|
|
46829
|
+
});
|
|
46830
|
+
}
|
|
46831
|
+
subscribe(table, input, callback) {
|
|
46832
|
+
const operation = CAPXUL_OPERATIONS.activity.subscribe;
|
|
46833
|
+
return Effect.sync(() => {
|
|
46834
|
+
let stopped = false;
|
|
46835
|
+
const unsubscribe = () => {
|
|
46836
|
+
stopped = true;
|
|
46837
|
+
};
|
|
46838
|
+
callback({ status: "loading" });
|
|
46839
|
+
this.#stream(table, input, operation, callback, () => stopped).catch(() => void 0);
|
|
46840
|
+
return unsubscribe;
|
|
46841
|
+
});
|
|
46842
|
+
}
|
|
46843
|
+
status = Effect.tryPromise({
|
|
46844
|
+
try: async () => {
|
|
46845
|
+
const response = await this.#fetch(`${this.#baseUrl}/status`, { method: "GET" });
|
|
46846
|
+
if (!response.ok) throw httpError("indexer.status", response.status, await safeText(response));
|
|
46847
|
+
return decodeStatus(await response.json());
|
|
46848
|
+
},
|
|
46849
|
+
catch: (cause) => toIndexerReadError("indexer.status", cause)
|
|
46850
|
+
});
|
|
46851
|
+
/** One authenticated `/sql/:method` call. Throws a `CapxulError` on refusal. */
|
|
46852
|
+
async #request(method, table, input, operation) {
|
|
46853
|
+
const query = ponderQuery(table, input);
|
|
46854
|
+
const token = await this.#token({ forceRefreshToken: false });
|
|
46855
|
+
if (token === null || token === "") throw Errors.notAuthenticated();
|
|
46856
|
+
const url = `${this.#baseUrl}/sql/${method}?sql=${encodeURIComponent(ponderQueryParam(query))}`;
|
|
46857
|
+
const headers = { authorization: `Bearer ${token}` };
|
|
46858
|
+
if (method === "live") headers.accept = "text/event-stream";
|
|
46859
|
+
let response;
|
|
46860
|
+
try {
|
|
46861
|
+
response = await this.#fetch(url, {
|
|
46862
|
+
method: "GET",
|
|
46863
|
+
headers
|
|
46864
|
+
});
|
|
46865
|
+
} catch (cause) {
|
|
46866
|
+
throw Errors.networkError(operation, cause, {
|
|
46867
|
+
provider: "indexer",
|
|
46868
|
+
failure_mode: "upstream-down"
|
|
46869
|
+
});
|
|
46870
|
+
}
|
|
46871
|
+
if (!response.ok) throw httpError(operation, response.status, await safeText(response));
|
|
46872
|
+
return response;
|
|
46873
|
+
}
|
|
46874
|
+
/**
|
|
46875
|
+
* Follow the live stream until the caller unsubscribes or the indexer closes
|
|
46876
|
+
* it. The indexer closes the stream on token expiry or revoked authority
|
|
46877
|
+
* with no frame, so any end the caller did not ask for is a teardown: it
|
|
46878
|
+
* reaches `captureException` under `activity.subscribe` and the caller sees
|
|
46879
|
+
* one `error` snapshot.
|
|
46880
|
+
*/
|
|
46881
|
+
async #stream(table, input, operation, callback, stopped) {
|
|
46882
|
+
let failure;
|
|
46883
|
+
try {
|
|
46884
|
+
const response = await this.#request("live", table, input, operation);
|
|
46885
|
+
if (response.body === null) throw Errors.providerError("indexer", operation, "empty stream");
|
|
46886
|
+
await readEventStream(response.body, (data) => {
|
|
46887
|
+
try {
|
|
46888
|
+
callback({
|
|
46889
|
+
status: "ok",
|
|
46890
|
+
value: decodeRows(table, JSON.parse(data))
|
|
46891
|
+
});
|
|
46892
|
+
} catch (cause) {
|
|
46893
|
+
failure = toPublicError$1(operation, cause);
|
|
46894
|
+
}
|
|
46895
|
+
}, () => stopped() || failure !== void 0);
|
|
46896
|
+
} catch (cause) {
|
|
46897
|
+
failure = toPublicError$1(operation, cause);
|
|
46898
|
+
}
|
|
46899
|
+
if (stopped()) return;
|
|
46900
|
+
const error = failure ?? Errors.capabilityUnavailable("indexer", operation);
|
|
46901
|
+
observeStreamFailure(this.#observation, CAPXUL_OPERATIONS.activity.subscribe, error);
|
|
46902
|
+
callback({
|
|
46903
|
+
status: "error",
|
|
46904
|
+
error
|
|
46905
|
+
});
|
|
46906
|
+
}
|
|
46907
|
+
};
|
|
46908
|
+
/**
|
|
46909
|
+
* Map an indexer refusal into the shared error vocabulary.
|
|
46910
|
+
*
|
|
46911
|
+
* 401 is the expected outcome of an expired or revoked session. 403 is not:
|
|
46912
|
+
* the indexer accepts only its own compiled statements for a Safe in the
|
|
46913
|
+
* claim, so a refusal means this SDK and that deployment disagree, or the
|
|
46914
|
+
* session gained a Safe and still holds the older token. Both must be loud.
|
|
46915
|
+
*/
|
|
46916
|
+
function httpError(operation, status, body) {
|
|
46917
|
+
if (status === 401) return Errors.notAuthenticated();
|
|
46918
|
+
if (status === 429) return Errors.rateLimited({ resource: "indexer" });
|
|
46919
|
+
if (status === 503) return Errors.capabilityUnavailable("indexer", operation);
|
|
46920
|
+
return Errors.providerError("indexer", operation, body, {
|
|
46921
|
+
httpStatus: status,
|
|
46922
|
+
...status >= 500 ? { failure_mode: "upstream-down" } : {},
|
|
46923
|
+
details: { reason: status === 403 ? "scope-refused" : "http-status" }
|
|
46924
|
+
});
|
|
46925
|
+
}
|
|
46926
|
+
function toPublicError$1(operation, cause) {
|
|
46927
|
+
if (cause instanceof CapxulError) return cause;
|
|
46928
|
+
return Errors.providerError("indexer", operation, cause);
|
|
46929
|
+
}
|
|
46930
|
+
function toIndexerReadError(operation, cause) {
|
|
46931
|
+
if (cause instanceof IndexerReadError) return cause;
|
|
46932
|
+
return indexerReadErrorFromCapxul(operation, toPublicError$1(operation, cause), cause);
|
|
46933
|
+
}
|
|
46934
|
+
async function safeText(response) {
|
|
46935
|
+
try {
|
|
46936
|
+
return await response.text();
|
|
46937
|
+
} catch {
|
|
46938
|
+
return "";
|
|
46939
|
+
}
|
|
46940
|
+
}
|
|
46941
|
+
//#endregion
|
|
45986
46942
|
//#region ../../packages/sdk/src/adapters/_shared/clock.ts
|
|
45987
46943
|
async function readClockNow(clock) {
|
|
45988
46944
|
try {
|
|
@@ -46439,7 +47395,16 @@ async function createProductionAdapters(input) {
|
|
|
46439
47395
|
}));
|
|
46440
47396
|
const applicationLayer = Layer.merge(portsLayer, optionalEngineeringTelemetryLayer(bootstrapResult.value.engineeringTelemetry, resolvedInput.value.runtime));
|
|
46441
47397
|
const context = await Effect.runPromise(Layer.buildWithScope(applicationLayer, scope));
|
|
46442
|
-
const
|
|
47398
|
+
const collected = await Effect.runPromise(collectProductionFlowPorts.pipe(Effect.provide(context)));
|
|
47399
|
+
const indexerUrl = input.indexerUrl ?? bootstrapResult.value.indexerUrl;
|
|
47400
|
+
const indexerRead = productionIndexerReadPort(indexerUrl === void 0 ? input : {
|
|
47401
|
+
...input,
|
|
47402
|
+
indexerUrl
|
|
47403
|
+
}, collected, observation);
|
|
47404
|
+
const ports = indexerRead === void 0 ? collected : {
|
|
47405
|
+
...collected,
|
|
47406
|
+
indexerRead
|
|
47407
|
+
};
|
|
46443
47408
|
const stopConnectionObservation = observeProductionConvexConnection(ports.convexCall, context);
|
|
46444
47409
|
const close = idempotentClose(async () => {
|
|
46445
47410
|
try {
|
|
@@ -46566,7 +47531,7 @@ async function createCapxulClientWithSignerControls(input, controls) {
|
|
|
46566
47531
|
...adapters.value.bootstrap,
|
|
46567
47532
|
authBaseUrl: resolvedAuthBaseUrl
|
|
46568
47533
|
}, {
|
|
46569
|
-
diagnostic: new ConsoleDiagnosticAdapter(),
|
|
47534
|
+
diagnostic: new EffectLogDiagnosticAdapter(adapters.value.context, new ConsoleDiagnosticAdapter()),
|
|
46570
47535
|
signUserOpHash: controls.signEmbeddedUserOpHash
|
|
46571
47536
|
});
|
|
46572
47537
|
signer = withSignerControl(signer, controls.signUserOpHash);
|
|
@@ -46771,6 +47736,28 @@ function idempotentClose(close) {
|
|
|
46771
47736
|
await close();
|
|
46772
47737
|
};
|
|
46773
47738
|
}
|
|
47739
|
+
/**
|
|
47740
|
+
* Build the Ponder read port for this client, or `undefined` when no indexer
|
|
47741
|
+
* origin was supplied. The token provider is the same
|
|
47742
|
+
* `AuthClientPort.getConvexJwt` closure `ConvexCallPort` uses, so the indexer
|
|
47743
|
+
* and Convex see one session with one scope.
|
|
47744
|
+
*/
|
|
47745
|
+
function productionIndexerReadPort(input, ports, observation) {
|
|
47746
|
+
if (input.indexerUrl === void 0 || input.indexerUrl === "") return void 0;
|
|
47747
|
+
return new PonderIndexerAdapter({
|
|
47748
|
+
baseUrl: normalizeHttpUrl("indexerUrl", input.indexerUrl),
|
|
47749
|
+
token: async ({ forceRefreshToken }) => {
|
|
47750
|
+
const token = await Effect.runPromise(Effect.result(ports.authClient.getConvexJwt({
|
|
47751
|
+
forceRefresh: forceRefreshToken,
|
|
47752
|
+
...input.signal === void 0 ? {} : { signal: input.signal }
|
|
47753
|
+
})));
|
|
47754
|
+
if (Result.isFailure(token)) return null;
|
|
47755
|
+
return String(token.success.token);
|
|
47756
|
+
},
|
|
47757
|
+
...input.fetch === void 0 ? {} : { fetch: input.fetch },
|
|
47758
|
+
...observation === void 0 ? {} : { observation }
|
|
47759
|
+
});
|
|
47760
|
+
}
|
|
46774
47761
|
//#endregion
|
|
46775
47762
|
//#region src/tools/account.ts
|
|
46776
47763
|
const READ = "account:read";
|
|
@@ -47382,7 +48369,7 @@ function stdioIdentity(env = process.env, options = {}) {
|
|
|
47382
48369
|
}
|
|
47383
48370
|
//#endregion
|
|
47384
48371
|
//#region package.json
|
|
47385
|
-
var version = "4.2.0-rc.
|
|
48372
|
+
var version = "4.2.0-rc.10";
|
|
47386
48373
|
//#endregion
|
|
47387
48374
|
//#region src/deps.ts
|
|
47388
48375
|
const NO_IDENTITY = async () => void 0;
|