tapimo 0.7.2 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -7
- package/dist/ApiKey.d.ts +3 -0
- package/dist/ApiKey.d.ts.map +1 -1
- package/dist/ApiKey.js +10 -0
- package/dist/ApiKey.js.map +1 -1
- package/dist/ApiKeys.d.ts +7 -3
- package/dist/ApiKeys.d.ts.map +1 -1
- package/dist/ApiKeys.js +9 -2
- package/dist/ApiKeys.js.map +1 -1
- package/dist/App.d.ts +20434 -19484
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +62 -4
- package/dist/App.js.map +1 -1
- package/dist/admin/App.d.ts +84 -74
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.d.ts +14 -1
- package/dist/admin/apps/api-keys.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.js +6 -2
- package/dist/admin/apps/api-keys.js.map +1 -1
- package/dist/admin/apps/organizations.d.ts +2 -0
- package/dist/admin/apps/organizations.d.ts.map +1 -1
- package/dist/admin/apps/verified-tokens.d.ts +168 -168
- package/dist/admin/ui.generated.d.ts +1 -1
- package/dist/admin/ui.generated.js +67 -67
- package/dist/admin/ui.generated.js.map +1 -1
- package/dist/analytics/Analytics.d.ts +2 -0
- package/dist/analytics/Analytics.d.ts.map +1 -1
- package/dist/analytics/Analytics.js +3 -0
- package/dist/analytics/Analytics.js.map +1 -1
- package/dist/apps/data/App.d.ts +10305 -12785
- package/dist/apps/data/App.d.ts.map +1 -1
- package/dist/apps/data/App.js +4 -8
- package/dist/apps/data/App.js.map +1 -1
- package/dist/apps/data/routes/activities.d.ts +24 -24
- package/dist/apps/data/routes/addresses.d.ts +288 -288
- package/dist/apps/data/routes/balances.d.ts +6 -6
- package/dist/apps/data/routes/blocks.d.ts +39 -39
- package/dist/apps/data/routes/coingecko.d.ts +170 -170
- package/dist/apps/data/routes/earn.d.ts +436 -6
- package/dist/apps/data/routes/earn.d.ts.map +1 -1
- package/dist/apps/data/routes/earn.js +631 -4
- package/dist/apps/data/routes/earn.js.map +1 -1
- package/dist/apps/data/routes/exchanges.d.ts +10 -10
- package/dist/apps/data/routes/fee-amm.d.ts +2 -2
- package/dist/apps/data/routes/indexer.d.ts +6 -6
- package/dist/apps/data/routes/indexer.js +4 -1
- package/dist/apps/data/routes/indexer.js.map +1 -1
- package/dist/apps/data/routes/receipts.d.ts +235 -235
- package/dist/apps/data/routes/rpc.d.ts +1 -1
- package/dist/apps/data/routes/rpc.js +4 -1
- package/dist/apps/data/routes/rpc.js.map +1 -1
- package/dist/apps/data/routes/tokenlist.d.ts +36 -36
- package/dist/apps/data/routes/tokens.d.ts +6 -6
- package/dist/apps/data/routes/transactions.d.ts +2 -2
- package/dist/apps/data/routes/transfers.d.ts +1 -1
- package/dist/apps/data/routes/valuation.d.ts +1 -1
- package/dist/apps/data/routes/verified-tokens.d.ts +36 -36
- package/dist/apps/data/routes/webhooks.d.ts +9 -9
- package/dist/apps/data/routes/zones.d.ts +14 -14
- package/dist/apps/funding/Access.d.ts +16 -0
- package/dist/apps/funding/Access.d.ts.map +1 -0
- package/dist/apps/funding/Access.js +22 -0
- package/dist/apps/funding/Access.js.map +1 -0
- package/dist/apps/{data/routes/funding.d.ts → funding/App.d.ts} +1717 -3035
- package/dist/apps/funding/App.d.ts.map +1 -0
- package/dist/apps/funding/App.js +46 -0
- package/dist/apps/funding/App.js.map +1 -0
- package/dist/apps/funding/Inventory.d.ts +5 -0
- package/dist/apps/funding/Inventory.d.ts.map +1 -0
- package/dist/apps/funding/Inventory.js +25 -0
- package/dist/apps/funding/Inventory.js.map +1 -0
- package/dist/apps/funding/ProviderAttempts.d.ts +5 -0
- package/dist/apps/funding/ProviderAttempts.d.ts.map +1 -0
- package/dist/apps/funding/ProviderAttempts.js +24 -0
- package/dist/apps/funding/ProviderAttempts.js.map +1 -0
- package/dist/apps/funding/index.d.ts +2 -0
- package/dist/apps/funding/index.d.ts.map +1 -0
- package/dist/apps/funding/index.js +2 -0
- package/dist/apps/funding/index.js.map +1 -0
- package/dist/apps/funding/routes/chains.d.ts +169 -0
- package/dist/apps/funding/routes/chains.d.ts.map +1 -0
- package/dist/apps/funding/routes/chains.js +80 -0
- package/dist/apps/funding/routes/chains.js.map +1 -0
- package/dist/apps/funding/routes/deposit-addresses.d.ts +2388 -0
- package/dist/apps/funding/routes/deposit-addresses.d.ts.map +1 -0
- package/dist/apps/funding/routes/deposit-addresses.js +860 -0
- package/dist/apps/funding/routes/deposit-addresses.js.map +1 -0
- package/dist/apps/funding/routes/providers.d.ts +91 -0
- package/dist/apps/funding/routes/providers.d.ts.map +1 -0
- package/dist/apps/funding/routes/providers.js +56 -0
- package/dist/apps/funding/routes/providers.js.map +1 -0
- package/dist/apps/funding/routes/quotes.d.ts +426 -0
- package/dist/apps/funding/routes/quotes.d.ts.map +1 -0
- package/dist/apps/funding/routes/quotes.js +188 -0
- package/dist/apps/funding/routes/quotes.js.map +1 -0
- package/dist/apps/funding/routes/transfers.d.ts +1999 -0
- package/dist/apps/funding/routes/transfers.d.ts.map +1 -0
- package/dist/apps/funding/routes/transfers.js +614 -0
- package/dist/apps/funding/routes/transfers.js.map +1 -0
- package/dist/apps/index.d.ts +1 -0
- package/dist/apps/index.d.ts.map +1 -1
- package/dist/apps/index.js +1 -0
- package/dist/apps/index.js.map +1 -1
- package/dist/apps/management/App.d.ts +430 -165
- package/dist/apps/management/App.d.ts.map +1 -1
- package/dist/apps/management/routes/api-keys.d.ts +298 -21
- package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
- package/dist/apps/management/routes/api-keys.js +75 -1
- package/dist/apps/management/routes/api-keys.js.map +1 -1
- package/dist/apps/management/routes/billing.d.ts +6 -6
- package/dist/apps/management/routes/faucet.d.ts +35 -35
- package/dist/apps/management/routes/invitations.d.ts +48 -48
- package/dist/apps/management/routes/invite-links.d.ts +38 -38
- package/dist/apps/management/routes/members.d.ts +69 -69
- package/dist/apps/management/routes/orgs.d.ts +37 -37
- package/dist/apps/management/routes/projects.d.ts +25 -25
- package/dist/apps/management/routes/scopes.d.ts +1 -1
- package/dist/apps/management/routes/usage.d.ts +72 -72
- package/dist/apps/management/routes/verified-token-requests.d.ts +18 -18
- package/dist/apps/management/routes/webhooks.d.ts +128 -128
- package/dist/apps/mcp.d.ts +2 -3
- package/dist/apps/mcp.d.ts.map +1 -1
- package/dist/apps/mcp.js +16 -14
- package/dist/apps/mcp.js.map +1 -1
- package/dist/apps/metadata.d.ts +4 -0
- package/dist/apps/metadata.d.ts.map +1 -1
- package/dist/apps/metadata.js +10 -0
- package/dist/apps/metadata.js.map +1 -1
- package/dist/apps/mpp/App.d.ts +2 -2
- package/dist/cloudflare.d.ts +50 -0
- package/dist/cloudflare.d.ts.map +1 -1
- package/dist/cloudflare.js +178 -0
- package/dist/cloudflare.js.map +1 -1
- package/dist/db/Db.d.ts +2 -0
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +37 -0
- package/dist/db/Db.js.map +1 -1
- package/dist/db/Schema.d.ts +12 -0
- package/dist/db/Schema.d.ts.map +1 -1
- package/dist/db/Schema.js +20 -0
- package/dist/db/Schema.js.map +1 -1
- package/dist/db/tables/fundingDepositAddresses.d.ts +13 -0
- package/dist/db/tables/fundingDepositAddresses.d.ts.map +1 -1
- package/dist/db/tables/fundingDepositAddresses.js +12 -0
- package/dist/db/tables/fundingDepositAddresses.js.map +1 -1
- package/dist/db/tables/fundingDepositRequestObservations.d.ts +45 -0
- package/dist/db/tables/fundingDepositRequestObservations.d.ts.map +1 -0
- package/dist/db/tables/fundingDepositRequestObservations.js +46 -0
- package/dist/db/tables/fundingDepositRequestObservations.js.map +1 -0
- package/dist/db/tables/fundingDeposits.d.ts +57 -1
- package/dist/db/tables/fundingDeposits.d.ts.map +1 -1
- package/dist/db/tables/fundingDeposits.js +82 -0
- package/dist/db/tables/fundingDeposits.js.map +1 -1
- package/dist/internal/Auth.d.ts +11 -11
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +41 -15
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/Cache.js +1 -1
- package/dist/internal/Cache.js.map +1 -1
- package/dist/internal/EdgeCache.d.ts +2 -2
- package/dist/internal/EdgeCache.d.ts.map +1 -1
- package/dist/internal/EdgeCache.js +10 -4
- package/dist/internal/EdgeCache.js.map +1 -1
- package/dist/internal/IpAllowlist.d.ts +15 -0
- package/dist/internal/IpAllowlist.d.ts.map +1 -0
- package/dist/internal/IpAllowlist.js +27 -0
- package/dist/internal/IpAllowlist.js.map +1 -0
- package/dist/internal/OpenApi.d.ts +1 -1
- package/dist/internal/OpenApi.js +1 -1
- package/dist/internal/OpenApi.js.map +1 -1
- package/dist/internal/Tidx.d.ts +6 -0
- package/dist/internal/Tidx.d.ts.map +1 -1
- package/dist/internal/Tidx.js +13 -3
- package/dist/internal/Tidx.js.map +1 -1
- package/dist/internal/Viem.d.ts +8 -0
- package/dist/internal/Viem.d.ts.map +1 -1
- package/dist/internal/Viem.js +12 -5
- package/dist/internal/Viem.js.map +1 -1
- package/dist/internal/funding/Deposit.d.ts +42 -0
- package/dist/internal/funding/Deposit.d.ts.map +1 -1
- package/dist/internal/funding/Deposit.js +37 -5
- package/dist/internal/funding/Deposit.js.map +1 -1
- package/dist/internal/funding/Evidence.d.ts +1 -5
- package/dist/internal/funding/Evidence.d.ts.map +1 -1
- package/dist/internal/funding/Evidence.js +4 -3
- package/dist/internal/funding/Evidence.js.map +1 -1
- package/dist/internal/funding/Provider.d.ts +102 -0
- package/dist/internal/funding/Provider.d.ts.map +1 -1
- package/dist/internal/funding/Provider.js +5 -0
- package/dist/internal/funding/Provider.js.map +1 -1
- package/dist/internal/funding/Reconciliation.d.ts +16 -2
- package/dist/internal/funding/Reconciliation.d.ts.map +1 -1
- package/dist/internal/funding/Reconciliation.js +257 -48
- package/dist/internal/funding/Reconciliation.js.map +1 -1
- package/dist/internal/funding/SourceObservation.d.ts +108 -0
- package/dist/internal/funding/SourceObservation.d.ts.map +1 -0
- package/dist/internal/funding/SourceObservation.js +143 -0
- package/dist/internal/funding/SourceObservation.js.map +1 -0
- package/dist/internal/funding/Subsidy.d.ts +2 -2
- package/dist/internal/funding/Subsidy.d.ts.map +1 -1
- package/dist/internal/funding/Subsidy.js +1 -1
- package/dist/internal/funding/Subsidy.js.map +1 -1
- package/dist/internal/funding/index.d.ts +1 -0
- package/dist/internal/funding/index.d.ts.map +1 -1
- package/dist/internal/funding/index.js +1 -0
- package/dist/internal/funding/index.js.map +1 -1
- package/dist/internal/funding/providers/relay.d.ts +43 -1
- package/dist/internal/funding/providers/relay.d.ts.map +1 -1
- package/dist/internal/funding/providers/relay.js +434 -27
- package/dist/internal/funding/providers/relay.js.map +1 -1
- package/package.json +3 -3
- package/src/ApiKey.test.ts +35 -0
- package/src/ApiKey.ts +27 -0
- package/src/ApiKeys.test.ts +29 -0
- package/src/ApiKeys.ts +11 -3
- package/src/App.test.ts +23 -5
- package/src/App.ts +76 -5
- package/src/Client.test-d.ts +171 -19
- package/src/admin/apps/api-keys.test.ts +25 -1
- package/src/admin/apps/api-keys.ts +6 -2
- package/src/admin/ui.generated.ts +67 -67
- package/src/analytics/Analytics.ts +4 -0
- package/src/apps/composition.test.ts +100 -2
- package/src/apps/data/App.test.ts +0 -12
- package/src/apps/data/App.ts +4 -8
- package/src/apps/data/routes/earn.test.ts +283 -0
- package/src/apps/data/routes/earn.ts +800 -3
- package/src/apps/data/routes/indexer.ts +2 -1
- package/src/apps/data/routes/rpc.ts +2 -0
- package/src/apps/data/routes/tokens.test.ts +6 -8
- package/src/apps/funding/Access.ts +26 -0
- package/src/apps/funding/App.test.ts +78 -0
- package/src/apps/funding/App.ts +63 -0
- package/src/apps/funding/Inventory.ts +30 -0
- package/src/apps/funding/ProviderAttempts.ts +26 -0
- package/src/apps/funding/index.ts +1 -0
- package/src/apps/funding/routes/chains.test.ts +78 -0
- package/src/apps/funding/routes/chains.ts +101 -0
- package/src/apps/funding/routes/deposit-addresses.test.ts +1628 -0
- package/src/apps/funding/routes/deposit-addresses.ts +1015 -0
- package/src/apps/funding/routes/providers.test.ts +165 -0
- package/src/apps/funding/routes/providers.ts +73 -0
- package/src/apps/funding/routes/quotes.test.ts +511 -0
- package/src/apps/funding/routes/quotes.ts +205 -0
- package/src/apps/funding/routes/transfers.test.ts +1255 -0
- package/src/apps/funding/routes/transfers.ts +704 -0
- package/src/apps/index.ts +1 -0
- package/src/apps/management/routes/api-keys.test.ts +98 -0
- package/src/apps/management/routes/api-keys.ts +96 -1
- package/src/apps/mcp.test.ts +17 -2
- package/src/apps/mcp.ts +18 -13
- package/src/apps/metadata.ts +12 -0
- package/src/apps/mpp/internal/Policy.test.ts +7 -1
- package/src/cloudflare.ts +279 -0
- package/src/db/Db.ts +62 -0
- package/src/db/Schema.ts +24 -0
- package/src/db/tables/fundingDepositAddresses.ts +28 -0
- package/src/db/tables/fundingDepositRequestObservations.test.ts +106 -0
- package/src/db/tables/fundingDepositRequestObservations.ts +99 -0
- package/src/db/tables/fundingDeposits.test.ts +138 -0
- package/src/db/tables/fundingDeposits.ts +145 -1
- package/src/internal/Auth.test.ts +177 -5
- package/src/internal/Auth.ts +48 -18
- package/src/internal/Cache.test.ts +37 -3
- package/src/internal/Cache.ts +1 -1
- package/src/internal/EdgeCache.test.ts +7 -7
- package/src/internal/EdgeCache.ts +13 -4
- package/src/internal/IpAllowlist.test.ts +52 -0
- package/src/internal/IpAllowlist.ts +39 -0
- package/src/internal/Log.test.ts +7 -1
- package/src/internal/OpenApi.ts +1 -1
- package/src/internal/Tidx.test.ts +28 -0
- package/src/internal/Tidx.ts +19 -3
- package/src/internal/Viem.test.ts +28 -0
- package/src/internal/Viem.ts +21 -5
- package/src/internal/funding/Deposit.ts +74 -5
- package/src/internal/funding/Evidence.test.ts +2 -2
- package/src/internal/funding/Evidence.ts +4 -9
- package/src/internal/funding/Provider.ts +115 -0
- package/src/internal/funding/Reconciliation.local.test.ts +7 -0
- package/src/internal/funding/Reconciliation.test.ts +1052 -35
- package/src/internal/funding/Reconciliation.ts +328 -56
- package/src/internal/funding/SourceObservation.test.ts +301 -0
- package/src/internal/funding/SourceObservation.ts +267 -0
- package/src/internal/funding/Subsidy.ts +2 -2
- package/src/internal/funding/index.test.ts +1 -0
- package/src/internal/funding/index.ts +1 -0
- package/src/internal/funding/providers/relay.test.ts +94 -4
- package/src/internal/funding/providers/relay.ts +528 -27
- package/dist/apps/data/routes/funding.d.ts.map +0 -1
- package/dist/apps/data/routes/funding.js +0 -1557
- package/dist/apps/data/routes/funding.js.map +0 -1
- package/src/apps/data/routes/funding.test.ts +0 -2994
- package/src/apps/data/routes/funding.ts +0 -1821
|
@@ -1,13 +1,45 @@
|
|
|
1
|
-
import { Address, Hash, Hex } from 'ox';
|
|
1
|
+
import { AbiEvent, AbiFunction, Address, Hash, Hex, RpcTransport } from 'ox';
|
|
2
|
+
import { createClient, custom, fallback } from 'viem';
|
|
3
|
+
import { getBlockNumber, getLogs, getTransaction, getTransactionReceipt } from 'viem/actions';
|
|
2
4
|
import * as z from 'zod/mini';
|
|
3
5
|
import * as Db from '../../../db/Db.js';
|
|
4
6
|
import * as FundingDepositAddresses from '../../../db/tables/fundingDepositAddresses.js';
|
|
7
|
+
import * as FundingDepositRequestObservations from '../../../db/tables/fundingDepositRequestObservations.js';
|
|
8
|
+
import * as Viem from '../../Viem.js';
|
|
9
|
+
import * as FundingCatalog from '../Catalog.js';
|
|
5
10
|
import * as FundingChain from '../Chain.js';
|
|
11
|
+
import * as Evidence from '../Evidence.js';
|
|
6
12
|
import * as FundingProvider from '../Provider.js';
|
|
7
13
|
import * as Subsidy from '../Subsidy.js';
|
|
8
14
|
const defaultBaseUrl = 'https://api.relay.link';
|
|
9
15
|
const defaultFetch = (input, init) => globalThis.fetch(input, init);
|
|
10
|
-
const
|
|
16
|
+
const deliveryBackfillBlocks = 256n;
|
|
17
|
+
const relayChainsCacheTtlMs = 60_000;
|
|
18
|
+
const sourceSweepForwardBlocks = 256n;
|
|
19
|
+
const depositErc20FullAllowance = AbiFunction.from('function depositErc20(address depositor,address token,bytes32 id)');
|
|
20
|
+
const depositErc20WithAmount = AbiFunction.from('function depositErc20(address depositor,address token,uint256 amount,bytes32 id)');
|
|
21
|
+
const relayErc20DepositEvent = AbiEvent.from('event RelayErc20Deposit(address from, address token, uint256 amount, bytes32 id)');
|
|
22
|
+
const relayTransfer = AbiFunction.from('function transfer(address recipient,uint256 amount)');
|
|
23
|
+
const transferEvent = AbiEvent.from('event Transfer(address indexed from, address indexed to, uint256 value)');
|
|
24
|
+
const webhookSignatureToleranceMs = 300_000;
|
|
25
|
+
const deliveryObservationStatuses = [
|
|
26
|
+
'depositing',
|
|
27
|
+
'pending',
|
|
28
|
+
'submitted',
|
|
29
|
+
'success',
|
|
30
|
+
'waiting',
|
|
31
|
+
];
|
|
32
|
+
// Bound provider statuses before using them as metric tags.
|
|
33
|
+
const webhookStatuses = [
|
|
34
|
+
'depositing',
|
|
35
|
+
'failure',
|
|
36
|
+
'fallback',
|
|
37
|
+
'pending',
|
|
38
|
+
'refund',
|
|
39
|
+
'submitted',
|
|
40
|
+
'success',
|
|
41
|
+
'waiting',
|
|
42
|
+
];
|
|
11
43
|
var schema;
|
|
12
44
|
(function (schema) {
|
|
13
45
|
const Decimal = z.union([
|
|
@@ -67,8 +99,35 @@ var schema;
|
|
|
67
99
|
requestId: z.optional(z.string()),
|
|
68
100
|
})),
|
|
69
101
|
});
|
|
102
|
+
schema.Chains = z.object({
|
|
103
|
+
chains: z.array(z.object({
|
|
104
|
+
id: Integer,
|
|
105
|
+
protocol: z.optional(z.object({
|
|
106
|
+
v2: z.optional(z.object({
|
|
107
|
+
depository: z.string().check(z.regex(/^0x[0-9a-fA-F]{40}$/)),
|
|
108
|
+
})),
|
|
109
|
+
})),
|
|
110
|
+
solverAddresses: z.optional(z.array(z.string().check(z.regex(/^0x[0-9a-fA-F]{40}$/)))),
|
|
111
|
+
})),
|
|
112
|
+
});
|
|
113
|
+
schema.DeliveryObservation = z.object({
|
|
114
|
+
relay: z.object({
|
|
115
|
+
orderId: z.string().check(z.regex(/^0x[0-9a-fA-F]{64}$/)),
|
|
116
|
+
sourceDepository: z.string().check(z.regex(/^0x[0-9a-fA-F]{40}$/)),
|
|
117
|
+
sourceObservedAt: z.iso.datetime(),
|
|
118
|
+
sourceSweepTransactionHash: z.string().check(z.regex(/^0x[0-9a-fA-F]{64}$/)),
|
|
119
|
+
}),
|
|
120
|
+
});
|
|
121
|
+
schema.RequestCorrelation = z.object({
|
|
122
|
+
relay: z.object({
|
|
123
|
+
depositor: z.optional(z.string().check(z.regex(/^0x[0-9a-fA-F]{40}$/))),
|
|
124
|
+
depository: z.optional(z.string().check(z.regex(/^0x[0-9a-fA-F]{40}$/))),
|
|
125
|
+
orderId: z.optional(z.string().check(z.regex(/^0x[0-9a-fA-F]{64}$/))),
|
|
126
|
+
solver: z.optional(z.string().check(z.regex(/^0x[0-9a-fA-F]{40}$/))),
|
|
127
|
+
}),
|
|
128
|
+
});
|
|
70
129
|
const RequestTransaction = z.object({
|
|
71
|
-
|
|
130
|
+
txHash: z.string().check(z.minLength(1)),
|
|
72
131
|
});
|
|
73
132
|
schema.Requests = z.object({
|
|
74
133
|
continuation: z.optional(z.string().check(z.minLength(1))),
|
|
@@ -77,10 +136,22 @@ var schema;
|
|
|
77
136
|
data: z.optional(z.object({
|
|
78
137
|
outTxs: z.optional(z.array(RequestTransaction)),
|
|
79
138
|
})),
|
|
80
|
-
depositAddress: z.optional(z.object({
|
|
81
|
-
depositTxHash: z.optional(z.string().check(z.minLength(1))),
|
|
82
|
-
})),
|
|
139
|
+
depositAddress: z.optional(z.nullable(z.object({
|
|
140
|
+
depositTxHash: z.optional(z.nullable(z.string().check(z.minLength(1)))),
|
|
141
|
+
}))),
|
|
83
142
|
id: z.string().check(z.minLength(1)),
|
|
143
|
+
protocol: z.optional(z.nullable(z.object({
|
|
144
|
+
deposit: z.optional(z.object({
|
|
145
|
+
origin: z.optional(z.object({
|
|
146
|
+
depositor: z.optional(z.string().check(z.regex(/^0x[0-9a-fA-F]{40}$/))),
|
|
147
|
+
depository: z.optional(z.string().check(z.regex(/^0x[0-9a-fA-F]{40}$/))),
|
|
148
|
+
})),
|
|
149
|
+
})),
|
|
150
|
+
orderId: z.optional(z.string().check(z.regex(/^0x[0-9a-fA-F]{64}$/))),
|
|
151
|
+
solver: z.optional(z.object({
|
|
152
|
+
address: z.optional(z.string().check(z.regex(/^0x[0-9a-fA-F]{40}$/))),
|
|
153
|
+
})),
|
|
154
|
+
}))),
|
|
84
155
|
status: z.string().check(z.minLength(1)),
|
|
85
156
|
updatedAt: z.iso.datetime(),
|
|
86
157
|
})),
|
|
@@ -89,10 +160,19 @@ var schema;
|
|
|
89
160
|
data: z.object({
|
|
90
161
|
depositAddress: z.nullable(z.object({ address: z.string().check(z.minLength(1)) })),
|
|
91
162
|
requestId: z.optional(z.string().check(z.minLength(1))),
|
|
163
|
+
status: z.string().check(z.minLength(1)),
|
|
164
|
+
updatedAt: z.number().check(z.int(), z.nonnegative()),
|
|
92
165
|
}),
|
|
93
166
|
event: z.literal('request.status.updated'),
|
|
94
167
|
});
|
|
95
168
|
})(schema || (schema = {}));
|
|
169
|
+
/** Validates a Relay request-list response and reports payload drift with field-level details. */
|
|
170
|
+
export function parseDepositAddressRequests(value) {
|
|
171
|
+
const parsed = schema.Requests.safeParse(value);
|
|
172
|
+
if (!parsed.success)
|
|
173
|
+
throw new FundingProvider.ProviderPayloadError(z.prettifyError(parsed.error));
|
|
174
|
+
return parsed.data;
|
|
175
|
+
}
|
|
96
176
|
/** Creates a Relay funding provider backed by `/quote/v2`. */
|
|
97
177
|
export function relay(options = {}) {
|
|
98
178
|
if ((options.userAddress !== undefined &&
|
|
@@ -103,6 +183,15 @@ export function relay(options = {}) {
|
|
|
103
183
|
const endpoint = quoteEndpoint(options);
|
|
104
184
|
const fetch = options.fetch ?? defaultFetch;
|
|
105
185
|
const now = options.now ?? (() => new Date());
|
|
186
|
+
const observeDepositAddressRequest = options.observation
|
|
187
|
+
? createDepositAddressObserver({
|
|
188
|
+
...options.observation,
|
|
189
|
+
...(options.apiKey ? { apiKey: options.apiKey } : {}),
|
|
190
|
+
...(options.baseUrl ? { baseUrl: options.baseUrl } : {}),
|
|
191
|
+
fetch,
|
|
192
|
+
now,
|
|
193
|
+
})
|
|
194
|
+
: undefined;
|
|
106
195
|
const webhook = (() => {
|
|
107
196
|
if (!options.apiKey || !options.webhook)
|
|
108
197
|
return undefined;
|
|
@@ -110,6 +199,7 @@ export function relay(options = {}) {
|
|
|
110
199
|
const verify = (input) => verifyWebhook(webhookOptions(input, apiKey));
|
|
111
200
|
return {
|
|
112
201
|
async receive(input) {
|
|
202
|
+
const receivedAt = now().toISOString();
|
|
113
203
|
const hint = (() => {
|
|
114
204
|
try {
|
|
115
205
|
return verify(input);
|
|
@@ -125,7 +215,8 @@ export function relay(options = {}) {
|
|
|
125
215
|
webhook.onResult?.('ignored');
|
|
126
216
|
return { type: 'ignored' };
|
|
127
217
|
}
|
|
128
|
-
const
|
|
218
|
+
const database = Db.get(webhook.db);
|
|
219
|
+
const address = await FundingDepositAddresses.getByProviderAddress(database, {
|
|
129
220
|
address: hint.address,
|
|
130
221
|
providerId: 'relay',
|
|
131
222
|
});
|
|
@@ -133,11 +224,33 @@ export function relay(options = {}) {
|
|
|
133
224
|
webhook.onResult?.('unknown_address');
|
|
134
225
|
return { type: 'unknown_address' };
|
|
135
226
|
}
|
|
227
|
+
if (hint.requestId)
|
|
228
|
+
await FundingDepositRequestObservations.observeWebhook(database, {
|
|
229
|
+
depositAddressId: address.id,
|
|
230
|
+
providerRequestId: hint.requestId,
|
|
231
|
+
receivedAt,
|
|
232
|
+
}).catch((cause) => {
|
|
233
|
+
webhook.onResult?.('observation_failed');
|
|
234
|
+
throw cause;
|
|
235
|
+
});
|
|
136
236
|
try {
|
|
237
|
+
const webhookTiming = (() => {
|
|
238
|
+
if (!hint.providerStatus || !hint.providerUpdatedAt || !hint.requestId || !hint.sentAt)
|
|
239
|
+
return undefined;
|
|
240
|
+
return {
|
|
241
|
+
enqueuedAt: now().toISOString(),
|
|
242
|
+
providerStatus: hint.providerStatus,
|
|
243
|
+
providerUpdatedAt: hint.providerUpdatedAt,
|
|
244
|
+
receivedAt,
|
|
245
|
+
sentAt: hint.sentAt,
|
|
246
|
+
};
|
|
247
|
+
})();
|
|
137
248
|
await webhook.dispatch({
|
|
138
249
|
addressId: address.id,
|
|
139
250
|
...(hint.requestId ? { requestId: hint.requestId } : {}),
|
|
251
|
+
trigger: 'webhook',
|
|
140
252
|
type: 'funding:deposit-address:reconcile',
|
|
253
|
+
...(webhookTiming ? { webhookTiming } : {}),
|
|
141
254
|
});
|
|
142
255
|
}
|
|
143
256
|
catch (cause) {
|
|
@@ -280,10 +393,9 @@ export function relay(options = {}) {
|
|
|
280
393
|
const requestUrl = requestsEndpoint(options);
|
|
281
394
|
if (requestId)
|
|
282
395
|
requestUrl.searchParams.set('id', requestId);
|
|
283
|
-
else
|
|
396
|
+
else
|
|
284
397
|
requestUrl.searchParams.set('depositAddress', address);
|
|
285
|
-
|
|
286
|
-
}
|
|
398
|
+
requestUrl.searchParams.set('includeChildRequests', 'true');
|
|
287
399
|
requestUrl.searchParams.set('limit', '50');
|
|
288
400
|
requestUrl.searchParams.set('sortBy', 'updatedAt');
|
|
289
401
|
requestUrl.searchParams.set('sortDirection', 'desc');
|
|
@@ -295,23 +407,43 @@ export function relay(options = {}) {
|
|
|
295
407
|
method: 'GET',
|
|
296
408
|
signal,
|
|
297
409
|
});
|
|
298
|
-
const parsed =
|
|
299
|
-
if (!parsed.success)
|
|
300
|
-
throw new FundingProvider.ProviderPayloadError();
|
|
410
|
+
const parsed = parseDepositAddressRequests(response);
|
|
301
411
|
return {
|
|
302
|
-
...(parsed.
|
|
303
|
-
requests: parsed.
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
412
|
+
...(parsed.continuation ? { continuation: parsed.continuation } : {}),
|
|
413
|
+
requests: parsed.requests.map((request) => {
|
|
414
|
+
const correlation = (() => {
|
|
415
|
+
const { protocol } = request;
|
|
416
|
+
if (!protocol)
|
|
417
|
+
return undefined;
|
|
418
|
+
const relay = {
|
|
419
|
+
...(protocol.deposit?.origin?.depositor
|
|
420
|
+
? { depositor: protocol.deposit.origin.depositor }
|
|
421
|
+
: {}),
|
|
422
|
+
...(protocol.deposit?.origin?.depository
|
|
423
|
+
? { depository: protocol.deposit.origin.depository }
|
|
424
|
+
: {}),
|
|
425
|
+
...(protocol.orderId ? { orderId: protocol.orderId } : {}),
|
|
426
|
+
...(protocol.solver?.address ? { solver: protocol.solver.address } : {}),
|
|
427
|
+
};
|
|
428
|
+
if (Object.keys(relay).length === 0)
|
|
429
|
+
return undefined;
|
|
430
|
+
return schema.RequestCorrelation.parse({ relay });
|
|
431
|
+
})();
|
|
432
|
+
return {
|
|
433
|
+
createdAt: new Date(request.createdAt).toISOString(),
|
|
434
|
+
destinationTransactionHashes: request.data?.outTxs?.map((tx) => tx.txHash) ?? [],
|
|
435
|
+
id: request.id,
|
|
436
|
+
...(correlation ? { providerState: correlation } : {}),
|
|
437
|
+
sourceTransactionHashes: request.depositAddress?.depositTxHash
|
|
438
|
+
? [request.depositAddress.depositTxHash]
|
|
439
|
+
: [],
|
|
440
|
+
status: request.status,
|
|
441
|
+
updatedAt: new Date(request.updatedAt).toISOString(),
|
|
442
|
+
};
|
|
443
|
+
}),
|
|
313
444
|
};
|
|
314
445
|
},
|
|
446
|
+
...(observeDepositAddressRequest ? { observeDepositAddressRequest } : {}),
|
|
315
447
|
async prepareTransfer({ candidate, method, mode, recipient, sender, slippageBps }, signal) {
|
|
316
448
|
// Catalog capabilities gate deposit addresses and exact destination
|
|
317
449
|
// off this adapter; refuse them defensively if one slips through.
|
|
@@ -390,12 +522,273 @@ export function relay(options = {}) {
|
|
|
390
522
|
},
|
|
391
523
|
});
|
|
392
524
|
}
|
|
525
|
+
function createDepositAddressObserver(options) {
|
|
526
|
+
let chainsExpiresAt = 0;
|
|
527
|
+
let chainsPromise;
|
|
528
|
+
let urlsExpiresAt = 0;
|
|
529
|
+
let urlsPromise;
|
|
530
|
+
const getChains = (signal) => {
|
|
531
|
+
if (chainsPromise && options.now().getTime() < chainsExpiresAt)
|
|
532
|
+
return chainsPromise;
|
|
533
|
+
chainsExpiresAt = options.now().getTime() + relayChainsCacheTtlMs;
|
|
534
|
+
chainsPromise = FundingProvider.requestJson(chainsEndpoint(options), {
|
|
535
|
+
fetch: options.fetch,
|
|
536
|
+
headers: options.apiKey ? { 'x-api-key': options.apiKey } : undefined,
|
|
537
|
+
signal,
|
|
538
|
+
})
|
|
539
|
+
.then((value) => schema.Chains.parse(value).chains)
|
|
540
|
+
.catch((cause) => {
|
|
541
|
+
chainsExpiresAt = 0;
|
|
542
|
+
chainsPromise = undefined;
|
|
543
|
+
throw cause;
|
|
544
|
+
});
|
|
545
|
+
return chainsPromise;
|
|
546
|
+
};
|
|
547
|
+
const getUrls = () => {
|
|
548
|
+
if (urlsPromise && options.now().getTime() < urlsExpiresAt)
|
|
549
|
+
return urlsPromise;
|
|
550
|
+
urlsExpiresAt = options.now().getTime() + relayChainsCacheTtlMs;
|
|
551
|
+
urlsPromise = FundingCatalog.read(Db.get(options.db))
|
|
552
|
+
.then((catalog) => new Map([...catalog.chainsByKey.values()].map((chain) => [
|
|
553
|
+
chain.id,
|
|
554
|
+
Evidence.resolveRpcUrls({
|
|
555
|
+
chain,
|
|
556
|
+
defaultChainId: options.defaultChainId ?? Viem.defaultChainId,
|
|
557
|
+
rpcUrlEnv: options.rpcUrlEnv,
|
|
558
|
+
}),
|
|
559
|
+
])))
|
|
560
|
+
.catch((cause) => {
|
|
561
|
+
urlsExpiresAt = 0;
|
|
562
|
+
urlsPromise = undefined;
|
|
563
|
+
throw cause;
|
|
564
|
+
});
|
|
565
|
+
return urlsPromise;
|
|
566
|
+
};
|
|
567
|
+
return async (parameters, signal) => {
|
|
568
|
+
if (!deliveryObservationStatuses.includes(parameters.request.status))
|
|
569
|
+
return { type: 'unsupported' };
|
|
570
|
+
if (parameters.sourceChain.kind !== 'evm' || parameters.destinationChain.kind !== 'evm')
|
|
571
|
+
return { type: 'unsupported' };
|
|
572
|
+
if (!Address.validate(parameters.address, { strict: false }) ||
|
|
573
|
+
!Address.validate(parameters.destinationToken.address, { strict: false }) ||
|
|
574
|
+
!Address.validate(parameters.recipient, { strict: false }) ||
|
|
575
|
+
!Address.validate(parameters.refundAddress, { strict: false }) ||
|
|
576
|
+
!Address.validate(parameters.sourceToken.address, { strict: false }) ||
|
|
577
|
+
!Hash.validate(parameters.source.transactionHash))
|
|
578
|
+
return { type: 'unsupported' };
|
|
579
|
+
const [chains, urls] = await Promise.all([getChains(signal), getUrls()]);
|
|
580
|
+
const sourceChain = relayEvmChain(chains, parameters.sourceChain);
|
|
581
|
+
const destinationChain = relayEvmChain(chains, parameters.destinationChain);
|
|
582
|
+
const sourceUrls = urls.get(parameters.sourceChain.id);
|
|
583
|
+
const destinationUrls = urls.get(parameters.destinationChain.id);
|
|
584
|
+
const depository = sourceChain?.protocol?.v2?.depository;
|
|
585
|
+
const solvers = destinationChain?.solverAddresses;
|
|
586
|
+
if (!depository ||
|
|
587
|
+
!solvers ||
|
|
588
|
+
solvers.length === 0 ||
|
|
589
|
+
!sourceUrls?.length ||
|
|
590
|
+
!destinationUrls?.length)
|
|
591
|
+
return { type: 'unsupported' };
|
|
592
|
+
const parsedCorrelation = schema.RequestCorrelation.safeParse(parameters.request.providerState);
|
|
593
|
+
const correlation = parsedCorrelation.success ? parsedCorrelation.data.relay : undefined;
|
|
594
|
+
if ((correlation?.depository &&
|
|
595
|
+
!Address.isEqual(correlation.depository, depository)) ||
|
|
596
|
+
(correlation?.solver &&
|
|
597
|
+
!solvers.some((solver) => Address.isEqual(solver, correlation.solver))))
|
|
598
|
+
return { type: 'unsupported' };
|
|
599
|
+
const depositor = (correlation?.depositor ?? parameters.refundAddress);
|
|
600
|
+
const stored = schema.DeliveryObservation.safeParse(parameters.providerState);
|
|
601
|
+
const sourceObservation = await (async () => {
|
|
602
|
+
if (stored.success)
|
|
603
|
+
return stored.data.relay;
|
|
604
|
+
const sourceClient = jsonRpcClient({ fetch: options.fetch, urls: sourceUrls });
|
|
605
|
+
const sourceReceipt = await getTransactionReceipt(sourceClient, {
|
|
606
|
+
hash: parameters.source.transactionHash,
|
|
607
|
+
});
|
|
608
|
+
if (sourceReceipt.status !== 'success' || sourceReceipt.blockNumber === null)
|
|
609
|
+
return undefined;
|
|
610
|
+
const sourceHead = await getBlockNumber(sourceClient, { cacheTime: 0 });
|
|
611
|
+
const sweepLogs = await getLogs(sourceClient, {
|
|
612
|
+
address: depository,
|
|
613
|
+
event: relayErc20DepositEvent,
|
|
614
|
+
fromBlock: sourceReceipt.blockNumber,
|
|
615
|
+
toBlock: minimum(sourceHead, sourceReceipt.blockNumber + sourceSweepForwardBlocks),
|
|
616
|
+
});
|
|
617
|
+
const observations = [];
|
|
618
|
+
for (const log of sweepLogs) {
|
|
619
|
+
if (!log.transactionHash)
|
|
620
|
+
continue;
|
|
621
|
+
const event = decodeEvent(relayErc20DepositEvent, log);
|
|
622
|
+
if (!event ||
|
|
623
|
+
!Address.isEqual(event.from, depositor) ||
|
|
624
|
+
!Address.isEqual(event.token, parameters.sourceToken.address) ||
|
|
625
|
+
event.amount !== BigInt(parameters.source.amount) ||
|
|
626
|
+
(correlation?.orderId && !Hex.isEqual(event.id, correlation.orderId)))
|
|
627
|
+
continue;
|
|
628
|
+
const transaction = await getTransaction(sourceClient, { hash: log.transactionHash });
|
|
629
|
+
const call = decodeRelayErc20Deposit(transaction.input);
|
|
630
|
+
if (!call ||
|
|
631
|
+
!Address.isEqual(transaction.from, parameters.address) ||
|
|
632
|
+
!transaction.to ||
|
|
633
|
+
!Address.isEqual(transaction.to, depository) ||
|
|
634
|
+
!Address.isEqual(call.depositor, event.from) ||
|
|
635
|
+
!Address.isEqual(call.token, event.token) ||
|
|
636
|
+
(call.amount !== undefined && call.amount !== event.amount) ||
|
|
637
|
+
!Hex.isEqual(call.id, event.id))
|
|
638
|
+
continue;
|
|
639
|
+
observations.push({
|
|
640
|
+
orderId: event.id,
|
|
641
|
+
sourceDepository: depository,
|
|
642
|
+
sourceObservedAt: options.now().toISOString(),
|
|
643
|
+
sourceSweepTransactionHash: log.transactionHash,
|
|
644
|
+
});
|
|
645
|
+
}
|
|
646
|
+
return observations.length === 1 ? observations[0] : undefined;
|
|
647
|
+
})();
|
|
648
|
+
if (!sourceObservation)
|
|
649
|
+
return { type: 'pending' };
|
|
650
|
+
const destinationClient = jsonRpcClient({ fetch: options.fetch, urls: destinationUrls });
|
|
651
|
+
const destinationHead = await getBlockNumber(destinationClient, { cacheTime: 0 });
|
|
652
|
+
const destinationLogs = await getLogs(destinationClient, {
|
|
653
|
+
address: parameters.destinationToken.address,
|
|
654
|
+
args: { to: parameters.recipient },
|
|
655
|
+
event: transferEvent,
|
|
656
|
+
fromBlock: destinationHead > deliveryBackfillBlocks ? destinationHead - deliveryBackfillBlocks : 0n,
|
|
657
|
+
toBlock: destinationHead,
|
|
658
|
+
});
|
|
659
|
+
const solverAddresses = (correlation?.solver ? [correlation.solver] : solvers).map((address) => address);
|
|
660
|
+
const correlatedTransactionHashes = [];
|
|
661
|
+
const uncorrelatedTransactionHashes = [];
|
|
662
|
+
for (const log of destinationLogs) {
|
|
663
|
+
if (!log.transactionHash ||
|
|
664
|
+
correlatedTransactionHashes.includes(log.transactionHash) ||
|
|
665
|
+
uncorrelatedTransactionHashes.includes(log.transactionHash))
|
|
666
|
+
continue;
|
|
667
|
+
const event = decodeEvent(transferEvent, log);
|
|
668
|
+
if (!event ||
|
|
669
|
+
event.value === 0n ||
|
|
670
|
+
!Address.isEqual(event.to, parameters.recipient) ||
|
|
671
|
+
!solverAddresses.some((address) => Address.isEqual(address, event.from)))
|
|
672
|
+
continue;
|
|
673
|
+
const transaction = await getTransaction(destinationClient, { hash: log.transactionHash });
|
|
674
|
+
const call = decodeRelayTransfer(transaction.input);
|
|
675
|
+
if (!call ||
|
|
676
|
+
!solverAddresses.some((address) => Address.isEqual(address, transaction.from)) ||
|
|
677
|
+
!Address.isEqual(event.from, transaction.from) ||
|
|
678
|
+
!transaction.to ||
|
|
679
|
+
!Address.isEqual(transaction.to, parameters.destinationToken.address) ||
|
|
680
|
+
!Address.isEqual(call.recipient, event.to) ||
|
|
681
|
+
call.amount !== event.value ||
|
|
682
|
+
(call.orderId && !Hex.isEqual(call.orderId, sourceObservation.orderId)))
|
|
683
|
+
continue;
|
|
684
|
+
if (call.orderId)
|
|
685
|
+
correlatedTransactionHashes.push(log.transactionHash);
|
|
686
|
+
else
|
|
687
|
+
uncorrelatedTransactionHashes.push(log.transactionHash);
|
|
688
|
+
}
|
|
689
|
+
const destinationTransactionHashes = (() => {
|
|
690
|
+
if (correlatedTransactionHashes.length > 0)
|
|
691
|
+
return correlatedTransactionHashes;
|
|
692
|
+
if (uncorrelatedTransactionHashes.length === 1)
|
|
693
|
+
return uncorrelatedTransactionHashes;
|
|
694
|
+
return [];
|
|
695
|
+
})();
|
|
696
|
+
const providerState = { relay: sourceObservation };
|
|
697
|
+
if (destinationTransactionHashes.length === 0)
|
|
698
|
+
return {
|
|
699
|
+
providerState,
|
|
700
|
+
providerTransactionHashes: [sourceObservation.sourceSweepTransactionHash],
|
|
701
|
+
type: 'pending',
|
|
702
|
+
};
|
|
703
|
+
return {
|
|
704
|
+
destinationTransactionHashes,
|
|
705
|
+
providerState: {
|
|
706
|
+
relay: {
|
|
707
|
+
...sourceObservation,
|
|
708
|
+
destinationObservedAt: options.now().toISOString(),
|
|
709
|
+
},
|
|
710
|
+
},
|
|
711
|
+
providerTransactionHashes: [
|
|
712
|
+
sourceObservation.sourceSweepTransactionHash,
|
|
713
|
+
...destinationTransactionHashes,
|
|
714
|
+
],
|
|
715
|
+
type: 'verified',
|
|
716
|
+
};
|
|
717
|
+
};
|
|
718
|
+
}
|
|
719
|
+
function chainsEndpoint(options) {
|
|
720
|
+
const endpoint = new URL(options.baseUrl ?? defaultBaseUrl);
|
|
721
|
+
endpoint.pathname = `${endpoint.pathname.replace(/\/+$/, '')}/chains`;
|
|
722
|
+
return endpoint;
|
|
723
|
+
}
|
|
724
|
+
function decodeRelayErc20Deposit(data) {
|
|
725
|
+
const fullAllowanceLength = 2 + 2 * (4 + 32 * 3);
|
|
726
|
+
const withAmountLength = 2 + 2 * (4 + 32 * 4);
|
|
727
|
+
try {
|
|
728
|
+
if (data.length === withAmountLength) {
|
|
729
|
+
const [depositor, token, amount, id] = AbiFunction.decodeData(depositErc20WithAmount, data);
|
|
730
|
+
return { amount, depositor, id, token };
|
|
731
|
+
}
|
|
732
|
+
if (data.length === fullAllowanceLength) {
|
|
733
|
+
const [depositor, token, id] = AbiFunction.decodeData(depositErc20FullAllowance, data);
|
|
734
|
+
return { depositor, id, token };
|
|
735
|
+
}
|
|
736
|
+
return undefined;
|
|
737
|
+
}
|
|
738
|
+
catch {
|
|
739
|
+
return undefined;
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
function decodeRelayTransfer(data) {
|
|
743
|
+
const encodedLength = 2 + 2 * (4 + 32 * 2);
|
|
744
|
+
if (data.length !== encodedLength && data.length !== encodedLength + 64)
|
|
745
|
+
return undefined;
|
|
746
|
+
try {
|
|
747
|
+
const [recipient, amount] = AbiFunction.decodeData(relayTransfer, data.slice(0, encodedLength));
|
|
748
|
+
return {
|
|
749
|
+
amount,
|
|
750
|
+
...(data.length > encodedLength
|
|
751
|
+
? { orderId: `0x${data.slice(encodedLength)}` }
|
|
752
|
+
: {}),
|
|
753
|
+
recipient,
|
|
754
|
+
};
|
|
755
|
+
}
|
|
756
|
+
catch {
|
|
757
|
+
return undefined;
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
function decodeEvent(abiEvent, log) {
|
|
761
|
+
try {
|
|
762
|
+
return AbiEvent.decode(abiEvent, log);
|
|
763
|
+
}
|
|
764
|
+
catch {
|
|
765
|
+
return undefined;
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
function jsonRpcClient(options) {
|
|
769
|
+
return createClient({
|
|
770
|
+
transport: fallback(options.urls.map((url) => {
|
|
771
|
+
const transport = RpcTransport.fromHttp(url, { fetchFn: options.fetch });
|
|
772
|
+
return custom(transport, { retryCount: 0 });
|
|
773
|
+
})),
|
|
774
|
+
});
|
|
775
|
+
}
|
|
776
|
+
function minimum(left, right) {
|
|
777
|
+
return left < right ? left : right;
|
|
778
|
+
}
|
|
779
|
+
function relayEvmChain(chains, chain) {
|
|
780
|
+
if (chain.kind !== 'evm')
|
|
781
|
+
return undefined;
|
|
782
|
+
const match = /^eip155:(\d+)$/.exec(chain.id);
|
|
783
|
+
if (!match?.[1])
|
|
784
|
+
return undefined;
|
|
785
|
+
return chains.find((candidate) => candidate.id === Number(match[1]));
|
|
786
|
+
}
|
|
393
787
|
function verifyWebhook(options) {
|
|
394
788
|
const timestamp = Number(options.timestamp);
|
|
395
789
|
if (!Number.isSafeInteger(timestamp))
|
|
396
790
|
throw new WebhookSignatureError();
|
|
397
|
-
|
|
398
|
-
if (Math.abs(now - timestamp) > webhookSignatureToleranceSeconds)
|
|
791
|
+
if (Math.abs(Date.now() - timestamp) > webhookSignatureToleranceMs)
|
|
399
792
|
throw new WebhookSignatureError();
|
|
400
793
|
if (!/^[0-9a-fA-F]{64}$/.test(options.signature))
|
|
401
794
|
throw new WebhookSignatureError();
|
|
@@ -415,7 +808,10 @@ function verifyWebhook(options) {
|
|
|
415
808
|
throw new WebhookPayloadError();
|
|
416
809
|
return {
|
|
417
810
|
address: parsed.data.data.depositAddress?.address,
|
|
811
|
+
providerStatus: webhookStatus(parsed.data.data.status),
|
|
812
|
+
providerUpdatedAt: webhookTimestamp(parsed.data.data.updatedAt),
|
|
418
813
|
requestId: parsed.data.data.requestId,
|
|
814
|
+
sentAt: webhookTimestamp(timestamp),
|
|
419
815
|
};
|
|
420
816
|
}
|
|
421
817
|
function webhookOptions(input, secret) {
|
|
@@ -432,7 +828,7 @@ function quoteEndpoint(options) {
|
|
|
432
828
|
}
|
|
433
829
|
function requestsEndpoint(options) {
|
|
434
830
|
const endpoint = new URL(options.baseUrl ?? defaultBaseUrl);
|
|
435
|
-
endpoint.pathname = `${endpoint.pathname.replace(/\/+$/, '')}/requests/
|
|
831
|
+
endpoint.pathname = `${endpoint.pathname.replace(/\/+$/, '')}/requests/v3`;
|
|
436
832
|
return endpoint;
|
|
437
833
|
}
|
|
438
834
|
function timingSafeEqual(left, right) {
|
|
@@ -443,6 +839,17 @@ function timingSafeEqual(left, right) {
|
|
|
443
839
|
mismatch |= left.charCodeAt(index) ^ right.charCodeAt(index);
|
|
444
840
|
return mismatch === 0;
|
|
445
841
|
}
|
|
842
|
+
function webhookStatus(status) {
|
|
843
|
+
return webhookStatuses.includes(status) ? status : 'unknown';
|
|
844
|
+
}
|
|
845
|
+
function webhookTimestamp(value) {
|
|
846
|
+
try {
|
|
847
|
+
return new Date(value).toISOString();
|
|
848
|
+
}
|
|
849
|
+
catch {
|
|
850
|
+
throw new WebhookPayloadError();
|
|
851
|
+
}
|
|
852
|
+
}
|
|
446
853
|
function relayChainId(chain) {
|
|
447
854
|
if (chain.id.startsWith('eip155:'))
|
|
448
855
|
return Number(FundingChain.eip155Id(chain));
|