tapimo 0.7.2 → 0.9.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 +20117 -19183
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +61 -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 +11 -11
- 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 +11696 -13937
- 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 +271 -271
- package/dist/apps/data/routes/addresses.d.ts +398 -167
- package/dist/apps/data/routes/addresses.d.ts.map +1 -1
- package/dist/apps/data/routes/balances.d.ts +278 -8
- package/dist/apps/data/routes/balances.d.ts.map +1 -1
- package/dist/apps/data/routes/balances.js +114 -2
- package/dist/apps/data/routes/balances.js.map +1 -1
- package/dist/apps/data/routes/blocks.d.ts +123 -123
- package/dist/apps/data/routes/coingecko.d.ts +170 -170
- package/dist/apps/data/routes/earn.d.ts +498 -6
- package/dist/apps/data/routes/earn.d.ts.map +1 -1
- package/dist/apps/data/routes/earn.js +876 -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 +31 -31
- 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 +449 -449
- package/dist/apps/data/routes/transactions.d.ts +2 -2
- package/dist/apps/data/routes/transfers.d.ts +81 -81
- 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} +1640 -3217
- package/dist/apps/funding/App.d.ts.map +1 -0
- package/dist/apps/funding/App.js +61 -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 +1997 -0
- package/dist/apps/funding/routes/deposit-addresses.d.ts.map +1 -0
- package/dist/apps/funding/routes/deposit-addresses.js +778 -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 +122 -122
- 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 +99 -99
- 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 +77 -77
- 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 +44 -44
- 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 +45 -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 +74 -1
- package/dist/db/tables/fundingDeposits.d.ts.map +1 -1
- package/dist/db/tables/fundingDeposits.js +126 -0
- package/dist/db/tables/fundingDeposits.js.map +1 -1
- package/dist/internal/Auth.d.ts +15 -11
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +52 -17
- 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 +348 -54
- 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 +438 -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 +55 -5
- package/src/App.ts +79 -5
- package/src/Client.test-d.ts +203 -28
- 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 +130 -3
- package/src/apps/data/App.test.ts +0 -12
- package/src/apps/data/App.ts +4 -8
- package/src/apps/data/routes/balances.test.ts +42 -0
- package/src/apps/data/routes/balances.ts +218 -85
- package/src/apps/data/routes/earn.test.ts +363 -0
- package/src/apps/data/routes/earn.ts +1141 -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 +78 -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 +1649 -0
- package/src/apps/funding/routes/deposit-addresses.ts +932 -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 +1236 -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 +71 -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 +239 -0
- package/src/db/tables/fundingDeposits.ts +214 -1
- package/src/internal/Auth.test.ts +205 -5
- package/src/internal/Auth.ts +63 -19
- 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 +1364 -109
- package/src/internal/funding/Reconciliation.ts +467 -88
- 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 +533 -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
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import * as NodeBuffer from 'node:buffer'
|
|
2
|
+
|
|
3
|
+
import { AbiEvent } from 'ox'
|
|
4
|
+
|
|
5
|
+
import * as FundingDeposits from '../../db/tables/fundingDeposits.js'
|
|
6
|
+
import * as TestApp from '../../../test/App.js'
|
|
7
|
+
import * as TestFunding from '../../../test/Funding.js'
|
|
8
|
+
import * as TestRelay from '../../../test/Relay.js'
|
|
9
|
+
import * as DepositAddress from './DepositAddress.js'
|
|
10
|
+
import * as Reconciliation from './Reconciliation.js'
|
|
11
|
+
import * as SourceObservation from './SourceObservation.js'
|
|
12
|
+
import * as Relay from './providers/relay.js'
|
|
13
|
+
|
|
14
|
+
const transferEvent = AbiEvent.from(
|
|
15
|
+
'event Transfer(address indexed from, address indexed to, uint256 value)',
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
describe('scan', () => {
|
|
19
|
+
test('finds confirmed transfers into active routes', async () => {
|
|
20
|
+
const route = TestFunding.transferSnapshot()
|
|
21
|
+
const address = `0x${'44'.repeat(20)}`
|
|
22
|
+
const sender = `0x${'55'.repeat(20)}`
|
|
23
|
+
const transactionHash = `0x${'aa'.repeat(32)}`
|
|
24
|
+
const requests: unknown[] = []
|
|
25
|
+
const server = await TestRelay.createServer(async (request, response) => {
|
|
26
|
+
const chunks: Uint8Array[] = []
|
|
27
|
+
for await (const chunk of request) chunks.push(chunk)
|
|
28
|
+
const body = JSON.parse(NodeBuffer.Buffer.concat(chunks).toString()) as {
|
|
29
|
+
id: number
|
|
30
|
+
method: string
|
|
31
|
+
}
|
|
32
|
+
requests.push(body)
|
|
33
|
+
const result =
|
|
34
|
+
body.method === 'eth_blockNumber'
|
|
35
|
+
? '0x10'
|
|
36
|
+
: [
|
|
37
|
+
{
|
|
38
|
+
address: route.sourceToken.address,
|
|
39
|
+
blockHash: `0x${'bb'.repeat(32)}`,
|
|
40
|
+
blockNumber: '0x10',
|
|
41
|
+
data: `0x${1_000_000n.toString(16).padStart(64, '0')}`,
|
|
42
|
+
logIndex: '0x2',
|
|
43
|
+
removed: false,
|
|
44
|
+
topics: [
|
|
45
|
+
AbiEvent.getSelector(transferEvent),
|
|
46
|
+
topicAddress(sender),
|
|
47
|
+
topicAddress(address),
|
|
48
|
+
],
|
|
49
|
+
transactionHash,
|
|
50
|
+
transactionIndex: '0x0',
|
|
51
|
+
},
|
|
52
|
+
]
|
|
53
|
+
response.writeHead(200, { 'content-type': 'application/json' })
|
|
54
|
+
response.end(JSON.stringify({ id: body.id, jsonrpc: '2.0', result }))
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
const result = await SourceObservation.scan({
|
|
59
|
+
chainId: route.sourceChain.id,
|
|
60
|
+
routes: [{ address, id: 'fda_source_observation' }],
|
|
61
|
+
rpcUrls: [server.url],
|
|
62
|
+
tokenAddress: route.sourceToken.address,
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
expect({ requests, result }).toMatchInlineSnapshot(`
|
|
66
|
+
{
|
|
67
|
+
"requests": [
|
|
68
|
+
{
|
|
69
|
+
"id": 0,
|
|
70
|
+
"jsonrpc": "2.0",
|
|
71
|
+
"method": "eth_blockNumber",
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"id": 1,
|
|
75
|
+
"jsonrpc": "2.0",
|
|
76
|
+
"method": "eth_getLogs",
|
|
77
|
+
"params": [
|
|
78
|
+
{
|
|
79
|
+
"address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
|
|
80
|
+
"fromBlock": "0x1",
|
|
81
|
+
"toBlock": "0x10",
|
|
82
|
+
"topics": [
|
|
83
|
+
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
|
|
84
|
+
null,
|
|
85
|
+
[
|
|
86
|
+
"0x0000000000000000000000004444444444444444444444444444444444444444",
|
|
87
|
+
],
|
|
88
|
+
],
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
"result": {
|
|
94
|
+
"cursor": 16n,
|
|
95
|
+
"head": 16n,
|
|
96
|
+
"observations": [
|
|
97
|
+
{
|
|
98
|
+
"addressId": "fda_source_observation",
|
|
99
|
+
"amount": "1000000",
|
|
100
|
+
"blockNumber": 16n,
|
|
101
|
+
"chainId": "eip155:8453",
|
|
102
|
+
"sender": "0x5555555555555555555555555555555555555555",
|
|
103
|
+
"tokenAddress": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
|
|
104
|
+
"transactionHash": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
|
105
|
+
"transferIndex": 2,
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
},
|
|
109
|
+
}
|
|
110
|
+
`)
|
|
111
|
+
} finally {
|
|
112
|
+
await server.closeAsync()
|
|
113
|
+
}
|
|
114
|
+
})
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
describe('observe', () => {
|
|
118
|
+
test('creates one chain-detected deposit and attaches the Relay request later', async () => {
|
|
119
|
+
const database = TestApp.databaseFactory()
|
|
120
|
+
const route = TestFunding.transferSnapshot()
|
|
121
|
+
const providerAddress = `0x${'44'.repeat(20)}`
|
|
122
|
+
const sender = `0x${'55'.repeat(20)}`
|
|
123
|
+
const sourceTransactionHash = `0x${'aa'.repeat(32)}`
|
|
124
|
+
const address = await DepositAddress.create(database(), {
|
|
125
|
+
apiKeyId: 'key_source_observation',
|
|
126
|
+
deliveryStrategy: 'provider',
|
|
127
|
+
environment: 'production',
|
|
128
|
+
id: 'fda_source_observation',
|
|
129
|
+
now: new Date('2026-01-01T00:00:00.000Z'),
|
|
130
|
+
orgId: 'org_source_observation',
|
|
131
|
+
providerOutputToken: route.destinationToken,
|
|
132
|
+
snapshot: {
|
|
133
|
+
address: providerAddress,
|
|
134
|
+
destinationChain: route.destinationChain,
|
|
135
|
+
destinationToken: route.destinationToken,
|
|
136
|
+
provider: route.provider,
|
|
137
|
+
recipient: route.recipient,
|
|
138
|
+
refundAddress: `0x${'66'.repeat(20)}`,
|
|
139
|
+
sourceChain: route.sourceChain,
|
|
140
|
+
sourceToken: route.sourceToken,
|
|
141
|
+
subsidize: false,
|
|
142
|
+
},
|
|
143
|
+
})
|
|
144
|
+
const input = {
|
|
145
|
+
addressId: address.id,
|
|
146
|
+
amount: '1000000',
|
|
147
|
+
chainId: route.sourceChain.id,
|
|
148
|
+
now: new Date('2026-01-01T00:00:01.000Z'),
|
|
149
|
+
recipient: providerAddress,
|
|
150
|
+
sender,
|
|
151
|
+
tokenAddress: route.sourceToken.address,
|
|
152
|
+
transactionHash: sourceTransactionHash,
|
|
153
|
+
transferIndex: 2,
|
|
154
|
+
}
|
|
155
|
+
const [first, second] = await Promise.all([
|
|
156
|
+
SourceObservation.observe(database(), input),
|
|
157
|
+
SourceObservation.observe(database(), input),
|
|
158
|
+
])
|
|
159
|
+
const routes = await SourceObservation.listRoutes(database(), {
|
|
160
|
+
providerId: 'relay',
|
|
161
|
+
sourceChainId: route.sourceChain.id,
|
|
162
|
+
sourceTokenKey: route.sourceToken.tokenKey,
|
|
163
|
+
})
|
|
164
|
+
const server = await TestRelay.createServer((request, response) => {
|
|
165
|
+
request.resume()
|
|
166
|
+
response.writeHead(200, { 'content-type': 'application/json' })
|
|
167
|
+
response.end(JSON.stringify({ requests: [] }))
|
|
168
|
+
})
|
|
169
|
+
const dispatches: Parameters<Reconciliation.createTracker.Options['dispatch']>[] = []
|
|
170
|
+
|
|
171
|
+
try {
|
|
172
|
+
const tracker = Reconciliation.createTracker({
|
|
173
|
+
db: database,
|
|
174
|
+
dispatch: async (...parameters) => {
|
|
175
|
+
dispatches.push(parameters)
|
|
176
|
+
},
|
|
177
|
+
providers: [Relay.relay({ apiKey: 'relay-api-key', baseUrl: server.url })],
|
|
178
|
+
verifyTransfers: async () => [],
|
|
179
|
+
})
|
|
180
|
+
const pending = await tracker.reconcile({
|
|
181
|
+
addressId: address.id,
|
|
182
|
+
trigger: 'chain',
|
|
183
|
+
type: 'funding:deposit-address:reconcile',
|
|
184
|
+
})
|
|
185
|
+
const reconciled = await Reconciliation.reconcileRequest(database(), {
|
|
186
|
+
address,
|
|
187
|
+
request: {
|
|
188
|
+
createdAt: '2026-01-01T00:00:02.000Z',
|
|
189
|
+
destinationTransactionHashes: [],
|
|
190
|
+
id: 'relay-source-request',
|
|
191
|
+
sourceTransactionHashes: [sourceTransactionHash],
|
|
192
|
+
status: 'pending',
|
|
193
|
+
updatedAt: '2026-01-01T00:00:03.000Z',
|
|
194
|
+
},
|
|
195
|
+
trigger: 'chain',
|
|
196
|
+
verifyTransfers: async () => [
|
|
197
|
+
{
|
|
198
|
+
amount: '1000000',
|
|
199
|
+
sender,
|
|
200
|
+
transactionHash: sourceTransactionHash,
|
|
201
|
+
transferIndex: 2,
|
|
202
|
+
},
|
|
203
|
+
],
|
|
204
|
+
})
|
|
205
|
+
const [record] = await FundingDeposits.listBySourceTransaction(database(), {
|
|
206
|
+
depositAddressId: address.id,
|
|
207
|
+
sourceTransactionHash,
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
expect({
|
|
211
|
+
dispatches,
|
|
212
|
+
outcomes: [first.type, second.type].toSorted(),
|
|
213
|
+
pending,
|
|
214
|
+
reconciled,
|
|
215
|
+
record: record
|
|
216
|
+
? {
|
|
217
|
+
detectionTrigger: record.detectionTrigger,
|
|
218
|
+
providerRequestId: record.providerRequestId,
|
|
219
|
+
providerRequestIds: record.providerRequestIds,
|
|
220
|
+
providerTransferIndex: record.providerTransferIndex,
|
|
221
|
+
sourceAmount: record.snapshot.sourceAmount,
|
|
222
|
+
sourceTransferIndex: record.sourceTransferIndex,
|
|
223
|
+
status: record.status,
|
|
224
|
+
}
|
|
225
|
+
: undefined,
|
|
226
|
+
routes,
|
|
227
|
+
sameDeposit: (() => {
|
|
228
|
+
if (first.type === 'ignored' || second.type === 'ignored') return false
|
|
229
|
+
return first.record.id === second.record.id
|
|
230
|
+
})(),
|
|
231
|
+
}).toMatchInlineSnapshot(
|
|
232
|
+
{
|
|
233
|
+
dispatches: [[{ addressId: expect.any(String) }, { delaySeconds: 1 }]],
|
|
234
|
+
},
|
|
235
|
+
`
|
|
236
|
+
{
|
|
237
|
+
"dispatches": [
|
|
238
|
+
[
|
|
239
|
+
{
|
|
240
|
+
"addressId": Any<String>,
|
|
241
|
+
"followUp": {
|
|
242
|
+
"attempt": 0,
|
|
243
|
+
"kind": "provider",
|
|
244
|
+
},
|
|
245
|
+
"trigger": "chain",
|
|
246
|
+
"type": "funding:deposit-address:reconcile",
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
"delaySeconds": 1,
|
|
250
|
+
},
|
|
251
|
+
],
|
|
252
|
+
],
|
|
253
|
+
"outcomes": [
|
|
254
|
+
"created",
|
|
255
|
+
"existing",
|
|
256
|
+
],
|
|
257
|
+
"pending": {
|
|
258
|
+
"created": 0,
|
|
259
|
+
"type": "completed",
|
|
260
|
+
"updated": 0,
|
|
261
|
+
},
|
|
262
|
+
"reconciled": {
|
|
263
|
+
"created": 0,
|
|
264
|
+
"terminal": false,
|
|
265
|
+
"updated": 1,
|
|
266
|
+
},
|
|
267
|
+
"record": {
|
|
268
|
+
"detectionTrigger": "chain",
|
|
269
|
+
"providerRequestId": "relay-source-request",
|
|
270
|
+
"providerRequestIds": [
|
|
271
|
+
"relay-source-request",
|
|
272
|
+
],
|
|
273
|
+
"providerTransferIndex": 0,
|
|
274
|
+
"sourceAmount": {
|
|
275
|
+
"baseUnits": "1000000",
|
|
276
|
+
"currency": "USD",
|
|
277
|
+
"decimals": 6,
|
|
278
|
+
"formatted": "1",
|
|
279
|
+
},
|
|
280
|
+
"sourceTransferIndex": 2,
|
|
281
|
+
"status": "bridging",
|
|
282
|
+
},
|
|
283
|
+
"routes": [
|
|
284
|
+
{
|
|
285
|
+
"address": "0x4444444444444444444444444444444444444444",
|
|
286
|
+
"id": "fda_source_observation",
|
|
287
|
+
},
|
|
288
|
+
],
|
|
289
|
+
"sameDeposit": true,
|
|
290
|
+
}
|
|
291
|
+
`,
|
|
292
|
+
)
|
|
293
|
+
} finally {
|
|
294
|
+
await server.closeAsync()
|
|
295
|
+
}
|
|
296
|
+
})
|
|
297
|
+
})
|
|
298
|
+
|
|
299
|
+
function topicAddress(address: string) {
|
|
300
|
+
return `0x${address.slice(2).toLowerCase().padStart(64, '0')}`
|
|
301
|
+
}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { AbiEvent, Address, RpcTransport } from 'ox'
|
|
2
|
+
import { createClient, custom, fallback } from 'viem'
|
|
3
|
+
import { getBlockNumber, getLogs } from 'viem/actions'
|
|
4
|
+
|
|
5
|
+
import type * as Db from '../../db/Db.js'
|
|
6
|
+
import * as FundingDepositAddresses from '../../db/tables/fundingDepositAddresses.js'
|
|
7
|
+
import * as FundingDeposits from '../../db/tables/fundingDeposits.js'
|
|
8
|
+
import * as Value from '../Value.js'
|
|
9
|
+
import * as Deposit from './Deposit.js'
|
|
10
|
+
|
|
11
|
+
const addressBatchSize = 50
|
|
12
|
+
const defaultBackfillBlocks = 16n
|
|
13
|
+
const defaultConfirmations = 1
|
|
14
|
+
const defaultMaximumBlocks = 16n
|
|
15
|
+
const transferEvent = AbiEvent.from(
|
|
16
|
+
'event Transfer(address indexed from, address indexed to, uint256 value)',
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
/** Active reusable address watched by one chain-and-token observer shard. */
|
|
20
|
+
export type Route = {
|
|
21
|
+
/** Provider-owned reusable address. */
|
|
22
|
+
address: string
|
|
23
|
+
/** Funding deposit address id. */
|
|
24
|
+
id: string
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Verified source transfer discovered directly from an EVM log. */
|
|
28
|
+
export type Observation = {
|
|
29
|
+
/** Funding deposit address that received the transfer. */
|
|
30
|
+
addressId: string
|
|
31
|
+
/** Source token quantity in base units. */
|
|
32
|
+
amount: string
|
|
33
|
+
/** Confirmed source block containing the transfer. */
|
|
34
|
+
blockNumber: bigint
|
|
35
|
+
/** Source chain CAIP-2 id. */
|
|
36
|
+
chainId: string
|
|
37
|
+
/** Source-chain sender. */
|
|
38
|
+
sender: string
|
|
39
|
+
/** Source token contract. */
|
|
40
|
+
tokenAddress: string
|
|
41
|
+
/** Source transaction hash. */
|
|
42
|
+
transactionHash: string
|
|
43
|
+
/** Transfer log position within the source transaction. */
|
|
44
|
+
transferIndex: number
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Scans confirmed EVM blocks for transfers into active reusable addresses. */
|
|
48
|
+
export async function scan(options: scan.Options): Promise<scan.Result> {
|
|
49
|
+
if (options.routes.length === 0)
|
|
50
|
+
return { cursor: options.cursor ?? 0n, head: options.cursor ?? 0n, observations: [] }
|
|
51
|
+
if (!Address.validate(options.tokenAddress, { strict: false }))
|
|
52
|
+
throw new ConfigurationError('source token address')
|
|
53
|
+
if (options.rpcUrls.length === 0) throw new ConfigurationError('source RPC URL')
|
|
54
|
+
|
|
55
|
+
const client = createClient({
|
|
56
|
+
transport: fallback(
|
|
57
|
+
options.rpcUrls.map((url) => {
|
|
58
|
+
const transport = RpcTransport.fromHttp(url, { fetchFn: options.fetch ?? globalThis.fetch })
|
|
59
|
+
return custom(transport, { retryCount: 0 })
|
|
60
|
+
}),
|
|
61
|
+
),
|
|
62
|
+
})
|
|
63
|
+
const head = await getBlockNumber(client, { cacheTime: 0 })
|
|
64
|
+
const confirmations = BigInt(options.confirmations ?? defaultConfirmations)
|
|
65
|
+
const confirmed = head >= confirmations ? head - confirmations + 1n : 0n
|
|
66
|
+
const backfillBlocks = options.backfillBlocks ?? defaultBackfillBlocks
|
|
67
|
+
const fromBlock = (() => {
|
|
68
|
+
if (options.cursor !== undefined) return options.cursor + 1n
|
|
69
|
+
if (confirmed >= backfillBlocks) return confirmed - backfillBlocks + 1n
|
|
70
|
+
return 0n
|
|
71
|
+
})()
|
|
72
|
+
if (fromBlock > confirmed)
|
|
73
|
+
return { cursor: options.cursor ?? confirmed, head: confirmed, observations: [] }
|
|
74
|
+
const maximumBlocks = options.maximumBlocks ?? defaultMaximumBlocks
|
|
75
|
+
const toBlock = minimum(confirmed, fromBlock + maximumBlocks - 1n)
|
|
76
|
+
const routesByAddress = new Map(
|
|
77
|
+
options.routes.map((route) => {
|
|
78
|
+
if (!Address.validate(route.address, { strict: false }))
|
|
79
|
+
throw new ConfigurationError('deposit address')
|
|
80
|
+
return [route.address.toLowerCase(), route] as const
|
|
81
|
+
}),
|
|
82
|
+
)
|
|
83
|
+
const addresses = [...routesByAddress.keys()] as Address.Address[]
|
|
84
|
+
const observations: Observation[] = []
|
|
85
|
+
for (let index = 0; index < addresses.length; index += addressBatchSize) {
|
|
86
|
+
const batch = addresses.slice(index, index + addressBatchSize)
|
|
87
|
+
const logs = await getLogs(client, {
|
|
88
|
+
address: options.tokenAddress as Address.Address,
|
|
89
|
+
args: { to: batch },
|
|
90
|
+
event: transferEvent,
|
|
91
|
+
fromBlock,
|
|
92
|
+
strict: true,
|
|
93
|
+
toBlock,
|
|
94
|
+
})
|
|
95
|
+
for (const log of logs) {
|
|
96
|
+
if (log.blockNumber === null || log.logIndex === null || !log.transactionHash) continue
|
|
97
|
+
const event = (() => {
|
|
98
|
+
try {
|
|
99
|
+
return AbiEvent.decode(transferEvent, { data: log.data, topics: log.topics })
|
|
100
|
+
} catch {
|
|
101
|
+
return undefined
|
|
102
|
+
}
|
|
103
|
+
})()
|
|
104
|
+
const route = event ? routesByAddress.get(event.to.toLowerCase()) : undefined
|
|
105
|
+
if (!event || !route) continue
|
|
106
|
+
observations.push({
|
|
107
|
+
addressId: route.id,
|
|
108
|
+
amount: event.value.toString(),
|
|
109
|
+
blockNumber: log.blockNumber,
|
|
110
|
+
chainId: options.chainId,
|
|
111
|
+
sender: event.from.toLowerCase(),
|
|
112
|
+
tokenAddress: options.tokenAddress.toLowerCase(),
|
|
113
|
+
transactionHash: log.transactionHash,
|
|
114
|
+
transferIndex: log.logIndex,
|
|
115
|
+
})
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
observations.sort(
|
|
119
|
+
(left, right) =>
|
|
120
|
+
Number(left.blockNumber - right.blockNumber) || left.transferIndex - right.transferIndex,
|
|
121
|
+
)
|
|
122
|
+
return { cursor: toBlock, head: confirmed, observations }
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export declare namespace scan {
|
|
126
|
+
/** EVM shard state and scan bounds. */
|
|
127
|
+
type Options = {
|
|
128
|
+
/** Initial confirmed-block backfill when no cursor exists. */
|
|
129
|
+
backfillBlocks?: bigint | undefined
|
|
130
|
+
/** Source chain CAIP-2 id. */
|
|
131
|
+
chainId: string
|
|
132
|
+
/** Required block confirmations. */
|
|
133
|
+
confirmations?: number | undefined
|
|
134
|
+
/** Last confirmed block processed by the shard. */
|
|
135
|
+
cursor?: bigint | undefined
|
|
136
|
+
/** Fetch implementation override. */
|
|
137
|
+
fetch?: typeof globalThis.fetch | undefined
|
|
138
|
+
/** Maximum confirmed blocks processed in one invocation. */
|
|
139
|
+
maximumBlocks?: bigint | undefined
|
|
140
|
+
/** Active reusable addresses in the shard. */
|
|
141
|
+
routes: readonly Route[]
|
|
142
|
+
/** Ordered source-chain RPC endpoints. */
|
|
143
|
+
rpcUrls: readonly string[]
|
|
144
|
+
/** Source token contract. */
|
|
145
|
+
tokenAddress: string
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** Confirmed cursor and verified transfers produced by one scan. */
|
|
149
|
+
type Result = {
|
|
150
|
+
/** Last confirmed block processed by the shard. */
|
|
151
|
+
cursor: bigint
|
|
152
|
+
/** Latest block satisfying the confirmation policy. */
|
|
153
|
+
head: bigint
|
|
154
|
+
/** Verified transfers into active addresses. */
|
|
155
|
+
observations: readonly Observation[]
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** Lists the active Relay addresses assigned to one source observer shard. */
|
|
160
|
+
export async function listRoutes(
|
|
161
|
+
db: Db.Db,
|
|
162
|
+
options: listRoutes.Options,
|
|
163
|
+
): Promise<readonly Route[]> {
|
|
164
|
+
const records = await FundingDepositAddresses.listActiveSources(db, options)
|
|
165
|
+
return records.map((record) => ({ address: record.address, id: record.id }))
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export declare namespace listRoutes {
|
|
169
|
+
/** Provider and source asset identifying one observer shard. */
|
|
170
|
+
type Options = {
|
|
171
|
+
/** Funding provider that owns the deposit addresses. */
|
|
172
|
+
providerId: string
|
|
173
|
+
/** Source chain CAIP-2 id. */
|
|
174
|
+
sourceChainId: string
|
|
175
|
+
/** Source token key. */
|
|
176
|
+
sourceTokenKey: string
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** Persists one verified source transfer before provider indexing. */
|
|
181
|
+
export async function observe(db: Db.Db, input: observe.Input): Promise<observe.Result> {
|
|
182
|
+
const address = await FundingDepositAddresses.get(db, input.addressId)
|
|
183
|
+
if (
|
|
184
|
+
!address ||
|
|
185
|
+
address.providerId !== 'relay' ||
|
|
186
|
+
address.status !== 'active' ||
|
|
187
|
+
address.snapshot.sourceChain.id !== input.chainId ||
|
|
188
|
+
!Address.isEqual(
|
|
189
|
+
address.snapshot.sourceToken.address as Address.Address,
|
|
190
|
+
input.tokenAddress as Address.Address,
|
|
191
|
+
) ||
|
|
192
|
+
!Address.isEqual(address.address as Address.Address, input.recipient as Address.Address)
|
|
193
|
+
)
|
|
194
|
+
return { type: 'ignored' }
|
|
195
|
+
|
|
196
|
+
return FundingDeposits.withSourceTransaction(db, {
|
|
197
|
+
depositAddressId: address.id,
|
|
198
|
+
fn: async (tx) => {
|
|
199
|
+
const existing = await FundingDeposits.listBySourceTransaction(tx, {
|
|
200
|
+
depositAddressId: address.id,
|
|
201
|
+
sourceTransactionHash: input.transactionHash,
|
|
202
|
+
})
|
|
203
|
+
const record =
|
|
204
|
+
existing.find((candidate) => candidate.sourceTransferIndex === input.transferIndex) ??
|
|
205
|
+
existing.find((candidate) => candidate.sourceTransferIndex === null)
|
|
206
|
+
if (record) return { record, type: 'existing' as const }
|
|
207
|
+
return Deposit.createFromSource(tx, {
|
|
208
|
+
now: input.now,
|
|
209
|
+
snapshot: {
|
|
210
|
+
...address.snapshot,
|
|
211
|
+
depositAddressId: address.id,
|
|
212
|
+
sender: input.sender,
|
|
213
|
+
sourceAmount: Value.tokenAmount({
|
|
214
|
+
baseUnits: input.amount,
|
|
215
|
+
currency: address.snapshot.sourceToken.currency,
|
|
216
|
+
decimals: address.snapshot.sourceToken.decimals,
|
|
217
|
+
}),
|
|
218
|
+
sourceTransactionHashes: [input.transactionHash],
|
|
219
|
+
},
|
|
220
|
+
sourceTransactionHash: input.transactionHash,
|
|
221
|
+
sourceTransferIndex: input.transferIndex,
|
|
222
|
+
})
|
|
223
|
+
},
|
|
224
|
+
sourceTransactionHash: input.transactionHash,
|
|
225
|
+
})
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export declare namespace observe {
|
|
229
|
+
/** Verified source transfer and route identity. */
|
|
230
|
+
type Input = {
|
|
231
|
+
/** Funding deposit address id. */
|
|
232
|
+
addressId: string
|
|
233
|
+
/** Source token quantity in base units. */
|
|
234
|
+
amount: string
|
|
235
|
+
/** Source chain CAIP-2 id. */
|
|
236
|
+
chainId: string
|
|
237
|
+
/** Detection time override. */
|
|
238
|
+
now?: Date | undefined
|
|
239
|
+
/** Provider-owned reusable address that received the transfer. */
|
|
240
|
+
recipient: string
|
|
241
|
+
/** Source-chain sender. */
|
|
242
|
+
sender: string
|
|
243
|
+
/** Source token contract. */
|
|
244
|
+
tokenAddress: string
|
|
245
|
+
/** Source transaction hash. */
|
|
246
|
+
transactionHash: string
|
|
247
|
+
/** Transfer log position within the source transaction. */
|
|
248
|
+
transferIndex: number
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/** Persistence outcome for one chain-observed source transfer. */
|
|
252
|
+
type Result =
|
|
253
|
+
| { record: FundingDeposits.Record; type: 'created' | 'existing' }
|
|
254
|
+
| { type: 'ignored' }
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
function minimum(left: bigint, right: bigint) {
|
|
258
|
+
return left < right ? left : right
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
class ConfigurationError extends Error {
|
|
262
|
+
override name = 'FundingSourceObservation.ConfigurationError'
|
|
263
|
+
|
|
264
|
+
constructor(field: string) {
|
|
265
|
+
super(`Invalid ${field} configured for funding source observation.`)
|
|
266
|
+
}
|
|
267
|
+
}
|
|
@@ -129,7 +129,7 @@ export declare namespace Settler {
|
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
/** Creates a subsidy settler backed by
|
|
132
|
+
/** Creates a subsidy settler backed by a Tempo account that holds pathUSD. */
|
|
133
133
|
export function create(options: create.Options): Settler {
|
|
134
134
|
const client = options.getClient()
|
|
135
135
|
return {
|
|
@@ -225,7 +225,7 @@ export function create(options: create.Options): Settler {
|
|
|
225
225
|
export declare namespace create {
|
|
226
226
|
/** Dependencies and policy for one subsidy settler. */
|
|
227
227
|
type Options = {
|
|
228
|
-
/**
|
|
228
|
+
/** Tempo account that signs subsidies and holds pathUSD. */
|
|
229
229
|
account: LocalAccount
|
|
230
230
|
/** Trusted Tempo RPC client resolver. */
|
|
231
231
|
getClient: Viem.GetClient
|
|
@@ -7,6 +7,7 @@ export * as Evidence from './Evidence.js'
|
|
|
7
7
|
export * as Provider from './Provider.js'
|
|
8
8
|
export * as Reconciliation from './Reconciliation.js'
|
|
9
9
|
export * as Route from './Route.js'
|
|
10
|
+
export * as SourceObservation from './SourceObservation.js'
|
|
10
11
|
export * as Subsidy from './Subsidy.js'
|
|
11
12
|
export * as Token from './Token.js'
|
|
12
13
|
export * as Transfer from './Transfer.js'
|