tapimo 0.5.2 → 0.6.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/dist/App.d.ts +13987 -5755
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js.map +1 -1
- package/dist/admin/App.d.ts +910 -412
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/App.js +4 -0
- package/dist/admin/App.js.map +1 -1
- package/dist/admin/apps/early-access.d.ts +148 -0
- package/dist/admin/apps/early-access.d.ts.map +1 -0
- package/dist/admin/apps/early-access.js +133 -0
- package/dist/admin/apps/early-access.js.map +1 -0
- package/dist/admin/apps/verified-tokens.d.ts +643 -118
- package/dist/admin/apps/verified-tokens.d.ts.map +1 -1
- package/dist/admin/apps/verified-tokens.js +214 -1
- package/dist/admin/apps/verified-tokens.js.map +1 -1
- package/dist/admin/ui.generated.d.ts +1 -1
- package/dist/admin/ui.generated.d.ts.map +1 -1
- package/dist/admin/ui.generated.js +45 -33
- package/dist/admin/ui.generated.js.map +1 -1
- package/dist/apps/data/App.d.ts +3733 -2428
- package/dist/apps/data/App.d.ts.map +1 -1
- package/dist/apps/data/App.js +11 -6
- package/dist/apps/data/App.js.map +1 -1
- package/dist/apps/data/FundingQuoteProviders.d.ts +34 -1
- package/dist/apps/data/FundingQuoteProviders.d.ts.map +1 -1
- package/dist/apps/data/FundingQuoteProviders.js +193 -2
- package/dist/apps/data/FundingQuoteProviders.js.map +1 -1
- package/dist/apps/data/FxOracle.d.ts +71 -0
- package/dist/apps/data/FxOracle.d.ts.map +1 -0
- package/dist/apps/data/FxOracle.js +97 -0
- package/dist/apps/data/FxOracle.js.map +1 -0
- package/dist/apps/data/index.d.ts +1 -0
- package/dist/apps/data/index.d.ts.map +1 -1
- package/dist/apps/data/index.js +1 -0
- package/dist/apps/data/index.js.map +1 -1
- package/dist/apps/data/routes/activities.d.ts +3575 -1358
- package/dist/apps/data/routes/activities.d.ts.map +1 -1
- package/dist/apps/data/routes/activities.js +230 -88
- package/dist/apps/data/routes/activities.js.map +1 -1
- package/dist/apps/data/routes/addresses.d.ts +963 -342
- package/dist/apps/data/routes/addresses.d.ts.map +1 -1
- package/dist/apps/data/routes/addresses.js +11 -9
- package/dist/apps/data/routes/addresses.js.map +1 -1
- package/dist/apps/data/routes/balances.d.ts +108 -57
- package/dist/apps/data/routes/balances.d.ts.map +1 -1
- package/dist/apps/data/routes/balances.js +88 -45
- package/dist/apps/data/routes/balances.js.map +1 -1
- package/dist/apps/data/routes/coingecko.d.ts +169 -169
- package/dist/apps/data/routes/exchanges.d.ts +952 -201
- package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
- package/dist/apps/data/routes/exchanges.js +518 -76
- package/dist/apps/data/routes/exchanges.js.map +1 -1
- package/dist/apps/data/routes/fee-amm.d.ts +24 -24
- package/dist/apps/data/routes/funding.d.ts +8 -2
- package/dist/apps/data/routes/funding.d.ts.map +1 -1
- package/dist/apps/data/routes/funding.js +32 -6
- package/dist/apps/data/routes/funding.js.map +1 -1
- package/dist/apps/data/routes/indexer.d.ts +5 -5
- package/dist/apps/data/routes/receipts.d.ts +392 -315
- package/dist/apps/data/routes/receipts.d.ts.map +1 -1
- package/dist/apps/data/routes/receipts.js +152 -77
- package/dist/apps/data/routes/receipts.js.map +1 -1
- package/dist/apps/data/routes/tokens.d.ts +166 -173
- package/dist/apps/data/routes/tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/tokens.js +14 -12
- package/dist/apps/data/routes/tokens.js.map +1 -1
- package/dist/apps/data/routes/transactions.d.ts +277 -536
- package/dist/apps/data/routes/transactions.d.ts.map +1 -1
- package/dist/apps/data/routes/transactions.js +96 -77
- package/dist/apps/data/routes/transactions.js.map +1 -1
- package/dist/apps/data/routes/transfers.d.ts +82 -17
- package/dist/apps/data/routes/transfers.d.ts.map +1 -1
- package/dist/apps/data/routes/transfers.js +70 -13
- package/dist/apps/data/routes/transfers.js.map +1 -1
- package/dist/apps/data/routes/valuation.d.ts +307 -0
- package/dist/apps/data/routes/valuation.d.ts.map +1 -0
- package/dist/apps/data/routes/valuation.js +292 -0
- package/dist/apps/data/routes/valuation.js.map +1 -0
- package/dist/apps/data/routes/verified-tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/verified-tokens.js +7 -5
- package/dist/apps/data/routes/verified-tokens.js.map +1 -1
- package/dist/apps/data/routes/webhooks.d.ts +459 -479
- package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/data/routes/webhooks.js +124 -25
- package/dist/apps/data/routes/webhooks.js.map +1 -1
- package/dist/apps/index.d.ts +1 -1
- package/dist/apps/index.d.ts.map +1 -1
- package/dist/apps/index.js +1 -1
- package/dist/apps/index.js.map +1 -1
- package/dist/apps/management/App.d.ts +8606 -1681
- package/dist/apps/management/App.d.ts.map +1 -1
- package/dist/apps/management/App.js +12 -1
- package/dist/apps/management/App.js.map +1 -1
- package/dist/apps/management/routes/api-keys.d.ts +23 -0
- package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
- package/dist/apps/management/routes/api-keys.js +5 -3
- package/dist/apps/management/routes/api-keys.js.map +1 -1
- package/dist/apps/management/routes/billing.d.ts +88 -48
- package/dist/apps/management/routes/billing.d.ts.map +1 -1
- package/dist/apps/management/routes/billing.js +10 -2
- package/dist/apps/management/routes/billing.js.map +1 -1
- package/dist/apps/management/routes/faucet.d.ts +218 -0
- package/dist/apps/management/routes/faucet.d.ts.map +1 -0
- package/dist/apps/management/routes/faucet.js +139 -0
- package/dist/apps/management/routes/faucet.js.map +1 -0
- package/dist/apps/management/routes/invitations.d.ts +121 -121
- package/dist/apps/management/routes/invitations.d.ts.map +1 -1
- package/dist/apps/management/routes/invitations.js +3 -0
- package/dist/apps/management/routes/invitations.js.map +1 -1
- package/dist/apps/management/routes/invite-links.d.ts +197 -168
- package/dist/apps/management/routes/invite-links.d.ts.map +1 -1
- package/dist/apps/management/routes/invite-links.js +26 -1
- package/dist/apps/management/routes/invite-links.js.map +1 -1
- package/dist/apps/management/routes/me.d.ts +2 -0
- package/dist/apps/management/routes/me.d.ts.map +1 -1
- package/dist/apps/management/routes/me.js +4 -0
- package/dist/apps/management/routes/me.js.map +1 -1
- package/dist/apps/management/routes/members.d.ts +49 -49
- package/dist/apps/management/routes/orgs.d.ts +91 -91
- package/dist/apps/management/routes/projects.d.ts +115 -115
- package/dist/apps/management/routes/usage.d.ts +35 -32
- package/dist/apps/management/routes/usage.d.ts.map +1 -1
- package/dist/apps/management/routes/usage.js +4 -0
- package/dist/apps/management/routes/usage.js.map +1 -1
- package/dist/apps/management/routes/verified-token-requests.d.ts +697 -0
- package/dist/apps/management/routes/verified-token-requests.d.ts.map +1 -0
- package/dist/apps/management/routes/verified-token-requests.js +271 -0
- package/dist/apps/management/routes/verified-token-requests.js.map +1 -0
- package/dist/apps/management/routes/webhooks.d.ts +6977 -0
- package/dist/apps/management/routes/webhooks.d.ts.map +1 -0
- package/dist/apps/management/routes/webhooks.js +573 -0
- package/dist/apps/management/routes/webhooks.js.map +1 -0
- package/dist/apps/mcp.d.ts +9 -2
- package/dist/apps/mcp.d.ts.map +1 -1
- package/dist/apps/mcp.js +9 -4
- package/dist/apps/mcp.js.map +1 -1
- package/dist/cli/Cli.d.ts.map +1 -1
- package/dist/cli/Cli.js +7 -2
- package/dist/cli/Cli.js.map +1 -1
- package/dist/db/Db.d.ts +4 -0
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +83 -0
- package/dist/db/Db.js.map +1 -1
- package/dist/db/Schema.d.ts +41 -0
- package/dist/db/Schema.d.ts.map +1 -1
- package/dist/db/Schema.js +45 -0
- package/dist/db/Schema.js.map +1 -1
- package/dist/db/tables/earlyAccess.d.ts +50 -0
- package/dist/db/tables/earlyAccess.d.ts.map +1 -0
- package/dist/db/tables/earlyAccess.js +63 -0
- package/dist/db/tables/earlyAccess.js.map +1 -0
- package/dist/db/tables/invitations.d.ts +12 -1
- package/dist/db/tables/invitations.d.ts.map +1 -1
- package/dist/db/tables/invitations.js +23 -0
- package/dist/db/tables/invitations.js.map +1 -1
- package/dist/db/tables/inviteLinks.d.ts +10 -2
- package/dist/db/tables/inviteLinks.d.ts.map +1 -1
- package/dist/db/tables/inviteLinks.js +10 -1
- package/dist/db/tables/inviteLinks.js.map +1 -1
- package/dist/db/tables/sponsoredTransactions.d.ts +2 -0
- package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
- package/dist/db/tables/sponsoredTransactions.js +2 -0
- package/dist/db/tables/sponsoredTransactions.js.map +1 -1
- package/dist/db/tables/verifiedTokenRequests.d.ts +94 -0
- package/dist/db/tables/verifiedTokenRequests.d.ts.map +1 -0
- package/dist/db/tables/verifiedTokenRequests.js +120 -0
- package/dist/db/tables/verifiedTokenRequests.js.map +1 -0
- package/dist/db/tables/webhookSubscriptions.d.ts +14 -0
- package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
- package/dist/db/tables/webhookSubscriptions.js +16 -0
- package/dist/db/tables/webhookSubscriptions.js.map +1 -1
- package/dist/internal/Auth.d.ts +43 -2
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +60 -45
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/FundingQuotes.d.ts +69 -15
- package/dist/internal/FundingQuotes.d.ts.map +1 -1
- package/dist/internal/FundingQuotes.js +74 -25
- package/dist/internal/FundingQuotes.js.map +1 -1
- package/dist/internal/Log.d.ts +19 -1
- package/dist/internal/Log.d.ts.map +1 -1
- package/dist/internal/Log.js +2 -0
- package/dist/internal/Log.js.map +1 -1
- package/dist/internal/MetricSink.d.ts.map +1 -1
- package/dist/internal/MetricSink.js +9 -0
- package/dist/internal/MetricSink.js.map +1 -1
- package/dist/internal/OpenApi.d.ts +2 -2
- package/dist/internal/OpenApi.d.ts.map +1 -1
- package/dist/internal/OpenApi.js +3 -0
- package/dist/internal/OpenApi.js.map +1 -1
- package/dist/internal/Schema.d.ts +14 -5
- package/dist/internal/Schema.d.ts.map +1 -1
- package/dist/internal/Schema.js +23 -5
- package/dist/internal/Schema.js.map +1 -1
- package/dist/internal/Value.d.ts +18 -0
- package/dist/internal/Value.d.ts.map +1 -1
- package/dist/internal/Value.js +11 -1
- package/dist/internal/Value.js.map +1 -1
- package/dist/internal/VerifiedTokens.d.ts.map +1 -1
- package/dist/internal/VerifiedTokens.js +10 -1
- package/dist/internal/VerifiedTokens.js.map +1 -1
- package/dist/internal/Viem.d.ts +1 -1
- package/dist/internal/Webhooks.d.ts +24 -3
- package/dist/internal/Webhooks.d.ts.map +1 -1
- package/dist/internal/Webhooks.js +34 -8
- package/dist/internal/Webhooks.js.map +1 -1
- package/package.json +2 -2
- package/src/App.ts +9 -1
- package/src/Client.test-d.ts +638 -6
- package/src/admin/App.ts +4 -0
- package/src/admin/apps/early-access.test.ts +125 -0
- package/src/admin/apps/early-access.ts +175 -0
- package/src/admin/apps/verified-tokens.test.ts +201 -0
- package/src/admin/apps/verified-tokens.ts +532 -286
- package/src/admin/ui/plugin.ts +2 -1
- package/src/admin/ui/src/lib/early-access.ts +63 -0
- package/src/admin/ui/src/lib/verified-tokens.ts +79 -0
- package/src/admin/ui/src/routeTree.gen.ts +33 -2
- package/src/admin/ui/src/routes/__root.tsx +2 -1
- package/src/admin/ui/src/routes/early-access.tsx +157 -0
- package/src/admin/ui/src/routes/verified-tokens.tsx +230 -19
- package/src/admin/ui.generated.ts +48 -33
- package/src/apps/data/App.ts +22 -14
- package/src/apps/data/FundingQuoteProviders.test.ts +298 -0
- package/src/apps/data/FundingQuoteProviders.ts +257 -4
- package/src/apps/data/FxOracle.test.ts +118 -0
- package/src/apps/data/FxOracle.ts +153 -0
- package/src/apps/data/index.ts +1 -0
- package/src/apps/data/routes/activities.test.ts +173 -3
- package/src/apps/data/routes/activities.ts +403 -132
- package/src/apps/data/routes/addresses.ts +19 -9
- package/src/apps/data/routes/balances.test.ts +144 -11
- package/src/apps/data/routes/balances.ts +140 -51
- package/src/apps/data/routes/exchanges.test.ts +540 -9
- package/src/apps/data/routes/exchanges.ts +690 -103
- package/src/apps/data/routes/funding.test.ts +84 -0
- package/src/apps/data/routes/funding.ts +38 -6
- package/src/apps/data/routes/receipts.test.ts +125 -23
- package/src/apps/data/routes/receipts.ts +205 -100
- package/src/apps/data/routes/tokens.test.ts +43 -0
- package/src/apps/data/routes/tokens.ts +27 -12
- package/src/apps/data/routes/transactions.test.ts +72 -19
- package/src/apps/data/routes/transactions.ts +162 -92
- package/src/apps/data/routes/transfers.test.ts +146 -4
- package/src/apps/data/routes/transfers.ts +91 -13
- package/src/apps/data/routes/valuation.test.ts +422 -0
- package/src/apps/data/routes/valuation.ts +423 -0
- package/src/apps/data/routes/verified-tokens.ts +14 -2
- package/src/apps/data/routes/webhooks.test.ts +56 -8
- package/src/apps/data/routes/webhooks.ts +144 -27
- package/src/apps/index.ts +1 -1
- package/src/apps/management/App.ts +13 -0
- package/src/apps/management/routes/api-keys.test.ts +87 -0
- package/src/apps/management/routes/api-keys.ts +4 -3
- package/src/apps/management/routes/billing.test.ts +112 -1
- package/src/apps/management/routes/billing.ts +7 -2
- package/src/apps/management/routes/faucet.test.ts +79 -0
- package/src/apps/management/routes/faucet.ts +185 -0
- package/src/apps/management/routes/invitations.test.ts +172 -0
- package/src/apps/management/routes/invitations.ts +3 -0
- package/src/apps/management/routes/invite-links.test.ts +117 -0
- package/src/apps/management/routes/invite-links.ts +43 -1
- package/src/apps/management/routes/me.test.ts +140 -88
- package/src/apps/management/routes/me.ts +6 -0
- package/src/apps/management/routes/usage.test.ts +6 -0
- package/src/apps/management/routes/usage.ts +7 -0
- package/src/apps/management/routes/verified-token-requests.test.ts +377 -0
- package/src/apps/management/routes/verified-token-requests.ts +397 -0
- package/src/apps/management/routes/webhooks.test.ts +426 -0
- package/src/apps/management/routes/webhooks.ts +672 -0
- package/src/apps/mcp.test.ts +13 -0
- package/src/apps/mcp.ts +18 -5
- package/src/cli/Cli.test.ts +36 -0
- package/src/cli/Cli.ts +7 -2
- package/src/db/Db.test.ts +19 -0
- package/src/db/Db.ts +95 -0
- package/src/db/Schema.ts +53 -0
- package/src/db/tables/earlyAccess.ts +86 -0
- package/src/db/tables/invitations.ts +26 -1
- package/src/db/tables/inviteLinks.ts +22 -3
- package/src/db/tables/sponsoredTransactions.ts +4 -0
- package/src/db/tables/verifiedTokenRequests.test.ts +200 -0
- package/src/db/tables/verifiedTokenRequests.ts +182 -0
- package/src/db/tables/webhookSubscriptions.ts +31 -0
- package/src/internal/Auth.ts +73 -45
- package/src/internal/FundingQuotes.test.ts +143 -1
- package/src/internal/FundingQuotes.ts +95 -28
- package/src/internal/Log.test-d.ts +21 -0
- package/src/internal/Log.test.ts +50 -0
- package/src/internal/Log.ts +24 -1
- package/src/internal/MetricSink.test.ts +160 -0
- package/src/internal/MetricSink.ts +10 -0
- package/src/internal/OpenApi.ts +3 -0
- package/src/internal/Schema.ts +50 -5
- package/src/internal/Value.test.ts +20 -0
- package/src/internal/Value.ts +24 -1
- package/src/internal/VerifiedTokens.ts +9 -1
- package/src/internal/Webhooks.test.ts +140 -0
- package/src/internal/Webhooks.ts +53 -9
|
@@ -14,14 +14,13 @@ import * as Store from '../../../internal/Store.js'
|
|
|
14
14
|
import * as Timing from '../../../internal/Timing.js'
|
|
15
15
|
import * as Ttl from '../../../internal/Ttl.js'
|
|
16
16
|
import * as Value from '../../../internal/Value.js'
|
|
17
|
+
import * as FxOracle from '../FxOracle.js'
|
|
17
18
|
import * as Tokens from './tokens.js'
|
|
19
|
+
import * as Transactions from './transactions.js'
|
|
20
|
+
import * as Valuation from './valuation.js'
|
|
18
21
|
|
|
19
|
-
// Receipts and transactions
|
|
20
|
-
//
|
|
21
|
-
// receipts). Neither module may touch the other's exports during module
|
|
22
|
-
// evaluation: schema references across the cycle must stay inside `z.lazy`, and
|
|
23
|
-
// function references are call-time only.
|
|
24
|
-
import { decodeTransactionType, embedFeeTokens, schema as txSchema } from './transactions.js'
|
|
22
|
+
// Receipts and transactions import each other. Cross-module schemas stay lazy,
|
|
23
|
+
// while function references resolve at call time.
|
|
25
24
|
|
|
26
25
|
/** Example transaction hash surfaced in OpenAPI docs. */
|
|
27
26
|
const exampleHash = '0x515801d7f9a5ac705e793e85904c9c69b3f1694b465cc8fb6ba3f0298dc82665'
|
|
@@ -33,7 +32,7 @@ const exampleHash = '0x515801d7f9a5ac705e793e85904c9c69b3f1694b465cc8fb6ba3f0298
|
|
|
33
32
|
*/
|
|
34
33
|
function computeFeeAmount(gasUsed: number | undefined, effectiveGasPrice: string | undefined) {
|
|
35
34
|
if (gasUsed === undefined || effectiveGasPrice === undefined) return undefined
|
|
36
|
-
return Fees.fromGas(BigInt(gasUsed), BigInt(effectiveGasPrice))
|
|
35
|
+
return Fees.fromGas(BigInt(gasUsed), BigInt(effectiveGasPrice))
|
|
37
36
|
}
|
|
38
37
|
|
|
39
38
|
/** Zod schemas owned by the receipt handlers. */
|
|
@@ -187,28 +186,39 @@ export namespace schema {
|
|
|
187
186
|
.check(z.describe('The transaction receipt exactly as returned by JSON-RPC.'))
|
|
188
187
|
}
|
|
189
188
|
|
|
190
|
-
/**
|
|
191
|
-
* Metadata for a receipt: the verbatim JSON-RPC receipt (always present) plus
|
|
192
|
-
* resources embedded on demand via `include`.
|
|
193
|
-
*/
|
|
189
|
+
/** Receipt metadata containing valuation provenance and the verbatim JSON-RPC receipt. */
|
|
194
190
|
export const ReceiptMeta = z
|
|
195
191
|
.object({
|
|
196
|
-
|
|
197
|
-
.optional(
|
|
198
|
-
.check(
|
|
192
|
+
pricing: z
|
|
193
|
+
.optional(Valuation.schema.Pricing)
|
|
194
|
+
.check(
|
|
195
|
+
z.describe(
|
|
196
|
+
'Rate provenance for the fee valuation. Present when conversion rates were consulted.',
|
|
197
|
+
),
|
|
198
|
+
),
|
|
199
199
|
rpc: Rpc.Receipt.check(z.describe('The original JSON-RPC receipt payload.')),
|
|
200
200
|
})
|
|
201
|
+
.check(z.describe('Metadata for this receipt, including pricing and the JSON-RPC payload.'))
|
|
202
|
+
|
|
203
|
+
/** The fee charged to the fee payer, carrying its value in the requested denomination. */
|
|
204
|
+
export const FeeAmount = z
|
|
205
|
+
.extend(Schema.TokenAmount, {
|
|
206
|
+
valuation: z
|
|
207
|
+
.optional(z.nullable(Valuation.schema.Value))
|
|
208
|
+
.check(
|
|
209
|
+
z.describe(
|
|
210
|
+
'The fee’s nominal value in the requested `denomination`. `null` when rates were unavailable.',
|
|
211
|
+
),
|
|
212
|
+
),
|
|
213
|
+
})
|
|
201
214
|
.check(
|
|
202
|
-
z.describe(
|
|
203
|
-
'Metadata for this receipt: the original JSON-RPC payload plus any requested `include` resources.',
|
|
204
|
-
),
|
|
215
|
+
z.describe('The fee charged to the fee payer, with its value in the requested denomination.'),
|
|
205
216
|
)
|
|
206
217
|
|
|
207
218
|
/**
|
|
208
219
|
* A humanized transaction receipt: decoded `status`/`type`, plain-number gas
|
|
209
|
-
* and block fields, and decimal-string
|
|
210
|
-
* are surfaced
|
|
211
|
-
* `meta.rpc`.
|
|
220
|
+
* and block fields, a structured fee amount, and a decimal-string gas price.
|
|
221
|
+
* The raw event logs are surfaced under `logs`, and the RPC receipt under `meta.rpc`.
|
|
212
222
|
*/
|
|
213
223
|
export const Receipt = z
|
|
214
224
|
.object({
|
|
@@ -245,19 +255,15 @@ export namespace schema {
|
|
|
245
255
|
effectiveGasPrice: Schema.DecimalString.check(
|
|
246
256
|
z.describe('Effective gas price paid for this transaction, in attodollars per gas.'),
|
|
247
257
|
),
|
|
248
|
-
feeAmount:
|
|
249
|
-
z.describe(
|
|
250
|
-
'Fee charged to the fee payer, as a decimal integer string in the fee token’s base units.',
|
|
251
|
-
),
|
|
252
|
-
),
|
|
258
|
+
feeAmount: FeeAmount.check(z.describe('Fee charged to the fee payer, denominated in USD.')),
|
|
253
259
|
feePayer: z
|
|
254
260
|
.optional(Schema.Address)
|
|
255
261
|
.check(z.describe('The address that paid the transaction fee.')),
|
|
256
262
|
feeToken: z
|
|
257
|
-
.optional(
|
|
263
|
+
.optional(z.lazy(() => Tokens.schema.TokenReference))
|
|
258
264
|
.check(
|
|
259
265
|
z.describe(
|
|
260
|
-
'The token used to pay the fee
|
|
266
|
+
'The token used to pay the fee, with RPC metadata and optional curated fields.',
|
|
261
267
|
),
|
|
262
268
|
),
|
|
263
269
|
gasUsed: z
|
|
@@ -277,7 +283,7 @@ export namespace schema {
|
|
|
277
283
|
z.describe('Event logs emitted by this transaction, returned in JSON-RPC log format.'),
|
|
278
284
|
),
|
|
279
285
|
meta: ReceiptMeta.check(
|
|
280
|
-
z.describe('
|
|
286
|
+
z.describe('Receipt metadata containing pricing provenance and the JSON-RPC payload.'),
|
|
281
287
|
),
|
|
282
288
|
recipient: z
|
|
283
289
|
.nullable(Schema.Address)
|
|
@@ -312,7 +318,9 @@ export namespace schema {
|
|
|
312
318
|
z.describe('The transaction position within its block.'),
|
|
313
319
|
z.meta({ examples: [0] }),
|
|
314
320
|
),
|
|
315
|
-
type: z
|
|
321
|
+
type: z
|
|
322
|
+
.lazy(() => Transactions.schema.TransactionType)
|
|
323
|
+
.check(z.meta({ examples: ['eip1559'] })),
|
|
316
324
|
})
|
|
317
325
|
.check(
|
|
318
326
|
z.describe(
|
|
@@ -334,25 +342,25 @@ export namespace schema {
|
|
|
334
342
|
})
|
|
335
343
|
.check(z.describe('Path parameters used to look up a receipt by transaction hash.'))
|
|
336
344
|
|
|
337
|
-
/** Optional
|
|
345
|
+
/** Optional curated token fields that callers opt into via `include`. */
|
|
338
346
|
export const Include = z
|
|
339
|
-
.enum(['feeToken'])
|
|
340
|
-
.check(z.describe('
|
|
347
|
+
.enum(['feeToken.logoUri', 'feeToken.verified'])
|
|
348
|
+
.check(z.describe('Additional fee-token fields you can request with `include`.'))
|
|
341
349
|
|
|
342
350
|
/**
|
|
343
351
|
* Parses a comma-separated `include` query value into a list of optional
|
|
344
|
-
*
|
|
345
|
-
* explicitly requested, keeping the base receipt response fast.
|
|
352
|
+
* token fields to embed. Curated lookups only run when explicitly requested.
|
|
346
353
|
*/
|
|
347
354
|
export const includeQuery = Schema.includeQuery(
|
|
348
355
|
Include,
|
|
349
|
-
'Comma-separated
|
|
356
|
+
'Comma-separated fee-token fields to include, such as `feeToken.logoUri,feeToken.verified`.',
|
|
350
357
|
)
|
|
351
358
|
|
|
352
359
|
/** Query parameters for receipt requests. */
|
|
353
360
|
export const Query = z
|
|
354
361
|
.strictObject({
|
|
355
362
|
chainId: Schema.ChainIdQuery,
|
|
363
|
+
denomination: Schema.Denomination,
|
|
356
364
|
include: includeQuery,
|
|
357
365
|
})
|
|
358
366
|
.check(z.describe('Query parameters for looking up a receipt.'))
|
|
@@ -363,13 +371,9 @@ export namespace schema {
|
|
|
363
371
|
|
|
364
372
|
/** Schemas for the getReceipts (list) operation. */
|
|
365
373
|
export namespace getReceipts {
|
|
366
|
-
/**
|
|
367
|
-
* Optional resources for the receipt list: the per-row `feeToken` embed
|
|
368
|
-
* plus the response-wide capped `totalCount`. The detail route keeps its
|
|
369
|
-
* own `feeToken`-only {@link getReceipt.Include}.
|
|
370
|
-
*/
|
|
374
|
+
/** Optional fee-token fields and response-wide count metadata. */
|
|
371
375
|
export const Include = z
|
|
372
|
-
.enum(['feeToken', 'totalCount'])
|
|
376
|
+
.enum(['feeToken.logoUri', 'feeToken.verified', 'totalCount'])
|
|
373
377
|
.check(
|
|
374
378
|
z.describe('Related resources to include in each receipt row or in response metadata.'),
|
|
375
379
|
)
|
|
@@ -377,7 +381,7 @@ export namespace schema {
|
|
|
377
381
|
/** Parses the comma-separated `include` value for the receipt list. */
|
|
378
382
|
export const includeQuery = Schema.includeQuery(
|
|
379
383
|
Include,
|
|
380
|
-
'Comma-separated
|
|
384
|
+
'Comma-separated resources to include, such as `feeToken.logoUri,feeToken.verified,totalCount`.',
|
|
381
385
|
)
|
|
382
386
|
|
|
383
387
|
/** Query parameters for receipt list requests. */
|
|
@@ -394,6 +398,7 @@ export namespace schema {
|
|
|
394
398
|
'blockNumber.to': Schema.blockNumberBound('receipts', 'to'),
|
|
395
399
|
chainId: Schema.ChainIdQuery,
|
|
396
400
|
cursor: Schema.Cursor,
|
|
401
|
+
denomination: Schema.Denomination,
|
|
397
402
|
feePayer: z
|
|
398
403
|
.optional(Schema.Address)
|
|
399
404
|
.check(z.describe('Filter to receipts whose transaction fee was paid by this address.')),
|
|
@@ -430,14 +435,28 @@ export namespace schema {
|
|
|
430
435
|
* which stores neither the block hash nor the event logs, so those fields are
|
|
431
436
|
* `null`/empty in the list `meta.rpc` payload.
|
|
432
437
|
*/
|
|
438
|
+
/** Page-level resources: opt-in counts plus valuation rate provenance. */
|
|
439
|
+
export const Meta = z
|
|
440
|
+
.object({
|
|
441
|
+
pricing: z
|
|
442
|
+
.optional(Valuation.schema.Pricing)
|
|
443
|
+
.check(
|
|
444
|
+
z.describe(
|
|
445
|
+
'Rate provenance for fee valuations. Present when conversion rates were ' +
|
|
446
|
+
'consulted; absent when every value was identity-valued or rates were unavailable.',
|
|
447
|
+
),
|
|
448
|
+
),
|
|
449
|
+
totalCount: z.optional(Schema.TotalCount),
|
|
450
|
+
totalCountCapped: z.optional(Schema.TotalCountCapped),
|
|
451
|
+
})
|
|
452
|
+
.check(z.describe('Page-level resources attached to this response.'))
|
|
453
|
+
|
|
433
454
|
export const Response = z
|
|
434
455
|
.object({
|
|
435
456
|
data: z.array(getReceipt.Response).check(z.describe('Receipts on this page.')),
|
|
436
457
|
meta: z
|
|
437
|
-
.optional(
|
|
438
|
-
.check(
|
|
439
|
-
z.describe('Response-level metadata requested with `include`, such as `totalCount`.'),
|
|
440
|
-
),
|
|
458
|
+
.optional(Meta)
|
|
459
|
+
.check(z.describe('Page-level resources: opt-in counts and valuation rate provenance.')),
|
|
441
460
|
nextCursor: Schema.NextCursor,
|
|
442
461
|
})
|
|
443
462
|
.check(z.describe('A page of receipts ordered by block number and transaction position.'))
|
|
@@ -445,7 +464,8 @@ export namespace schema {
|
|
|
445
464
|
}
|
|
446
465
|
|
|
447
466
|
/** Creates receipt handlers. */
|
|
448
|
-
export function receipts() {
|
|
467
|
+
export function receipts(options: receipts.Options = {}) {
|
|
468
|
+
const oracle = options.fx?.oracle ?? FxOracle.ecb()
|
|
449
469
|
return new Hono<App.Environment>()
|
|
450
470
|
.get(
|
|
451
471
|
'/v1/transactions/receipts',
|
|
@@ -459,7 +479,7 @@ export function receipts() {
|
|
|
459
479
|
'List transaction receipts across Tempo, with filters for addresses, blocks, timestamps, fees, and status.',
|
|
460
480
|
operationId: 'getReceipts',
|
|
461
481
|
responses: OpenApi.responses({
|
|
462
|
-
errors: { 502: 'Could not read
|
|
482
|
+
errors: { 502: 'Could not read receipt or token data from an upstream service.' },
|
|
463
483
|
success: {
|
|
464
484
|
description: 'A page of transaction receipts.',
|
|
465
485
|
schema: schema.getReceipts.Response,
|
|
@@ -484,9 +504,8 @@ export function receipts() {
|
|
|
484
504
|
const query = c.req.valid('query')
|
|
485
505
|
const chainId = query.chainId ?? c.get('chainId')
|
|
486
506
|
|
|
487
|
-
// Cursor pages
|
|
488
|
-
|
|
489
|
-
if (query.cursor !== undefined) Cache.setPolicy(c, Cache.policies.immutable)
|
|
507
|
+
// Cursor pages carry current fee valuations and curated verification data.
|
|
508
|
+
if (query.cursor !== undefined) Cache.setPolicy(c, Cache.policies.metadata)
|
|
490
509
|
|
|
491
510
|
try {
|
|
492
511
|
// `totalCount` is opt-in and shares the page's filters; run it
|
|
@@ -516,7 +535,10 @@ export function receipts() {
|
|
|
516
535
|
feeToken: query.feeToken,
|
|
517
536
|
fromBlock: query['blockNumber.from'],
|
|
518
537
|
fromTimestamp: query['timestamp.from'],
|
|
519
|
-
include: query.include.
|
|
538
|
+
include: query.include.filter(
|
|
539
|
+
(resource): resource is z.output<typeof schema.getReceipt.Include> =>
|
|
540
|
+
resource !== 'totalCount',
|
|
541
|
+
),
|
|
520
542
|
limit: query.limit,
|
|
521
543
|
order: query.order,
|
|
522
544
|
page: query.page,
|
|
@@ -527,15 +549,43 @@ export function receipts() {
|
|
|
527
549
|
toTimestamp: query['timestamp.to'],
|
|
528
550
|
})
|
|
529
551
|
|
|
530
|
-
|
|
552
|
+
// Value each fee via its own currency tag, in the requested
|
|
553
|
+
// denomination.
|
|
554
|
+
const denomination = query.denomination ?? 'USD'
|
|
555
|
+
const rates = await Valuation.ratesFor(c, {
|
|
556
|
+
currencies: receipts.data.map((receipt) => receipt.feeAmount.currency),
|
|
557
|
+
denomination,
|
|
558
|
+
oracle,
|
|
559
|
+
})
|
|
560
|
+
const data = receipts.data.map((receipt) => ({
|
|
561
|
+
...receipt,
|
|
562
|
+
feeAmount: {
|
|
563
|
+
...receipt.feeAmount,
|
|
564
|
+
valuation: Valuation.valuationFor({
|
|
565
|
+
amount: BigInt(receipt.feeAmount.baseUnits),
|
|
566
|
+
denomination,
|
|
567
|
+
rates,
|
|
568
|
+
token: receipt.feeAmount,
|
|
569
|
+
}),
|
|
570
|
+
},
|
|
571
|
+
}))
|
|
572
|
+
|
|
573
|
+
const counts = countPromise ? await countPromise : undefined
|
|
574
|
+
const meta = {
|
|
575
|
+
...(rates ? { pricing: Valuation.pricing(rates, oracle) } : {}),
|
|
576
|
+
...counts,
|
|
577
|
+
}
|
|
531
578
|
return c.json(
|
|
532
579
|
Response.validated(schema.getReceipts.Response, {
|
|
533
|
-
|
|
534
|
-
...(meta ? { meta } : {}),
|
|
580
|
+
data,
|
|
581
|
+
...(Object.keys(meta).length > 0 ? { meta } : {}),
|
|
582
|
+
nextCursor: receipts.nextCursor,
|
|
535
583
|
}),
|
|
536
584
|
200,
|
|
537
585
|
)
|
|
538
586
|
} catch (cause) {
|
|
587
|
+
if (cause instanceof Valuation.UnsupportedDenominationError)
|
|
588
|
+
return Response.error(c, { code: 'query_invalid', message: cause.message, status: 400 })
|
|
539
589
|
return Response.upstream(c, cause)
|
|
540
590
|
}
|
|
541
591
|
},
|
|
@@ -560,7 +610,7 @@ export function receipts() {
|
|
|
560
610
|
description: 'No receipt was found for that transaction hash.',
|
|
561
611
|
codes: ['receipt_not_found'],
|
|
562
612
|
},
|
|
563
|
-
502: 'Could not read receipt data from
|
|
613
|
+
502: 'Could not read receipt or token data from upstream JSON-RPC.',
|
|
564
614
|
},
|
|
565
615
|
success: {
|
|
566
616
|
description: 'A single transaction receipt with status, gas, fees, and logs.',
|
|
@@ -571,11 +621,8 @@ export function receipts() {
|
|
|
571
621
|
tags: ['Transactions'],
|
|
572
622
|
}),
|
|
573
623
|
Cache.response<App.Environment>({
|
|
574
|
-
//
|
|
575
|
-
//
|
|
576
|
-
// pending 200. Default to no-store so the 404 isn't cached with a
|
|
577
|
-
// long-lived header (which would mask the receipt once mined); the handler
|
|
578
|
-
// unconditionally upgrades the 200 to `immutable` below.
|
|
624
|
+
// Default to no-store so a 404 does not mask the eventual mined receipt.
|
|
625
|
+
// Successful responses use the metadata policy for current valuations.
|
|
579
626
|
cacheControl: Cache.policies.noStore,
|
|
580
627
|
name: 'tempo-api:receipts:v1',
|
|
581
628
|
key: (c) => Cache.urlKey(c, schema.getReceipt.Query),
|
|
@@ -619,50 +666,73 @@ export function receipts() {
|
|
|
619
666
|
|
|
620
667
|
const data = humanizeReceipt(Response.validated(schema.Rpc.Receipt, rpc))
|
|
621
668
|
|
|
622
|
-
//
|
|
623
|
-
|
|
624
|
-
Cache.setPolicy(c, Cache.policies.immutable)
|
|
669
|
+
// Mined receipts still carry current valuations and verification data.
|
|
670
|
+
Cache.setPolicy(c, Cache.policies.metadata)
|
|
625
671
|
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
672
|
+
const [enriched] = await enrichReceipts(c, {
|
|
673
|
+
chainId,
|
|
674
|
+
include: query.include,
|
|
675
|
+
receipts: [data],
|
|
676
|
+
})
|
|
677
|
+
if (!enriched) throw new Error('Unable to enrich transaction receipt')
|
|
632
678
|
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
679
|
+
// Value the fee via its own currency tag, in the requested
|
|
680
|
+
// denomination.
|
|
681
|
+
const denomination = query.denomination ?? 'USD'
|
|
682
|
+
const rates = await Valuation.ratesFor(c, {
|
|
683
|
+
currencies: [enriched.feeAmount.currency],
|
|
684
|
+
denomination,
|
|
685
|
+
oracle,
|
|
686
|
+
})
|
|
687
|
+
const valued = {
|
|
688
|
+
...enriched,
|
|
689
|
+
feeAmount: {
|
|
690
|
+
...enriched.feeAmount,
|
|
691
|
+
valuation: Valuation.valuationFor({
|
|
692
|
+
amount: BigInt(enriched.feeAmount.baseUnits),
|
|
693
|
+
denomination,
|
|
694
|
+
rates,
|
|
695
|
+
token: enriched.feeAmount,
|
|
696
|
+
}),
|
|
697
|
+
},
|
|
698
|
+
meta: {
|
|
699
|
+
...enriched.meta,
|
|
700
|
+
...(rates ? { pricing: Valuation.pricing(rates, oracle) } : {}),
|
|
701
|
+
},
|
|
702
|
+
}
|
|
703
|
+
return c.json(Response.validated(schema.getReceipt.Response, valued), 200)
|
|
643
704
|
} catch (cause) {
|
|
705
|
+
if (cause instanceof Valuation.UnsupportedDenominationError)
|
|
706
|
+
return Response.error(c, { code: 'query_invalid', message: cause.message, status: 400 })
|
|
644
707
|
return Response.upstream(c, cause)
|
|
645
708
|
}
|
|
646
709
|
},
|
|
647
710
|
)
|
|
648
711
|
}
|
|
649
712
|
|
|
713
|
+
export declare namespace receipts {
|
|
714
|
+
/** Options for the receipt handlers. */
|
|
715
|
+
type Options = {
|
|
716
|
+
/** FX configuration backing fee valuation. */
|
|
717
|
+
fx?: Valuation.addresses.Fx | undefined
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
|
|
650
721
|
/**
|
|
651
|
-
* Lists humanized receipts
|
|
652
|
-
* `feeToken`).
|
|
722
|
+
* Lists humanized receipts with required fee-token metadata and optional curated fields.
|
|
653
723
|
*/
|
|
654
724
|
export async function listReceipts(c: Context<App.Environment>, options: listReceipts.Options) {
|
|
655
725
|
const { include, ...rest } = options
|
|
656
726
|
const page = await getReceipts(c, rest)
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
: page.data
|
|
660
|
-
|
|
727
|
+
return {
|
|
728
|
+
...page,
|
|
729
|
+
data: await enrichReceipts(c, { chainId: rest.chainId, include, receipts: page.data }),
|
|
730
|
+
}
|
|
661
731
|
}
|
|
662
732
|
|
|
663
733
|
export declare namespace listReceipts {
|
|
664
734
|
type Options = getReceipts.Options & {
|
|
665
|
-
/** Optional
|
|
735
|
+
/** Optional curated fee-token fields to embed. */
|
|
666
736
|
include: readonly z.output<typeof schema.getReceipt.Include>[]
|
|
667
737
|
}
|
|
668
738
|
}
|
|
@@ -825,7 +895,7 @@ export function getReceipts(c: Context<App.Environment>, options: getReceipts.Op
|
|
|
825
895
|
// Reconstruct the RPC shape from the indexed columns, then humanize it
|
|
826
896
|
// through the same path as the detail endpoint so the list and detail
|
|
827
897
|
// responses are identical. Rows that fail to reconstruct are skipped.
|
|
828
|
-
const data:
|
|
898
|
+
const data: humanizeReceipt.Output[] = []
|
|
829
899
|
for (const row of page.rows) {
|
|
830
900
|
const tx = typeof row['tx_hash'] === 'string' ? txByHash.get(row['tx_hash']) : undefined
|
|
831
901
|
const merged = { ...row, fee_token: tx?.feeToken, type: tx?.type }
|
|
@@ -977,8 +1047,8 @@ export async function embedReceipts(
|
|
|
977
1047
|
c: Context<App.Environment>,
|
|
978
1048
|
options: embedReceipts.Options,
|
|
979
1049
|
): Promise<Map<string, z.output<typeof schema.Receipt>>> {
|
|
980
|
-
const { chainId, rows } = options
|
|
981
|
-
const found = new Map<string,
|
|
1050
|
+
const { chainId, include, rows } = options
|
|
1051
|
+
const found = new Map<string, humanizeReceipt.Output>()
|
|
982
1052
|
|
|
983
1053
|
// Only mined rows can have a receipt; their block numbers also feed the
|
|
984
1054
|
// block bound the `logs` lookup requires.
|
|
@@ -989,7 +1059,7 @@ export async function embedReceipts(
|
|
|
989
1059
|
blocks.push(row.blockNumber)
|
|
990
1060
|
hashes.add(row.hash.toLowerCase())
|
|
991
1061
|
}
|
|
992
|
-
if (hashes.size === 0) return
|
|
1062
|
+
if (hashes.size === 0) return new Map()
|
|
993
1063
|
|
|
994
1064
|
const tidx = c.get('getTidx')(chainId)
|
|
995
1065
|
const inList = [...hashes].map((hash) => `'${hash}'`).join(', ')
|
|
@@ -1057,7 +1127,8 @@ export async function embedReceipts(
|
|
|
1057
1127
|
meta: { ...receipt.meta, rpc: { ...receipt.meta.rpc, logs } },
|
|
1058
1128
|
})
|
|
1059
1129
|
}
|
|
1060
|
-
|
|
1130
|
+
const receipts = await enrichReceipts(c, { chainId, include, receipts: [...found.values()] })
|
|
1131
|
+
return new Map(receipts.map((receipt) => [receipt.transactionHash.toLowerCase(), receipt]))
|
|
1061
1132
|
}
|
|
1062
1133
|
|
|
1063
1134
|
const receiptRowByHash = new Map<string, Record<string, unknown>>()
|
|
@@ -1087,7 +1158,8 @@ export async function embedReceipts(
|
|
|
1087
1158
|
})
|
|
1088
1159
|
if (rpc.success) found.set(hash, humanizeReceipt(rpc.data))
|
|
1089
1160
|
}
|
|
1090
|
-
|
|
1161
|
+
const receipts = await enrichReceipts(c, { chainId, include, receipts: [...found.values()] })
|
|
1162
|
+
return new Map(receipts.map((receipt) => [receipt.transactionHash.toLowerCase(), receipt]))
|
|
1091
1163
|
}
|
|
1092
1164
|
|
|
1093
1165
|
export declare namespace embedReceipts {
|
|
@@ -1095,12 +1167,14 @@ export declare namespace embedReceipts {
|
|
|
1095
1167
|
type Options = {
|
|
1096
1168
|
/** Target chain id. */
|
|
1097
1169
|
chainId: z.output<typeof Schema.ChainId>
|
|
1170
|
+
/** Optional curated fee-token fields to embed. */
|
|
1171
|
+
include: readonly string[]
|
|
1098
1172
|
/**
|
|
1099
1173
|
* Pre-fetched humanized receipts for the page (the `status`-filtered
|
|
1100
1174
|
* transactions path). When provided, the receipts query is skipped and only
|
|
1101
1175
|
* the page's event logs are fetched and reattached.
|
|
1102
1176
|
*/
|
|
1103
|
-
receipts?: readonly
|
|
1177
|
+
receipts?: readonly humanizeReceipt.Output[] | undefined
|
|
1104
1178
|
/**
|
|
1105
1179
|
* The page's humanized transaction rows. Typed structurally (rather than as
|
|
1106
1180
|
* the transactions schema output) so this module never touches the
|
|
@@ -1119,18 +1193,37 @@ export declare namespace embedReceipts {
|
|
|
1119
1193
|
}
|
|
1120
1194
|
}
|
|
1121
1195
|
|
|
1196
|
+
/** Resolves required RPC fee-token metadata and optional curated fields for receipts. */
|
|
1197
|
+
export function enrichReceipts(c: Context<App.Environment>, options: enrichReceipts.Options) {
|
|
1198
|
+
return Transactions.enrichFeeTokens(c, {
|
|
1199
|
+
chainId: options.chainId,
|
|
1200
|
+
include: options.include,
|
|
1201
|
+
rows: options.receipts,
|
|
1202
|
+
})
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
export declare namespace enrichReceipts {
|
|
1206
|
+
/** Inputs for enriching humanized receipts. */
|
|
1207
|
+
type Options = {
|
|
1208
|
+
/** Target chain id. */
|
|
1209
|
+
chainId: z.output<typeof Schema.ChainId>
|
|
1210
|
+
/** Optional curated fee-token fields to embed. */
|
|
1211
|
+
include: readonly string[]
|
|
1212
|
+
/** Humanized receipts whose fee token is still an address. */
|
|
1213
|
+
receipts: readonly humanizeReceipt.Output[]
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1122
1217
|
/**
|
|
1123
1218
|
* Humanizes a JSON-RPC transaction receipt: decodes `status`/`type`, converts
|
|
1124
|
-
*
|
|
1219
|
+
* gas price and fee values, converts block fields to numbers, and derives the
|
|
1125
1220
|
* block `timestamp` from the top-level `blockTimestamp` (present when
|
|
1126
1221
|
* reconstructed from the index) or the (shared) per-log timestamp — `null` when
|
|
1127
1222
|
* neither is available. The verbatim payload is preserved under `meta.rpc` and
|
|
1128
1223
|
* the raw logs under `logs`. Shared by the receipt detail (RPC source) and list
|
|
1129
1224
|
* (reconstructed from the indexer) endpoints, so both expose an identical shape.
|
|
1130
1225
|
*/
|
|
1131
|
-
export function humanizeReceipt(
|
|
1132
|
-
rpc: z.output<typeof schema.Rpc.Receipt>,
|
|
1133
|
-
): z.output<typeof schema.Receipt> {
|
|
1226
|
+
export function humanizeReceipt(rpc: z.output<typeof schema.Rpc.Receipt>): humanizeReceipt.Output {
|
|
1134
1227
|
const gasUsed = Value.hexToNumber(rpc.gasUsed) ?? 0
|
|
1135
1228
|
const effectiveGasPrice = Value.fromHex(rpc.effectiveGasPrice) ?? '0'
|
|
1136
1229
|
return {
|
|
@@ -1139,7 +1232,11 @@ export function humanizeReceipt(
|
|
|
1139
1232
|
contractAddress: rpc.contractAddress ?? null,
|
|
1140
1233
|
cumulativeGasUsed: Value.hexToNumber(rpc.cumulativeGasUsed) ?? 0,
|
|
1141
1234
|
effectiveGasPrice,
|
|
1142
|
-
feeAmount:
|
|
1235
|
+
feeAmount: Value.tokenAmount({
|
|
1236
|
+
baseUnits: computeFeeAmount(gasUsed, effectiveGasPrice) ?? 0n,
|
|
1237
|
+
currency: 'USD',
|
|
1238
|
+
decimals: Fees.tokenDecimals,
|
|
1239
|
+
}),
|
|
1143
1240
|
feePayer: rpc.feePayer ?? undefined,
|
|
1144
1241
|
feeToken: rpc.feeToken ?? undefined,
|
|
1145
1242
|
gasUsed,
|
|
@@ -1152,7 +1249,15 @@ export function humanizeReceipt(
|
|
|
1152
1249
|
timestamp: Value.hexSecondsToIso(rpc.blockTimestamp ?? rpc.logs[0]?.blockTimestamp) ?? null,
|
|
1153
1250
|
transactionHash: rpc.transactionHash,
|
|
1154
1251
|
transactionIndex: Value.hexToNumber(rpc.transactionIndex) ?? 0,
|
|
1155
|
-
type: decodeTransactionType(rpc.type),
|
|
1252
|
+
type: Transactions.decodeTransactionType(rpc.type),
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
export declare namespace humanizeReceipt {
|
|
1257
|
+
/** Humanized receipt before its fee-token address is resolved to metadata. */
|
|
1258
|
+
type Output = Omit<z.output<typeof schema.Receipt>, 'feeToken'> & {
|
|
1259
|
+
/** Address of the token used to pay the fee. */
|
|
1260
|
+
feeToken?: z.output<typeof Schema.Address> | undefined
|
|
1156
1261
|
}
|
|
1157
1262
|
}
|
|
1158
1263
|
|
|
@@ -980,6 +980,27 @@ describe('GET /tokens/:symbol', () => {
|
|
|
980
980
|
})
|
|
981
981
|
|
|
982
982
|
describe('GET /tokens/:token/transactions', () => {
|
|
983
|
+
test('parses granular fee-token includes', () => {
|
|
984
|
+
expect(
|
|
985
|
+
Tokens.schema.getTokenTransactions.Query.parse({
|
|
986
|
+
include: 'feeToken.logoUri,feeToken.verified,token,totalCount',
|
|
987
|
+
}).include,
|
|
988
|
+
).toMatchInlineSnapshot(`
|
|
989
|
+
[
|
|
990
|
+
"feeToken.logoUri",
|
|
991
|
+
"feeToken.verified",
|
|
992
|
+
"token",
|
|
993
|
+
"totalCount",
|
|
994
|
+
]
|
|
995
|
+
`)
|
|
996
|
+
expect(
|
|
997
|
+
Tokens.schema.getTokenTransactions.Query.safeParse({ include: 'feeToken' }).success,
|
|
998
|
+
).toBe(false)
|
|
999
|
+
expect(
|
|
1000
|
+
Tokens.schema.getTokenTransactions.Query.safeParse({ include: 'token.logoUri' }).success,
|
|
1001
|
+
).toBe(false)
|
|
1002
|
+
})
|
|
1003
|
+
|
|
983
1004
|
test('returns a transaction page touching the token contract', async () => {
|
|
984
1005
|
const client = app()
|
|
985
1006
|
const response = await client.v1.tokens[':token'].transactions.$get(
|
|
@@ -996,6 +1017,12 @@ describe('GET /tokens/:token/transactions', () => {
|
|
|
996
1017
|
for (const tx of body.data) {
|
|
997
1018
|
const involves = tx.sender === TestApp.token || tx.recipient === TestApp.token
|
|
998
1019
|
expect(involves).toBe(true)
|
|
1020
|
+
if (tx.feeToken) {
|
|
1021
|
+
expect(tx.feeToken.address).toBe(tx.meta.rpc.feeToken)
|
|
1022
|
+
expect(typeof tx.feeToken.symbol).toBe('string')
|
|
1023
|
+
expect(tx.feeToken.logoUri).toBeUndefined()
|
|
1024
|
+
expect(tx.feeToken.verified).toBeUndefined()
|
|
1025
|
+
}
|
|
999
1026
|
}
|
|
1000
1027
|
// Default ordering is newest-first (descending block then in-block index).
|
|
1001
1028
|
const blocks = body.data
|
|
@@ -1006,6 +1033,22 @@ describe('GET /tokens/:token/transactions', () => {
|
|
|
1006
1033
|
expect(body.meta).toBeUndefined()
|
|
1007
1034
|
})
|
|
1008
1035
|
|
|
1036
|
+
test('includes requested fee-token fields', async () => {
|
|
1037
|
+
const client = app()
|
|
1038
|
+
const response = await client.v1.tokens[':token'].transactions.$get(
|
|
1039
|
+
{
|
|
1040
|
+
param: { token: TestApp.token },
|
|
1041
|
+
query: { include: 'feeToken.logoUri,feeToken.verified', limit: '5' },
|
|
1042
|
+
},
|
|
1043
|
+
TestApp.auth,
|
|
1044
|
+
)
|
|
1045
|
+
const body = await TestApp.json(response, Tokens.schema.getTokenTransactions.Response)
|
|
1046
|
+
|
|
1047
|
+
expect(response.status).toBe(200)
|
|
1048
|
+
const withFeeToken = body.data.find((transaction) => transaction.feeToken)
|
|
1049
|
+
if (withFeeToken) expect(typeof withFeeToken.feeToken!.verified).toBe('boolean')
|
|
1050
|
+
})
|
|
1051
|
+
|
|
1009
1052
|
test('embeds a capped total count on demand via include=totalCount', async () => {
|
|
1010
1053
|
const client = app()
|
|
1011
1054
|
const response = await client.v1.tokens[':token'].transactions.$get(
|