tapimo 0.12.0 → 0.13.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 +5561 -5026
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +38 -3
- package/dist/App.js.map +1 -1
- package/dist/Scope.d.ts +2 -0
- package/dist/Scope.d.ts.map +1 -1
- package/dist/Scope.js +17 -0
- package/dist/Scope.js.map +1 -1
- package/dist/admin/App.d.ts +123 -74
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.d.ts +80 -0
- package/dist/admin/apps/api-keys.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.js +54 -0
- package/dist/admin/apps/api-keys.js.map +1 -1
- package/dist/admin/apps/earn-vaults.d.ts +15 -15
- package/dist/admin/apps/earn-vaults.js +1 -1
- package/dist/admin/apps/verified-tokens.d.ts +81 -81
- 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 +151 -151
- package/dist/admin/ui.generated.js.map +1 -1
- package/dist/apps/Zones.d.ts +16 -16
- package/dist/apps/Zones.js +4 -4
- package/dist/apps/data/App.js +18 -18
- package/dist/apps/data/App.js.map +1 -1
- package/dist/apps/data/ZoneSelection.d.ts +8 -8
- package/dist/apps/data/ZoneSelection.d.ts.map +1 -1
- package/dist/apps/data/ZoneSelection.js +1 -1
- package/dist/apps/data/ZoneSelection.js.map +1 -1
- package/dist/apps/data/routes/activities.d.ts +588 -584
- package/dist/apps/data/routes/activities.d.ts.map +1 -1
- package/dist/apps/data/routes/activities.js +1561 -1239
- package/dist/apps/data/routes/activities.js.map +1 -1
- package/dist/apps/data/routes/balances.d.ts +26 -26
- package/dist/apps/data/routes/balances.d.ts.map +1 -1
- package/dist/apps/data/routes/balances.js +43 -16
- package/dist/apps/data/routes/balances.js.map +1 -1
- package/dist/apps/data/routes/blocks.d.ts +44 -44
- package/dist/apps/data/routes/blocks.d.ts.map +1 -1
- package/dist/apps/data/routes/blocks.js +21 -11
- package/dist/apps/data/routes/blocks.js.map +1 -1
- package/dist/apps/data/routes/coingecko.d.ts +3 -3
- package/dist/apps/data/routes/earn.d.ts +18 -18
- package/dist/apps/data/routes/earn.js +13 -13
- package/dist/apps/data/routes/exchanges.d.ts +145 -145
- package/dist/apps/data/routes/fee-amm.d.ts +2 -2
- package/dist/apps/data/routes/receipts.d.ts +155 -55
- package/dist/apps/data/routes/receipts.d.ts.map +1 -1
- package/dist/apps/data/routes/receipts.js +28 -10
- package/dist/apps/data/routes/receipts.js.map +1 -1
- package/dist/apps/data/routes/tokenlist.d.ts +13 -13
- package/dist/apps/data/routes/tokens.d.ts +98 -98
- package/dist/apps/data/routes/tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/tokens.js +51 -20
- package/dist/apps/data/routes/tokens.js.map +1 -1
- package/dist/apps/data/routes/transactions.d.ts +7 -2
- package/dist/apps/data/routes/transactions.d.ts.map +1 -1
- package/dist/apps/data/routes/transactions.js +37 -17
- package/dist/apps/data/routes/transactions.js.map +1 -1
- package/dist/apps/data/routes/transfers.d.ts +1 -1
- package/dist/apps/data/routes/transfers.d.ts.map +1 -1
- package/dist/apps/data/routes/transfers.js +18 -12
- package/dist/apps/data/routes/transfers.js.map +1 -1
- package/dist/apps/data/routes/valuation.d.ts +1 -1
- package/dist/apps/data/routes/valuation.d.ts.map +1 -1
- package/dist/apps/data/routes/valuation.js +12 -7
- package/dist/apps/data/routes/valuation.js.map +1 -1
- package/dist/apps/data/routes/verified-tokens.d.ts +3 -3
- package/dist/apps/data/routes/webhooks.d.ts +11 -11
- package/dist/apps/data/routes/zones.d.ts +14 -14
- package/dist/apps/data/routes/zones.js +1 -1
- package/dist/apps/funding/App.d.ts +11 -0
- package/dist/apps/funding/App.d.ts.map +1 -1
- package/dist/apps/funding/routes/deposit-addresses.d.ts.map +1 -1
- package/dist/apps/funding/routes/deposit-addresses.js +16 -11
- package/dist/apps/funding/routes/deposit-addresses.js.map +1 -1
- package/dist/apps/funding/routes/transfers.d.ts +60 -48
- package/dist/apps/funding/routes/transfers.d.ts.map +1 -1
- package/dist/apps/funding/routes/transfers.js +27 -19
- package/dist/apps/funding/routes/transfers.js.map +1 -1
- package/dist/apps/management/App.d.ts +4487 -3963
- package/dist/apps/management/App.d.ts.map +1 -1
- package/dist/apps/management/routes/api-keys.d.ts +710 -159
- package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
- package/dist/apps/management/routes/api-keys.js +236 -4
- package/dist/apps/management/routes/api-keys.js.map +1 -1
- package/dist/apps/management/routes/faucet.d.ts +6 -6
- package/dist/apps/management/routes/invite-links.d.ts +42 -42
- package/dist/apps/management/routes/members.d.ts +30 -30
- package/dist/apps/management/routes/projects.d.ts +40 -40
- package/dist/apps/management/routes/usage.d.ts +24 -24
- package/dist/apps/management/routes/verified-token-requests.d.ts +1 -1
- package/dist/apps/management/routes/webhooks.d.ts +55 -55
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +12 -1
- package/dist/db/Db.js.map +1 -1
- package/dist/db/Schema.d.ts +3 -2
- package/dist/db/Schema.d.ts.map +1 -1
- package/dist/db/Schema.js +5 -2
- package/dist/db/Schema.js.map +1 -1
- package/dist/db/tables/fundingCatalog.d.ts +4 -2
- package/dist/db/tables/fundingCatalog.d.ts.map +1 -1
- package/dist/db/tables/fundingCatalog.js +5 -1
- package/dist/db/tables/fundingCatalog.js.map +1 -1
- package/dist/handlers/internal/utils.d.ts.map +1 -1
- package/dist/handlers/internal/utils.js +9 -0
- package/dist/handlers/internal/utils.js.map +1 -1
- package/dist/internal/Auth.d.ts +3 -1
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +6 -3
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/EarnVaults.d.ts +3 -3
- package/dist/internal/EarnVaults.js +3 -3
- package/dist/internal/Fetch.d.ts +23 -0
- package/dist/internal/Fetch.d.ts.map +1 -0
- package/dist/internal/Fetch.js +26 -0
- package/dist/internal/Fetch.js.map +1 -0
- package/dist/internal/Log.d.ts +3 -1
- package/dist/internal/Log.d.ts.map +1 -1
- package/dist/internal/Log.js +16 -3
- package/dist/internal/Log.js.map +1 -1
- package/dist/internal/OpenApi.d.ts +5 -3
- package/dist/internal/OpenApi.d.ts.map +1 -1
- package/dist/internal/OpenApi.js +13 -3
- package/dist/internal/OpenApi.js.map +1 -1
- package/dist/internal/Response.d.ts +1 -1
- package/dist/internal/Response.d.ts.map +1 -1
- package/dist/internal/Schema.d.ts +6 -3
- package/dist/internal/Schema.d.ts.map +1 -1
- package/dist/internal/Schema.js +8 -2
- package/dist/internal/Schema.js.map +1 -1
- package/dist/internal/Store.d.ts +16 -3
- package/dist/internal/Store.d.ts.map +1 -1
- package/dist/internal/Store.js +82 -16
- package/dist/internal/Store.js.map +1 -1
- package/dist/internal/Tidx.d.ts.map +1 -1
- package/dist/internal/Tidx.js +7 -2
- package/dist/internal/Tidx.js.map +1 -1
- package/dist/internal/Timeout.d.ts +36 -0
- package/dist/internal/Timeout.d.ts.map +1 -0
- package/dist/internal/Timeout.js +37 -0
- package/dist/internal/Timeout.js.map +1 -0
- package/dist/internal/Timing.d.ts +9 -0
- package/dist/internal/Timing.d.ts.map +1 -1
- package/dist/internal/Timing.js +7 -0
- package/dist/internal/Timing.js.map +1 -1
- package/dist/internal/WebhookDestination.d.ts.map +1 -1
- package/dist/internal/WebhookDestination.js +3 -0
- package/dist/internal/WebhookDestination.js.map +1 -1
- package/dist/internal/funding/Action.d.ts +9 -0
- package/dist/internal/funding/Action.d.ts.map +1 -1
- package/dist/internal/funding/Action.js +16 -8
- package/dist/internal/funding/Action.js.map +1 -1
- package/dist/internal/funding/Catalog.d.ts +9 -2
- package/dist/internal/funding/Catalog.d.ts.map +1 -1
- package/dist/internal/funding/Catalog.js +19 -8
- package/dist/internal/funding/Catalog.js.map +1 -1
- package/dist/internal/funding/Provider.d.ts +68 -13
- package/dist/internal/funding/Provider.d.ts.map +1 -1
- package/dist/internal/funding/Provider.js +29 -8
- package/dist/internal/funding/Provider.js.map +1 -1
- package/dist/internal/funding/Transfer.d.ts +13 -12
- package/dist/internal/funding/Transfer.d.ts.map +1 -1
- package/dist/internal/funding/Transfer.js +23 -21
- package/dist/internal/funding/Transfer.js.map +1 -1
- package/dist/internal/funding/providers/stargate.d.ts +28 -9
- package/dist/internal/funding/providers/stargate.d.ts.map +1 -1
- package/dist/internal/funding/providers/stargate.js +251 -117
- package/dist/internal/funding/providers/stargate.js.map +1 -1
- package/dist/internal/index.d.ts +1 -0
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +1 -0
- package/dist/internal/index.js.map +1 -1
- package/package.json +2 -2
- package/src/App.test.ts +100 -0
- package/src/App.ts +42 -3
- package/src/Client.test-d.ts +46 -0
- package/src/Scope.test.ts +20 -0
- package/src/Scope.ts +16 -0
- package/src/admin/apps/api-keys.test.ts +75 -0
- package/src/admin/apps/api-keys.ts +64 -0
- package/src/admin/apps/earn-vaults.test.ts +1 -1
- package/src/admin/apps/earn-vaults.ts +1 -1
- package/src/admin/ui/src/lib/api-keys.ts +19 -0
- package/src/admin/ui/src/routes/api-keys.tsx +89 -2
- package/src/admin/ui.generated.ts +189 -151
- package/src/apps/Zones.test.ts +4 -4
- package/src/apps/Zones.ts +4 -4
- package/src/apps/composition.test.ts +1 -1
- package/src/apps/data/App.test.ts +41 -0
- package/src/apps/data/App.ts +18 -18
- package/src/apps/data/ZoneSelection.test.ts +2 -2
- package/src/apps/data/ZoneSelection.ts +8 -8
- package/src/apps/data/routes/activities.test.ts +1526 -12
- package/src/apps/data/routes/activities.ts +1774 -1356
- package/src/apps/data/routes/balances.ts +133 -97
- package/src/apps/data/routes/blocks.test.ts +533 -0
- package/src/apps/data/routes/blocks.ts +35 -16
- package/src/apps/data/routes/earn.test.ts +4 -2
- package/src/apps/data/routes/earn.ts +13 -13
- package/src/apps/data/routes/earn.zone-access.test.ts +6 -6
- package/src/apps/data/routes/receipts.ts +47 -16
- package/src/apps/data/routes/tokens.test.ts +578 -0
- package/src/apps/data/routes/tokens.ts +283 -225
- package/src/apps/data/routes/transactions.ts +68 -29
- package/src/apps/data/routes/transfers.test.ts +421 -0
- package/src/apps/data/routes/transfers.ts +45 -27
- package/src/apps/data/routes/valuation.ts +94 -78
- package/src/apps/data/routes/zones.test.ts +2 -2
- package/src/apps/data/routes/zones.ts +1 -1
- package/src/apps/funding/routes/deposit-addresses.test.ts +25 -3
- package/src/apps/funding/routes/deposit-addresses.ts +17 -12
- package/src/apps/funding/routes/quotes.test.ts +5 -9
- package/src/apps/funding/routes/transfers.test.ts +395 -8
- package/src/apps/funding/routes/transfers.ts +76 -59
- package/src/apps/management/routes/api-keys.test.ts +220 -0
- package/src/apps/management/routes/api-keys.ts +280 -3
- package/src/db/Db.ts +13 -1
- package/src/db/Schema.ts +5 -2
- package/src/db/tables/earnVaults.test.ts +9 -9
- package/src/db/tables/fundingCatalog.test.ts +16 -2
- package/src/db/tables/fundingCatalog.ts +9 -3
- package/src/handlers/internal/utils.test.ts +53 -0
- package/src/handlers/internal/utils.ts +15 -0
- package/src/internal/Auth.ts +12 -4
- package/src/internal/EarnVaults.capabilities.test.ts +2 -2
- package/src/internal/EarnVaults.test.ts +1 -1
- package/src/internal/EarnVaults.ts +3 -3
- package/src/internal/Fetch.test.ts +46 -0
- package/src/internal/Fetch.ts +56 -0
- package/src/internal/Log.test.ts +21 -0
- package/src/internal/Log.ts +20 -5
- package/src/internal/OpenApi.ts +14 -4
- package/src/internal/Response.ts +1 -1
- package/src/internal/Schema.test.ts +2 -0
- package/src/internal/Schema.ts +12 -2
- package/src/internal/Store.test.ts +178 -0
- package/src/internal/Store.ts +104 -18
- package/src/internal/Tidx.test.ts +2 -1
- package/src/internal/Tidx.ts +7 -2
- package/src/internal/Timeout.test.ts +35 -0
- package/src/internal/Timeout.ts +73 -0
- package/src/internal/Timing.ts +16 -0
- package/src/internal/WebhookDestination.ts +3 -0
- package/src/internal/funding/Action.test.ts +41 -1
- package/src/internal/funding/Action.ts +69 -41
- package/src/internal/funding/Catalog.test.ts +34 -0
- package/src/internal/funding/Catalog.ts +28 -11
- package/src/internal/funding/Provider.test.ts +73 -0
- package/src/internal/funding/Provider.ts +82 -28
- package/src/internal/funding/Transfer.ts +133 -110
- package/src/internal/funding/providers/index.test.ts +4 -167
- package/src/internal/funding/providers/relay.test.ts +2 -2
- package/src/internal/funding/providers/stargate.test.ts +163 -0
- package/src/internal/funding/providers/stargate.ts +359 -134
- package/src/internal/index.test.ts +1 -0
- package/src/internal/index.ts +1 -0
|
@@ -4,6 +4,7 @@ import type * as Db from '../../db/Db.js'
|
|
|
4
4
|
import * as FundingTransferEvents from '../../db/tables/fundingTransferEvents.js'
|
|
5
5
|
import * as FundingTransfers from '../../db/tables/fundingTransfers.js'
|
|
6
6
|
import * as Id from '../Id.js'
|
|
7
|
+
import * as OpenApi from '../OpenApi.js'
|
|
7
8
|
import * as Schema from '../Schema.js'
|
|
8
9
|
import * as Action from './Action.js'
|
|
9
10
|
import * as Provider from './Provider.js'
|
|
@@ -91,22 +92,25 @@ export namespace schema {
|
|
|
91
92
|
)
|
|
92
93
|
|
|
93
94
|
/** Customer-safe explanation of a status that needs context. */
|
|
94
|
-
export const StatusReason =
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
export const StatusReason = OpenApi.component(
|
|
96
|
+
z
|
|
97
|
+
.object({
|
|
98
|
+
code: z
|
|
99
|
+
.enum(statusReasonCodes)
|
|
100
|
+
.check(
|
|
101
|
+
z.describe('Stable machine-readable reason code.'),
|
|
102
|
+
z.meta({ examples: ['destination_amount_below_minimum'] }),
|
|
103
|
+
),
|
|
104
|
+
message: z.string().check(
|
|
105
|
+
z.describe('Human-readable explanation of the reason.'),
|
|
106
|
+
z.meta({
|
|
107
|
+
examples: ['The verified destination amount did not satisfy the quoted minimum.'],
|
|
108
|
+
}),
|
|
101
109
|
),
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}),
|
|
107
|
-
),
|
|
108
|
-
})
|
|
109
|
-
.check(z.describe('Why the transfer is in its current status, when context is needed.'))
|
|
110
|
+
})
|
|
111
|
+
.check(z.describe('Why the transfer is in its current status, when context is needed.')),
|
|
112
|
+
'FundingTransferStatusReason',
|
|
113
|
+
)
|
|
110
114
|
|
|
111
115
|
/** Funding method selected at creation. */
|
|
112
116
|
export const Method = z
|
|
@@ -122,39 +126,45 @@ export namespace schema {
|
|
|
122
126
|
)
|
|
123
127
|
|
|
124
128
|
/** One fee applied to the transfer. */
|
|
125
|
-
export const Fee =
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
129
|
+
export const Fee = OpenApi.component(
|
|
130
|
+
z
|
|
131
|
+
.object({
|
|
132
|
+
amount: Schema.TokenAmount,
|
|
133
|
+
side: z
|
|
134
|
+
.enum(['destination', 'source'])
|
|
135
|
+
.check(
|
|
136
|
+
z.describe('Which side of the transfer the fee is taken from.'),
|
|
137
|
+
z.meta({ examples: ['destination'] }),
|
|
138
|
+
),
|
|
139
|
+
token: Provider.schema.TokenRef,
|
|
140
|
+
type: z
|
|
141
|
+
.enum(['provider'])
|
|
142
|
+
.check(z.describe('What the fee pays for.'), z.meta({ examples: ['provider'] })),
|
|
143
|
+
})
|
|
144
|
+
.check(z.describe('One fee applied to the transfer.')),
|
|
145
|
+
'FundingTransferFee',
|
|
146
|
+
)
|
|
140
147
|
|
|
141
148
|
/** Freshness and validity window of the selected quote. */
|
|
142
|
-
export const Quote =
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
.
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
.
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
149
|
+
export const Quote = OpenApi.component(
|
|
150
|
+
z
|
|
151
|
+
.object({
|
|
152
|
+
expiresAt: z.iso
|
|
153
|
+
.datetime()
|
|
154
|
+
.check(
|
|
155
|
+
z.describe('When the quoted terms stop being executable (ISO 8601).'),
|
|
156
|
+
z.meta({ examples: ['2026-07-30T04:01:00.000Z'] }),
|
|
157
|
+
),
|
|
158
|
+
sampledAt: z.iso
|
|
159
|
+
.datetime()
|
|
160
|
+
.check(
|
|
161
|
+
z.describe('When the provider produced the quote (ISO 8601).'),
|
|
162
|
+
z.meta({ examples: ['2026-07-30T04:00:00.000Z'] }),
|
|
163
|
+
),
|
|
164
|
+
})
|
|
165
|
+
.check(z.describe('Freshness and validity window of the selected quote.')),
|
|
166
|
+
'FundingTransferQuote',
|
|
167
|
+
)
|
|
158
168
|
|
|
159
169
|
const hashesCheck = (description: string) => [
|
|
160
170
|
z.describe(description),
|
|
@@ -219,8 +229,8 @@ export namespace schema {
|
|
|
219
229
|
.check(z.describe('Quote terms and reconciled public fields of a funding transfer.'))
|
|
220
230
|
|
|
221
231
|
const fundingTransferFields = {
|
|
222
|
-
createdAt: z
|
|
223
|
-
.
|
|
232
|
+
createdAt: z.iso
|
|
233
|
+
.datetime()
|
|
224
234
|
.check(
|
|
225
235
|
z.describe('When the transfer was created (ISO 8601).'),
|
|
226
236
|
z.meta({ examples: ['2026-07-30T04:00:00.000Z'] }),
|
|
@@ -253,8 +263,8 @@ export namespace schema {
|
|
|
253
263
|
sourceTransactionHashes: snapshotFields.sourceTransactionHashes,
|
|
254
264
|
status: Status,
|
|
255
265
|
statusReason: z.optional(StatusReason),
|
|
256
|
-
updatedAt: z
|
|
257
|
-
.
|
|
266
|
+
updatedAt: z.iso
|
|
267
|
+
.datetime()
|
|
258
268
|
.check(
|
|
259
269
|
z.describe('When the transfer last materially changed (ISO 8601).'),
|
|
260
270
|
z.meta({ examples: ['2026-07-30T04:00:20.000Z'] }),
|
|
@@ -270,73 +280,86 @@ export namespace schema {
|
|
|
270
280
|
}
|
|
271
281
|
|
|
272
282
|
/** A funding transfer as returned by reads. Reads never include `action`. */
|
|
273
|
-
export const FundingTransfer =
|
|
274
|
-
.object(fundingTransferFields)
|
|
275
|
-
|
|
283
|
+
export const FundingTransfer = OpenApi.component(
|
|
284
|
+
z.object(fundingTransferFields).check(z.describe('One durable funding transfer.')),
|
|
285
|
+
'FundingTransfer',
|
|
286
|
+
)
|
|
276
287
|
|
|
277
288
|
/** A created funding transfer: the read shape plus the executable action. */
|
|
278
|
-
export const CreatedFundingTransfer =
|
|
279
|
-
|
|
280
|
-
|
|
289
|
+
export const CreatedFundingTransfer = OpenApi.component(
|
|
290
|
+
z
|
|
291
|
+
.object({ action: Action.schema.Action, ...fundingTransferFields })
|
|
292
|
+
.check(z.describe('The created funding transfer, including its one-time executable action.')),
|
|
293
|
+
'CreatedFundingTransfer',
|
|
294
|
+
)
|
|
281
295
|
|
|
282
296
|
/** Request body accepted by funding transfer creation. */
|
|
283
|
-
export const CreateRequest =
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
z.regex(/^[1-9]\d*$/),
|
|
289
|
-
z.describe('Amount in base units of the token the mode fixes.'),
|
|
290
|
-
z.meta({ examples: ['1000000'] }),
|
|
291
|
-
),
|
|
292
|
-
destinationToken: z
|
|
293
|
-
.string()
|
|
294
|
-
.check(
|
|
295
|
-
z.minLength(1),
|
|
296
|
-
z.describe('Tempo destination token symbol, contract address, or token key.'),
|
|
297
|
-
z.meta({ examples: ['pathusd'] }),
|
|
298
|
-
),
|
|
299
|
-
mode: Mode,
|
|
300
|
-
recipient: z
|
|
301
|
-
.string()
|
|
302
|
-
.check(
|
|
303
|
-
z.regex(/^0x[0-9a-fA-F]{40}$/),
|
|
304
|
-
z.describe('Final beneficiary of the transfer.'),
|
|
305
|
-
z.meta({ examples: [`0x${'11'.repeat(20)}`] }),
|
|
306
|
-
),
|
|
307
|
-
sender: z
|
|
308
|
-
.string()
|
|
309
|
-
.check(
|
|
310
|
-
z.regex(/^0x[0-9a-fA-F]{40}$/),
|
|
311
|
-
z.describe('Source-chain account that signs the funding action.'),
|
|
312
|
-
z.meta({ examples: [`0x${'22'.repeat(20)}`] }),
|
|
313
|
-
),
|
|
314
|
-
slippageBps: z.optional(
|
|
315
|
-
z
|
|
316
|
-
.number()
|
|
297
|
+
export const CreateRequest = OpenApi.component(
|
|
298
|
+
z
|
|
299
|
+
.strictObject({
|
|
300
|
+
amount: z
|
|
301
|
+
.string()
|
|
317
302
|
.check(
|
|
318
|
-
z.
|
|
319
|
-
z.
|
|
320
|
-
z.
|
|
321
|
-
z.describe('Maximum acceptable slippage in basis points.'),
|
|
322
|
-
z.meta({ examples: [50] }),
|
|
303
|
+
z.regex(/^[1-9]\d*$/),
|
|
304
|
+
z.describe('Amount in base units of the token the mode fixes.'),
|
|
305
|
+
z.meta({ examples: ['1000000'] }),
|
|
323
306
|
),
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
307
|
+
destinationToken: z
|
|
308
|
+
.string()
|
|
309
|
+
.check(
|
|
310
|
+
z.minLength(1),
|
|
311
|
+
z.describe('Tempo destination token symbol, contract address, or token key.'),
|
|
312
|
+
z.meta({ examples: ['pathusd'] }),
|
|
313
|
+
),
|
|
314
|
+
mode: Mode,
|
|
315
|
+
provider: z
|
|
316
|
+
.optional(z.string().check(z.minLength(1)))
|
|
317
|
+
.check(
|
|
318
|
+
z.describe('Funding provider ID. Omit to select the best available provider.'),
|
|
319
|
+
z.meta({ examples: ['relay'] }),
|
|
320
|
+
),
|
|
321
|
+
recipient: z
|
|
322
|
+
.string()
|
|
323
|
+
.check(
|
|
324
|
+
z.regex(/^0x[0-9a-fA-F]{40}$/),
|
|
325
|
+
z.describe('Final beneficiary of the transfer.'),
|
|
326
|
+
z.meta({ examples: [`0x${'11'.repeat(20)}`] }),
|
|
327
|
+
),
|
|
328
|
+
sender: z
|
|
329
|
+
.string()
|
|
330
|
+
.check(
|
|
331
|
+
z.regex(/^0x[0-9a-fA-F]{40}$/),
|
|
332
|
+
z.describe('Source-chain account that signs the funding action.'),
|
|
333
|
+
z.meta({ examples: [`0x${'22'.repeat(20)}`] }),
|
|
334
|
+
),
|
|
335
|
+
slippageBps: z.optional(
|
|
336
|
+
z
|
|
337
|
+
.number()
|
|
338
|
+
.check(
|
|
339
|
+
z.int(),
|
|
340
|
+
z.gte(0),
|
|
341
|
+
z.lte(10_000),
|
|
342
|
+
z.describe('Maximum acceptable slippage in basis points.'),
|
|
343
|
+
z.meta({ examples: [50] }),
|
|
344
|
+
),
|
|
337
345
|
),
|
|
338
|
-
|
|
339
|
-
|
|
346
|
+
sourceChain: z
|
|
347
|
+
.string()
|
|
348
|
+
.check(
|
|
349
|
+
z.describe('Source chain CAIP-2 id, slug, or alias.'),
|
|
350
|
+
z.meta({ examples: ['base', 'eip155:8453'] }),
|
|
351
|
+
),
|
|
352
|
+
sourceToken: z
|
|
353
|
+
.string()
|
|
354
|
+
.check(
|
|
355
|
+
z.minLength(1),
|
|
356
|
+
z.describe('Source token symbol, contract address, or token key.'),
|
|
357
|
+
z.meta({ examples: ['usdc'] }),
|
|
358
|
+
),
|
|
359
|
+
})
|
|
360
|
+
.check(z.describe('Funding transfer creation request.')),
|
|
361
|
+
'CreateFundingTransferRequest',
|
|
362
|
+
)
|
|
340
363
|
}
|
|
341
364
|
|
|
342
365
|
/** Stored public snapshot of a funding transfer (see {@link schema.Snapshot}). */
|
|
@@ -22,10 +22,7 @@ const providers = [
|
|
|
22
22
|
integratorId: 'squid-integrator-id',
|
|
23
23
|
userAddress: '0x1111111111111111111111111111111111111111',
|
|
24
24
|
}),
|
|
25
|
-
Stargate.stargate(
|
|
26
|
-
apiKey: 'layerzero-api-key',
|
|
27
|
-
userAddress: '0x1111111111111111111111111111111111111111',
|
|
28
|
-
}),
|
|
25
|
+
Stargate.stargate(),
|
|
29
26
|
Symbiosis.symbiosis({ userAddress: '0x1111111111111111111111111111111111111111' }),
|
|
30
27
|
] as const
|
|
31
28
|
|
|
@@ -340,126 +337,12 @@ describe('funding providers', () => {
|
|
|
340
337
|
})
|
|
341
338
|
})
|
|
342
339
|
|
|
343
|
-
test('maps the best Stargate quote to an available quote result', async () => {
|
|
344
|
-
const requests: RecordedRequest[] = []
|
|
345
|
-
const candidate = quoteCandidate('stargate')
|
|
346
|
-
const fetch = recordingFetch(requests, async () => jsonResponse(stargateQuotes(candidate)))
|
|
347
|
-
const provider = Stargate.stargate({
|
|
348
|
-
apiKey: 'layerzero-api-key',
|
|
349
|
-
baseUrl: 'https://layerzero.test/v1/',
|
|
350
|
-
fetch,
|
|
351
|
-
now,
|
|
352
|
-
userAddress: '0x1111111111111111111111111111111111111111',
|
|
353
|
-
})
|
|
354
|
-
|
|
355
|
-
const result = await provider.getQuote(getQuoteInput(candidate), new AbortController().signal)
|
|
356
|
-
|
|
357
|
-
expect(requests).toHaveLength(1)
|
|
358
|
-
expect(requests[0]?.url.pathname).toBe('/v1/quotes')
|
|
359
|
-
expect(new Headers(requests[0]?.init?.headers).get('user-agent')).toBe('tempo-api')
|
|
360
|
-
expect(new Headers(requests[0]?.init?.headers).get('x-api-key')).toBe('layerzero-api-key')
|
|
361
|
-
expect(jsonRequestBody(requests[0])).toEqual({
|
|
362
|
-
amount: '1000000',
|
|
363
|
-
dstChainKey: 'tempo',
|
|
364
|
-
dstTokenAddress: candidate.destinationToken.address,
|
|
365
|
-
dstWalletAddress: '0x1111111111111111111111111111111111111111',
|
|
366
|
-
options: { amountType: 'EXACT_SRC_AMOUNT' },
|
|
367
|
-
srcChainKey: 'base',
|
|
368
|
-
srcTokenAddress: candidate.sourceToken.address,
|
|
369
|
-
srcWalletAddress: '0x1111111111111111111111111111111111111111',
|
|
370
|
-
})
|
|
371
|
-
expect(result).toEqual({
|
|
372
|
-
expiresAt: '2026-01-01T00:01:00.000Z',
|
|
373
|
-
destinationAmountMin: '999100',
|
|
374
|
-
destinationAmount: '999600',
|
|
375
|
-
quality: {
|
|
376
|
-
estimatedSeconds: 259,
|
|
377
|
-
liquiditySource: 'providerQuote',
|
|
378
|
-
sourceDetail: 'stargate:value-transfer-v1:bus',
|
|
379
|
-
tier: 'liquid',
|
|
380
|
-
},
|
|
381
|
-
sampledAt: '2026-01-01T00:00:00.000Z',
|
|
382
|
-
status: 'available',
|
|
383
|
-
})
|
|
384
|
-
})
|
|
385
|
-
|
|
386
|
-
test('skips expired Stargate alternatives', async () => {
|
|
387
|
-
const candidate = quoteCandidate('stargate')
|
|
388
|
-
const response = stargateQuotes(candidate)
|
|
389
|
-
response.quotes[2]!.expiresAt = '2026-01-01T00:00:00.000Z'
|
|
390
|
-
const provider = Stargate.stargate({
|
|
391
|
-
apiKey: 'layerzero-api-key',
|
|
392
|
-
fetch: recordingFetch([], async () => jsonResponse(response)),
|
|
393
|
-
now,
|
|
394
|
-
userAddress: '0x1111111111111111111111111111111111111111',
|
|
395
|
-
})
|
|
396
|
-
|
|
397
|
-
await expect(
|
|
398
|
-
provider.getQuote(getQuoteInput(candidate), new AbortController().signal),
|
|
399
|
-
).resolves.toMatchObject({
|
|
400
|
-
destinationAmountMin: '999000',
|
|
401
|
-
destinationAmount: '999500',
|
|
402
|
-
quality: {
|
|
403
|
-
sourceDetail: 'stargate:value-transfer-v1:taxi',
|
|
404
|
-
tier: 'liquid',
|
|
405
|
-
},
|
|
406
|
-
status: 'available',
|
|
407
|
-
})
|
|
408
|
-
})
|
|
409
|
-
|
|
410
340
|
test('exposes Base and Ethereum Stargate quote candidates', () => {
|
|
411
341
|
expect(
|
|
412
342
|
['base', 'ethereum'].map((sourceChain) => quoteCandidate('stargate', { sourceChain }).id),
|
|
413
343
|
).toEqual(['base-usdc-tempo-usdce-stargate', 'ethereum-usdc-tempo-usdce-stargate'])
|
|
414
344
|
})
|
|
415
345
|
|
|
416
|
-
test('maps responses without Stargate routes to unavailable quote results', async () => {
|
|
417
|
-
const candidate = quoteCandidate('stargate')
|
|
418
|
-
const response = stargateQuotes(candidate)
|
|
419
|
-
response.quotes = response.quotes.filter((quote) => quote.routeSteps[0]?.type === 'CCTP')
|
|
420
|
-
const provider = Stargate.stargate({
|
|
421
|
-
apiKey: 'layerzero-api-key',
|
|
422
|
-
fetch: recordingFetch([], async () => jsonResponse(response)),
|
|
423
|
-
now,
|
|
424
|
-
userAddress: '0x1111111111111111111111111111111111111111',
|
|
425
|
-
})
|
|
426
|
-
|
|
427
|
-
await expect(
|
|
428
|
-
provider.getQuote(getQuoteInput(candidate), new AbortController().signal),
|
|
429
|
-
).resolves.toMatchObject({
|
|
430
|
-
quality: {
|
|
431
|
-
sourceDetail: 'stargate:value-transfer-v1:NO_STARGATE_ROUTE',
|
|
432
|
-
tier: 'unavailable',
|
|
433
|
-
},
|
|
434
|
-
status: 'unavailable',
|
|
435
|
-
})
|
|
436
|
-
})
|
|
437
|
-
|
|
438
|
-
test('rejects malformed Stargate quotes', async () => {
|
|
439
|
-
const candidate = quoteCandidate('stargate')
|
|
440
|
-
const response = stargateQuotes(candidate)
|
|
441
|
-
response.quotes[2]!.srcAmount = '1'
|
|
442
|
-
const provider = Stargate.stargate({
|
|
443
|
-
apiKey: 'layerzero-api-key',
|
|
444
|
-
fetch: recordingFetch([], async () => jsonResponse(response)),
|
|
445
|
-
now,
|
|
446
|
-
userAddress: '0x1111111111111111111111111111111111111111',
|
|
447
|
-
})
|
|
448
|
-
|
|
449
|
-
await expect(
|
|
450
|
-
provider.getQuote(getQuoteInput(candidate), new AbortController().signal),
|
|
451
|
-
).rejects.toThrowErrorMatchingInlineSnapshot(`[FundingProvider.ProviderPayloadError]`)
|
|
452
|
-
})
|
|
453
|
-
|
|
454
|
-
test('rejects invalid Stargate configuration', () => {
|
|
455
|
-
expect(() =>
|
|
456
|
-
Stargate.stargate({
|
|
457
|
-
apiKey: '',
|
|
458
|
-
userAddress: '0x1111111111111111111111111111111111111111',
|
|
459
|
-
}),
|
|
460
|
-
).toThrowErrorMatchingInlineSnapshot(`[FundingProvider.ProviderConfigurationError]`)
|
|
461
|
-
})
|
|
462
|
-
|
|
463
346
|
test('maps successful Symbiosis quotes to available quote results', async () => {
|
|
464
347
|
const requests: RecordedRequest[] = []
|
|
465
348
|
const candidate = quoteCandidate('symbiosis')
|
|
@@ -1086,29 +969,17 @@ describe('funding providers', () => {
|
|
|
1086
969
|
})
|
|
1087
970
|
})
|
|
1088
971
|
|
|
1089
|
-
test('returns bounded Stargate failure diagnostics',
|
|
1090
|
-
const candidate = quoteCandidate('stargate')
|
|
1091
|
-
const provider = Stargate.stargate({
|
|
1092
|
-
apiKey: 'layerzero-api-key',
|
|
1093
|
-
fetch: recordingFetch([], async () => jsonResponse({ message: 'Unauthorized' }, 401)),
|
|
1094
|
-
now,
|
|
1095
|
-
userAddress: '0x1111111111111111111111111111111111111111',
|
|
1096
|
-
})
|
|
1097
|
-
const cause = await provider
|
|
1098
|
-
.getQuote(getQuoteInput(candidate), new AbortController().signal)
|
|
1099
|
-
.catch((error: unknown) => error)
|
|
1100
|
-
|
|
972
|
+
test('returns bounded Stargate failure diagnostics', () => {
|
|
1101
973
|
expect(
|
|
1102
974
|
FundingProvider.failure({
|
|
1103
|
-
cause,
|
|
975
|
+
cause: new TypeError('network failure'),
|
|
1104
976
|
operation: 'getQuote',
|
|
1105
977
|
provider: getProvider('stargate'),
|
|
1106
978
|
}),
|
|
1107
979
|
).toEqual({
|
|
1108
|
-
failure: '
|
|
980
|
+
failure: 'network',
|
|
1109
981
|
id: 'stargate',
|
|
1110
982
|
operation: 'getQuote',
|
|
1111
|
-
status: 401,
|
|
1112
983
|
})
|
|
1113
984
|
})
|
|
1114
985
|
|
|
@@ -1210,40 +1081,6 @@ function squidQuote(candidate: FundingProvider.getQuote.Parameters['candidate'])
|
|
|
1210
1081
|
}
|
|
1211
1082
|
}
|
|
1212
1083
|
|
|
1213
|
-
function stargateQuotes(candidate: FundingProvider.getQuote.Parameters['candidate']) {
|
|
1214
|
-
return {
|
|
1215
|
-
error: null,
|
|
1216
|
-
quotes: [
|
|
1217
|
-
{
|
|
1218
|
-
dstAmount: '999900',
|
|
1219
|
-
dstAmountMin: '999800',
|
|
1220
|
-
duration: { estimated: '10000' },
|
|
1221
|
-
id: 'quote-cctp',
|
|
1222
|
-
routeSteps: [{ srcChainKey: 'base', type: 'CCTP' }],
|
|
1223
|
-
srcAmount: candidate.sourceAmount.amount,
|
|
1224
|
-
},
|
|
1225
|
-
{
|
|
1226
|
-
dstAmount: '999500',
|
|
1227
|
-
dstAmountMin: '999000',
|
|
1228
|
-
duration: { estimated: '27600' },
|
|
1229
|
-
expiresAt: '2026-01-01T00:01:00.000Z',
|
|
1230
|
-
id: 'quote-stargate-taxi',
|
|
1231
|
-
routeSteps: [{ srcChainKey: 'base', type: 'STARGATE_V2_TAXI' }],
|
|
1232
|
-
srcAmount: candidate.sourceAmount.amount,
|
|
1233
|
-
},
|
|
1234
|
-
{
|
|
1235
|
-
dstAmount: '999600',
|
|
1236
|
-
dstAmountMin: '999100',
|
|
1237
|
-
duration: { estimated: '258899.99999999997' },
|
|
1238
|
-
expiresAt: '2026-01-01T00:01:00.000Z',
|
|
1239
|
-
id: 'quote-stargate-bus',
|
|
1240
|
-
routeSteps: [{ srcChainKey: 'base', type: 'STARGATE_V2_BUS' }],
|
|
1241
|
-
srcAmount: candidate.sourceAmount.amount,
|
|
1242
|
-
},
|
|
1243
|
-
],
|
|
1244
|
-
}
|
|
1245
|
-
}
|
|
1246
|
-
|
|
1247
1084
|
function symbiosisQuote(candidate: FundingProvider.getQuote.Parameters['candidate']) {
|
|
1248
1085
|
const source =
|
|
1249
1086
|
candidate.sourceChain.kind === 'tron'
|
|
@@ -147,8 +147,8 @@ describe.skipIf(!apiKey)('relay.prepareTransfer (live)', () => {
|
|
|
147
147
|
expect(call.data).toMatch(/^0x[0-9a-fA-F]*$/)
|
|
148
148
|
expect(call.value).toBe('0x0')
|
|
149
149
|
}
|
|
150
|
-
expect(result.correlation
|
|
151
|
-
expect(result.correlation
|
|
150
|
+
expect(result.correlation?.requestId).toMatch(/^0x[0-9a-f]{64}$/)
|
|
151
|
+
expect(result.correlation?.checkEndpoint).toContain('/intents/status/v3')
|
|
152
152
|
expect(BigInt(result.destinationAmount) > 0n).toBe(true)
|
|
153
153
|
expect(BigInt(result.destinationAmountMin) > 0n).toBe(true)
|
|
154
154
|
expect(BigInt(result.destinationAmountMin) <= BigInt(result.destinationAmount)).toBe(true)
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { AbiFunction, Hex } from 'ox'
|
|
2
|
+
|
|
3
|
+
import type * as Action from '../Action.js'
|
|
4
|
+
import type * as Catalog from '../Catalog.js'
|
|
5
|
+
import * as FundingProvider from '../Provider.js'
|
|
6
|
+
import * as Stargate from './stargate.js'
|
|
7
|
+
|
|
8
|
+
const amount = 1_000_000n
|
|
9
|
+
const destinationToken = '0x20C000000000000000000000b9537d11c60E8b50'
|
|
10
|
+
const nativeFee = 10_000n
|
|
11
|
+
const otherAddress = '0x9999999999999999999999999999999999999999'
|
|
12
|
+
const pool = '0x27a16dc786820B16E5c9028b75B99F6f604b5d26'
|
|
13
|
+
const recipient = '0x1111111111111111111111111111111111111111'
|
|
14
|
+
const sender = '0x2222222222222222222222222222222222222222'
|
|
15
|
+
const sourceToken = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
|
|
16
|
+
|
|
17
|
+
const approve = AbiFunction.from('function approve(address spender, uint256 amount)')
|
|
18
|
+
const sendToken = AbiFunction.from(
|
|
19
|
+
'function sendToken((uint32 dstEid, bytes32 to, uint256 amountLD, uint256 minAmountLD, bytes extraOptions, bytes composeMsg, bytes oftCmd) sendParam, (uint256 nativeFee, uint256 lzTokenFee) fee, address refundAddress) payable returns ((bytes32 guid, uint64 nonce, (uint256 nativeFee, uint256 lzTokenFee) fee) msgReceipt, (uint256 amountSentLD, uint256 amountReceivedLD) oftReceipt, (uint72 ticketId, bytes passengerBytes) ticket)',
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
describe('stargate', () => {
|
|
23
|
+
test('creates a credential-free quote and transfer provider', () => {
|
|
24
|
+
expect(Stargate.stargate()).toMatchObject({
|
|
25
|
+
getQuote: expect.any(Function),
|
|
26
|
+
id: 'stargate',
|
|
27
|
+
name: 'Stargate',
|
|
28
|
+
prepareTransfer: expect.any(Function),
|
|
29
|
+
})
|
|
30
|
+
})
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
describe('validateAction', () => {
|
|
34
|
+
test('accepts the exact approval and Taxi send calls', () => {
|
|
35
|
+
expect(validate(action())).toEqual([{ to: pool, value: Hex.fromNumber(nativeFee) }])
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
test('rejects calls outside the curated Stargate route', () => {
|
|
39
|
+
const invalid = [
|
|
40
|
+
action({ approvalAmount: amount + 1n }),
|
|
41
|
+
action({ approvalSpender: otherAddress }),
|
|
42
|
+
action({ composeMsg: '0x01' }),
|
|
43
|
+
action({ destinationEid: 1 }),
|
|
44
|
+
action({ executionTarget: otherAddress }),
|
|
45
|
+
action({ extraOptions: '0x01' }),
|
|
46
|
+
action({ lzTokenFee: 1n }),
|
|
47
|
+
action({ minimumAmount: amount - 1n }),
|
|
48
|
+
action({ oftCmd: '0x01' }),
|
|
49
|
+
action({ recipient: otherAddress }),
|
|
50
|
+
action({ refundAddress: otherAddress }),
|
|
51
|
+
action({ sourceAmount: amount + 1n }),
|
|
52
|
+
]
|
|
53
|
+
for (const candidate of invalid)
|
|
54
|
+
expect(() => validate(candidate)).toThrowError(FundingProvider.ProviderPayloadError)
|
|
55
|
+
expect(() => validate(action(), { sourceTokenAddress: otherAddress })).toThrowError(
|
|
56
|
+
FundingProvider.ProviderPayloadError,
|
|
57
|
+
)
|
|
58
|
+
expect(() => validate(action(), { destinationTokenAddress: otherAddress })).toThrowError(
|
|
59
|
+
FundingProvider.ProviderPayloadError,
|
|
60
|
+
)
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
test('rejects malformed selectors and mismatched native value', () => {
|
|
64
|
+
const malformed = action()
|
|
65
|
+
malformed.calls[1]!.data = '0xdeadbeef'
|
|
66
|
+
expect(() => validate(malformed)).toThrowError(FundingProvider.ProviderPayloadError)
|
|
67
|
+
|
|
68
|
+
const mismatched = action()
|
|
69
|
+
mismatched.calls[1]!.value = Hex.fromNumber(nativeFee + 1n)
|
|
70
|
+
expect(() => validate(mismatched)).toThrowError(FundingProvider.ProviderPayloadError)
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
test('rejects missing or mismatched route configuration', () => {
|
|
74
|
+
expect(() =>
|
|
75
|
+
Stargate.validateAction({
|
|
76
|
+
action: action(),
|
|
77
|
+
destinationTokenAddress: destinationToken,
|
|
78
|
+
recipient,
|
|
79
|
+
sender,
|
|
80
|
+
sourceAmount: amount.toString(),
|
|
81
|
+
sourceChainId: 'eip155:8453',
|
|
82
|
+
sourceTokenAddress: sourceToken,
|
|
83
|
+
}),
|
|
84
|
+
).toThrowError(FundingProvider.ProviderPayloadError)
|
|
85
|
+
expect(() => validate(action(), { configuration: { poolAddress: otherAddress } })).toThrowError(
|
|
86
|
+
FundingProvider.ProviderPayloadError,
|
|
87
|
+
)
|
|
88
|
+
})
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
function action(options: action.Options = {}): Action.EvmCalls {
|
|
92
|
+
const executionFee = options.nativeFee ?? nativeFee
|
|
93
|
+
const sendParam = {
|
|
94
|
+
amountLD: options.sourceAmount ?? amount,
|
|
95
|
+
composeMsg: options.composeMsg ?? '0x',
|
|
96
|
+
dstEid: options.destinationEid ?? 30_410,
|
|
97
|
+
extraOptions: options.extraOptions ?? '0x',
|
|
98
|
+
minAmountLD: options.minimumAmount ?? amount,
|
|
99
|
+
oftCmd: options.oftCmd ?? '0x',
|
|
100
|
+
to: Hex.padLeft(options.recipient ?? recipient, 32),
|
|
101
|
+
} as const
|
|
102
|
+
return {
|
|
103
|
+
calls: [
|
|
104
|
+
{
|
|
105
|
+
data: AbiFunction.encodeData(approve, [
|
|
106
|
+
options.approvalSpender ?? pool,
|
|
107
|
+
options.approvalAmount ?? amount,
|
|
108
|
+
]),
|
|
109
|
+
to: sourceToken,
|
|
110
|
+
value: '0x0',
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
data: AbiFunction.encodeData(sendToken, [
|
|
114
|
+
sendParam,
|
|
115
|
+
{ lzTokenFee: options.lzTokenFee ?? 0n, nativeFee: executionFee },
|
|
116
|
+
options.refundAddress ?? sender,
|
|
117
|
+
]),
|
|
118
|
+
to: options.executionTarget ?? pool,
|
|
119
|
+
value: Hex.fromNumber(executionFee),
|
|
120
|
+
},
|
|
121
|
+
],
|
|
122
|
+
type: 'evm:calls',
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
declare namespace action {
|
|
127
|
+
type Options = {
|
|
128
|
+
approvalAmount?: bigint | undefined
|
|
129
|
+
approvalSpender?: `0x${string}` | undefined
|
|
130
|
+
composeMsg?: Hex.Hex | undefined
|
|
131
|
+
destinationEid?: number | undefined
|
|
132
|
+
executionTarget?: `0x${string}` | undefined
|
|
133
|
+
extraOptions?: Hex.Hex | undefined
|
|
134
|
+
lzTokenFee?: bigint | undefined
|
|
135
|
+
minimumAmount?: bigint | undefined
|
|
136
|
+
nativeFee?: bigint | undefined
|
|
137
|
+
oftCmd?: Hex.Hex | undefined
|
|
138
|
+
recipient?: Hex.Hex | undefined
|
|
139
|
+
refundAddress?: `0x${string}` | undefined
|
|
140
|
+
sourceAmount?: bigint | undefined
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function validate(candidate: Action.EvmCalls, options: validate.Options = {}) {
|
|
145
|
+
return Stargate.validateAction({
|
|
146
|
+
action: candidate,
|
|
147
|
+
configuration: options.configuration ?? { poolAddress: pool },
|
|
148
|
+
destinationTokenAddress: options.destinationTokenAddress ?? destinationToken,
|
|
149
|
+
recipient,
|
|
150
|
+
sender,
|
|
151
|
+
sourceAmount: amount.toString(),
|
|
152
|
+
sourceChainId: 'eip155:8453',
|
|
153
|
+
sourceTokenAddress: options.sourceTokenAddress ?? sourceToken,
|
|
154
|
+
})
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
declare namespace validate {
|
|
158
|
+
type Options = {
|
|
159
|
+
configuration?: Catalog.Configuration | undefined
|
|
160
|
+
destinationTokenAddress?: string | undefined
|
|
161
|
+
sourceTokenAddress?: string | undefined
|
|
162
|
+
}
|
|
163
|
+
}
|