crypto-aio 0.2.0 → 1.0.0-rc.1
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/CHANGELOG.md +70 -2
- package/README.md +16 -10
- package/dist/adapters/avalanche/driver.d.ts +4 -0
- package/dist/adapters/avalanche/driver.js.map +1 -1
- package/dist/adapters/avalanche/sdk.d.ts +15 -0
- package/dist/adapters/avalanche/sdk.js.map +1 -1
- package/dist/adapters/evm/plugin.d.ts +1 -0
- package/dist/adapters/evm/plugin.js.map +1 -1
- package/dist/adapters/ton/network.d.ts +1 -0
- package/dist/adapters/ton/network.js +1 -0
- package/dist/adapters/ton/network.js.map +1 -1
- package/dist/adapters/ton/types.d.ts +1 -0
- package/dist/adapters/ton/types.js.map +1 -1
- package/dist/adapters/tron/decode.js +3 -2
- package/dist/adapters/tron/decode.js.map +1 -1
- package/dist/adapters/tron/http.d.ts +6 -0
- package/dist/adapters/tron/http.js +9 -0
- package/dist/adapters/tron/http.js.map +1 -1
- package/dist/adapters/tron/network.d.ts +4 -0
- package/dist/adapters/tron/network.js +4 -0
- package/dist/adapters/tron/network.js.map +1 -1
- package/dist/adapters/tron/proofs.js +6 -2
- package/dist/adapters/tron/proofs.js.map +1 -1
- package/dist/adapters/tron/reader.js +1 -1
- package/dist/adapters/tron/reader.js.map +1 -1
- package/dist/adapters/utxo/driver.d.ts +4 -0
- package/dist/adapters/utxo/driver.js.map +1 -1
- package/dist/adapters/utxo/esplora.d.ts +6 -0
- package/dist/adapters/utxo/esplora.js +20 -3
- package/dist/adapters/utxo/esplora.js.map +1 -1
- package/dist/adapters/utxo/types.d.ts +1 -0
- package/dist/adapters/utxo/types.js.map +1 -1
- package/dist/core/blockchain/handle.d.ts +6 -1
- package/dist/core/blockchain/handle.js +1 -1
- package/dist/core/blockchain/handle.js.map +1 -1
- package/dist/core/config/types.d.ts +64 -0
- package/dist/core/config/types.js.map +1 -1
- package/dist/core/container/container.d.ts +3 -0
- package/dist/core/container/container.js.map +1 -1
- package/dist/core/container/pool.js +12 -0
- package/dist/core/container/pool.js.map +1 -1
- package/dist/core/driver/types.d.ts +124 -7
- package/dist/core/driver/types.js.map +1 -1
- package/dist/core/errors/codes.d.ts +3 -0
- package/dist/core/errors/codes.js.map +1 -1
- package/dist/core/errors/error.d.ts +26 -0
- package/dist/core/errors/error.js +20 -0
- package/dist/core/errors/error.js.map +1 -1
- package/dist/core/events/logger.d.ts +17 -1
- package/dist/core/events/logger.js +5 -1
- package/dist/core/events/logger.js.map +1 -1
- package/dist/core/events/types.d.ts +26 -1
- package/dist/core/events/types.js.map +1 -1
- package/dist/core/lifecycle/engine.d.ts +5 -0
- package/dist/core/lifecycle/engine.js.map +1 -1
- package/dist/core/lifecycle/monitor.d.ts +6 -0
- package/dist/core/lifecycle/monitor.js.map +1 -1
- package/dist/core/lifecycle/views.d.ts +5 -0
- package/dist/core/lifecycle/views.js.map +1 -1
- package/dist/core/lifecycle/workers.d.ts +1 -0
- package/dist/core/lifecycle/workers.js.map +1 -1
- package/dist/core/model/address.d.ts +4 -0
- package/dist/core/model/address.js.map +1 -1
- package/dist/core/model/amount.d.ts +5 -0
- package/dist/core/model/amount.js.map +1 -1
- package/dist/core/model/asset.d.ts +11 -0
- package/dist/core/model/asset.js +2 -0
- package/dist/core/model/asset.js.map +1 -1
- package/dist/core/model/capability.d.ts +6 -0
- package/dist/core/model/capability.js +4 -0
- package/dist/core/model/capability.js.map +1 -1
- package/dist/core/model/chain.d.ts +19 -0
- package/dist/core/model/chain.js +1 -0
- package/dist/core/model/chain.js.map +1 -1
- package/dist/core/model/fee.d.ts +24 -1
- package/dist/core/model/fee.js.map +1 -1
- package/dist/core/model/ids.d.ts +10 -7
- package/dist/core/model/ids.js +1 -0
- package/dist/core/model/ids.js.map +1 -1
- package/dist/core/model/intent.d.ts +13 -0
- package/dist/core/model/intent.js.map +1 -1
- package/dist/core/model/ordering.d.ts +5 -0
- package/dist/core/model/ordering.js.map +1 -1
- package/dist/core/model/transaction.d.ts +39 -0
- package/dist/core/model/transaction.js.map +1 -1
- package/dist/core/observe/scanner.d.ts +10 -1
- package/dist/core/observe/scanner.js +6 -0
- package/dist/core/observe/scanner.js.map +1 -1
- package/dist/core/registry/assets.d.ts +5 -0
- package/dist/core/registry/assets.js.map +1 -1
- package/dist/core/registry/plugin.d.ts +6 -1
- package/dist/core/registry/plugin.js.map +1 -1
- package/dist/core/registry/providers.d.ts +5 -0
- package/dist/core/registry/providers.js.map +1 -1
- package/dist/core/registry/schemes.d.ts +7 -0
- package/dist/core/registry/schemes.js.map +1 -1
- package/dist/core/secret/redact.d.ts +9 -0
- package/dist/core/secret/redact.js +9 -0
- package/dist/core/secret/redact.js.map +1 -1
- package/dist/core/secret/secret.d.ts +4 -0
- package/dist/core/secret/secret.js +4 -0
- package/dist/core/secret/secret.js.map +1 -1
- package/dist/core/signing/callback.d.ts +5 -0
- package/dist/core/signing/callback.js.map +1 -1
- package/dist/core/signing/hd.d.ts +4 -0
- package/dist/core/signing/hd.js.map +1 -1
- package/dist/core/signing/local.d.ts +17 -0
- package/dist/core/signing/local.js +5 -0
- package/dist/core/signing/local.js.map +1 -1
- package/dist/core/signing/types.d.ts +35 -1
- package/dist/core/signing/types.js.map +1 -1
- package/dist/core/store/format.d.ts +3 -3
- package/dist/core/store/format.js +18 -8
- package/dist/core/store/format.js.map +1 -1
- package/dist/core/store/memory.d.ts +11 -0
- package/dist/core/store/memory.js +11 -0
- package/dist/core/store/memory.js.map +1 -1
- package/dist/core/store/types.d.ts +164 -3
- package/dist/core/store/types.js +4 -0
- package/dist/core/store/types.js.map +1 -1
- package/dist/core/transport/http-transport.js +33 -13
- package/dist/core/transport/http-transport.js.map +1 -1
- package/dist/core/transport/types.d.ts +70 -0
- package/dist/core/transport/types.js.map +1 -1
- package/dist/core/util/clock.d.ts +6 -0
- package/dist/core/util/clock.js.map +1 -1
- package/dist/core/util/json.d.ts +6 -0
- package/dist/core/util/json.js +21 -8
- package/dist/core/util/json.js.map +1 -1
- package/dist/testing/contracts/api.d.ts +1 -0
- package/dist/testing/contracts/api.js +1 -0
- package/dist/testing/contracts/api.js.map +1 -1
- package/dist/testing/contracts/cursors.d.ts +5 -0
- package/dist/testing/contracts/cursors.js +4 -0
- package/dist/testing/contracts/cursors.js.map +1 -1
- package/dist/testing/contracts/locks.d.ts +6 -0
- package/dist/testing/contracts/locks.js +5 -0
- package/dist/testing/contracts/locks.js.map +1 -1
- package/dist/testing/contracts/operations.d.ts +11 -0
- package/dist/testing/contracts/operations.js +10 -0
- package/dist/testing/contracts/operations.js.map +1 -1
- package/dist/testing/contracts/sequences.d.ts +5 -0
- package/dist/testing/contracts/sequences.js +4 -0
- package/dist/testing/contracts/sequences.js.map +1 -1
- package/dist/testing/env.d.ts +11 -0
- package/dist/testing/env.js +1 -0
- package/dist/testing/env.js.map +1 -1
- package/dist/testing/fake-chain.d.ts +32 -0
- package/dist/testing/fake-chain.js +11 -0
- package/dist/testing/fake-chain.js.map +1 -1
- package/dist/testing/fake-driver.d.ts +2 -0
- package/dist/testing/fake-driver.js.map +1 -1
- package/dist/testing/fake-fetch.d.ts +6 -0
- package/dist/testing/fake-fetch.js +2 -0
- package/dist/testing/fake-fetch.js.map +1 -1
- package/dist/testing/fake-plugin.d.ts +2 -0
- package/dist/testing/fake-plugin.js +2 -0
- package/dist/testing/fake-plugin.js.map +1 -1
- package/dist/testing/faulty-store.d.ts +2 -0
- package/dist/testing/faulty-store.js +1 -0
- package/dist/testing/faulty-store.js.map +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,73 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.0.0-rc.1] - 2026-11-12
|
|
11
|
+
|
|
12
|
+
The release candidate for 1.0.0. It keeps the API 0.2.0 settled and writes down the
|
|
13
|
+
contract 1.0 keeps: [Versioning and
|
|
14
|
+
stability](https://vhidvz.github.io/crypto-aio/reference/stability.html) lists what semver
|
|
15
|
+
covers surface by surface, [Errors](https://vhidvz.github.io/crypto-aio/reference/errors.html)
|
|
16
|
+
the safe action for every code and the error fields you may rely on, and the plugin and
|
|
17
|
+
store pages what a driver and a durable store must do. It closes the gaps a review of every
|
|
18
|
+
page found in the surfaces 1.0 freezes. Code written for 0.2.0 needs no change unless it
|
|
19
|
+
reads Tron block times (now Unix seconds, as on every family) or writes a plugin driver
|
|
20
|
+
that misdeclares its capabilities; [Upgrade to
|
|
21
|
+
1.0](https://vhidvz.github.io/crypto-aio/reference/upgrading.html) says what changed. It is
|
|
22
|
+
published under npm's `next` tag: `npm install crypto-aio@next`.
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- `CallOptions.endpointLimit`: a transport read without a quorum can mark a definitive
|
|
27
|
+
refusal as the endpoint's own limit, so the read asks the endpoints it has not asked
|
|
28
|
+
instead of failing; the refusal stands only when every endpoint refuses.
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
|
|
32
|
+
- `stringifyTagged` refuses, with a `TypeError`, a plain object whose only key is `$bigint`
|
|
33
|
+
or `$bytes` (with a string value): `parseTagged` would read it back as a bigint or bytes,
|
|
34
|
+
so a durable store built on them refuses the write instead of storing data that reads
|
|
35
|
+
back changed. The format they write is unchanged, and the core never stores such an
|
|
36
|
+
object.
|
|
37
|
+
- A plugin driver that does not implement a capability its manifest and network declare
|
|
38
|
+
(`ChainDriver.capabilities`), or that orders Attempts otherwise than its chain
|
|
39
|
+
(`ordering`), is refused with `CONFIG_INVALID` when its handle first loads it, instead
|
|
40
|
+
of failing later at a port it lacks.
|
|
41
|
+
- During a rolling upgrade, `aio.operations.list()` and `recover()` leave out an
|
|
42
|
+
Operation a newer version stored, with a logged warning, instead of throwing
|
|
43
|
+
`RECORD_FORMAT_UNSUPPORTED` on the first one; a read by id, key or ref still throws.
|
|
44
|
+
- `Scanner`'s constructor is private, so its internal dependencies leave the declarations;
|
|
45
|
+
scanners come from `bc.scanner()`, as before (the package exports `Scanner` as a type
|
|
46
|
+
only).
|
|
47
|
+
- `OperationStore.findByRef` is specified for several Operations of a namespace holding
|
|
48
|
+
one ref, which the core never writes: a store may return any one of them.
|
|
49
|
+
- **Breaking (Tron):** block and transaction `timestamp`s are Unix seconds on every family.
|
|
50
|
+
Tron reported java-tron's milliseconds, so the same field meant another unit there;
|
|
51
|
+
multiply by 1,000 where you relied on milliseconds. Drivers report seconds too.
|
|
52
|
+
- The documentation states the 1.0 contract and corrects what 0.2.0 left stale: proofs
|
|
53
|
+
as 0.2.0 sizes them (a down endpoint still counts, so production wants three or more
|
|
54
|
+
providers), `TX_UNEVIDENCED` as a failure where value may have moved, what abandoning a
|
|
55
|
+
signed transfer leaves possible on each family, Avalanche change in deposit crediting,
|
|
56
|
+
TON's 512-transaction proof window, each family's covered fee and `ext` shapes, the
|
|
57
|
+
rules a driver and a durable store must keep, and a production checklist covering
|
|
58
|
+
stores, providers, keys, workers, monitoring and upgrades. 26 more snippets are
|
|
59
|
+
type-checked by the docs tests.
|
|
60
|
+
|
|
61
|
+
### Removed
|
|
62
|
+
|
|
63
|
+
- The repository's Dependabot configuration: the nightly run tests the newest release of
|
|
64
|
+
every chain SDK, and GitHub's security updates work without it. The runtime
|
|
65
|
+
dependencies `@noble/*` and `@scure/*` stay on their 1.x lines, since their 2.x lines
|
|
66
|
+
are ES modules only, which Jest's CommonJS loader cannot `require`; the pack check now
|
|
67
|
+
loads every entry point under Jest.
|
|
68
|
+
|
|
69
|
+
### Fixed
|
|
70
|
+
|
|
71
|
+
- Bitcoin: an indexer that refuses an address for its own limit (HTTP 400 "Scripthash
|
|
72
|
+
history too large to scan" or "Too many unspent transaction outputs") no longer fails the
|
|
73
|
+
balance, unspent-output or history read when another `indexer` endpoint is configured:
|
|
74
|
+
the read asks it. blockstream.info started refusing busy addresses this way, which failed
|
|
75
|
+
the nightly signet suite.
|
|
76
|
+
|
|
10
77
|
## [0.2.0] - 2026-10-21
|
|
11
78
|
|
|
12
79
|
crypto-aio 0.2.0 settles everything 1.0 will promise: the API is locked by reports in CI,
|
|
@@ -160,8 +227,9 @@ says what to do for each.
|
|
|
160
227
|
|
|
161
228
|
### Added
|
|
162
229
|
|
|
163
|
-
- initial release
|
|
230
|
+
- initial release 🎉🎊.
|
|
164
231
|
|
|
165
|
-
[Unreleased]: https://github.com/vhidvz/crypto-aio/compare/0.
|
|
232
|
+
[Unreleased]: https://github.com/vhidvz/crypto-aio/compare/1.0.0-rc.1...HEAD
|
|
233
|
+
[1.0.0-rc.1]: https://github.com/vhidvz/crypto-aio/compare/0.2.0...1.0.0-rc.1
|
|
166
234
|
[0.2.0]: https://github.com/vhidvz/crypto-aio/compare/0.1.0...0.2.0
|
|
167
235
|
[0.1.0]: https://github.com/vhidvz/crypto-aio/releases/tag/0.1.0
|
package/README.md
CHANGED
|
@@ -37,11 +37,13 @@ node that says "final" about a block that is later replaced. crypto-aio is the l
|
|
|
37
37
|
those cases, written once, with the same API on every chain:
|
|
38
38
|
|
|
39
39
|
- **Pay exactly once.** Every transfer carries your own idempotency key. Repeat the call after a
|
|
40
|
-
timeout, a crash or a lost reply, and you get the same payment back, never a second one
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
timeout, a crash or a lost reply, and you get the same payment back, never a second one
|
|
41
|
+
(across restarts too, with durable stores).
|
|
42
|
+
- **Crash-safe.** With durable stores, a signed transaction is stored before it is sent. After
|
|
43
|
+
a restart, the library sends those exact bytes again; recovery never signs.
|
|
43
44
|
- **Final means proven.** A transfer is final only on finalized chain data that a quorum of
|
|
44
|
-
independent endpoints agree on, never on one node's word
|
|
45
|
+
independent endpoints agree on, never on one node's word, once you configure two or more
|
|
46
|
+
(three keep proofs going through an outage).
|
|
45
47
|
- **Deposits that survive reorgs.** Durable scanners deliver every block at least once, and roll
|
|
46
48
|
back when the chain reorganizes.
|
|
47
49
|
- **Keys stay with signers.** In memory, or behind your HSM, KMS or MPC custody, with a policy
|
|
@@ -118,6 +120,7 @@ configure({
|
|
|
118
120
|
},
|
|
119
121
|
signers: { hot: localSigner({ id: 'hot', secp256k1: secret(process.env.HOT_KEY ?? '') }) },
|
|
120
122
|
wallets: { treasury: { signer: 'hot' } },
|
|
123
|
+
// Two providers cross-check every proof; production wants three, so one outage never stalls it.
|
|
121
124
|
chains: { ethereum: { network: 'sepolia', provider: ['alchemy', 'infura'], wallet: 'treasury' } },
|
|
122
125
|
lifecycle: { requireIdempotencyKey: true },
|
|
123
126
|
});
|
|
@@ -129,6 +132,7 @@ console.log((await eth.getBalance(me.canonical)).amount.format()); // e.g. '0.5
|
|
|
129
132
|
const sub = await eth.transfer(
|
|
130
133
|
{ to: '0x3535353535353535353535353535353535353535', amount: '0.01' },
|
|
131
134
|
{ idempotencyKey: 'withdrawal-42' }, // your own id: repeating the call never pays twice
|
|
135
|
+
// (across restarts too, once `stores` are durable)
|
|
132
136
|
);
|
|
133
137
|
const { status } = await sub.wait({ finality: 'final' });
|
|
134
138
|
console.log(status.state, status.evidence); // 'final' 'proven'
|
|
@@ -151,12 +155,14 @@ family.
|
|
|
151
155
|
|
|
152
156
|
## Status
|
|
153
157
|
|
|
154
|
-
crypto-aio is
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
API
|
|
158
|
-
|
|
159
|
-
|
|
158
|
+
crypto-aio 1.0 is in release candidate: **1.0.0-rc.1**, on npm's `next` tag
|
|
159
|
+
(`npm install crypto-aio@next`). From 1.0.0, [semantic
|
|
160
|
+
versioning](https://vhidvz.github.io/crypto-aio/reference/stability.html) covers what that
|
|
161
|
+
page lists: the API, the driver port and what a process stores, but not `crypto-aio/native`
|
|
162
|
+
or message texts. The 0.0.x releases on npm are an older, unrelated API. [Known
|
|
163
|
+
limitations](https://vhidvz.github.io/crypto-aio/reference/limitations.html) lists what it
|
|
164
|
+
does not do yet, and [Upgrade to 1.0](https://vhidvz.github.io/crypto-aio/reference/upgrading.html)
|
|
165
|
+
what changes from 0.2.0 and 0.1.0. Only in-memory stores ship: production needs durable stores of your
|
|
160
166
|
own, proven with the contract suites in `crypto-aio/testing`; [examples/postgres-store](examples/postgres-store)
|
|
161
167
|
is a reference implementation on PostgreSQL. Release notes are in the [changelog](CHANGELOG.md).
|
|
162
168
|
|
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import type { DriverFactory } from '../../core/driver/types';
|
|
7
7
|
import { type AvalancheSdk, type SdkContext } from './sdk';
|
|
8
|
+
/**
|
|
9
|
+
* What `native(bc, '@avalabs/avalanchejs')` hands out. It mirrors the SDK, so it is outside
|
|
10
|
+
* semver: a new avalanchejs line may change it in a minor release.
|
|
11
|
+
*/
|
|
8
12
|
export interface AvalancheNativeClient {
|
|
9
13
|
/**
|
|
10
14
|
* The `@avalabs/avalanchejs` module. Its type names the members this library uses; cast
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"driver.js","sourceRoot":"","sources":["../../../src/adapters/avalanche/driver.ts"],"names":[],"mappings":";;;AAMA,mDAAsD;AAEtD,+BAAwE;AACxE,uCAAgF;AAChF,mCAAqC;AACrC,uCAAuE;AACvE,uCAAgF;AAChF,qCAAoD;AACpD,qCAAkF;AAClF,+BAAsE;
|
|
1
|
+
{"version":3,"file":"driver.js","sourceRoot":"","sources":["../../../src/adapters/avalanche/driver.ts"],"names":[],"mappings":";;;AAMA,mDAAsD;AAEtD,+BAAwE;AACxE,uCAAgF;AAChF,mCAAqC;AACrC,uCAAuE;AACvE,uCAAgF;AAChF,qCAAoD;AACpD,qCAAkF;AAClF,+BAAsE;AAsBtE,SAAS,UAAU,CAAC,MAA8B;IAChD,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC;IACxD,OAAO;QACL,QAAQ,EAAE,KAAK,EAAE,IAAkB,EAAE,EAAE,CACrC,IAAA,gBAAU,EACR,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,mBAAmB,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAChF,CAAC,EAAE;QACN,gBAAgB,EAAE,MAAM,CAAC,cAAc;QACvC,MAAM,EAAE,KAAK,EAAE,IAAkB,EAAE,EAAE,CACnC,IAAA,iBAAW,EACR,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,YAAY,EAAE,EAAE,CAAC,CAAiC;YAC1E,EAAE,MAAM,CACX;KACJ,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,MAA8B;IACnD,OAAO;QACL,QAAQ,EAAE,KAAK,EAAE,IAAkB,EAAE,EAAE,CACrC,aAAO,CAAC,SAAS,CACf,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CAC5E;QACH,gBAAgB,EAAE,MAAM,CAAC,cAAc;QACvC,MAAM,EAAE,KAAK,EAAE,IAAkB,EAAE,EAAE,CACnC,aAAO,CAAC,YAAY,CAClB,MAAM,IAAI,CAAC,IAAI,CAAC;YACd,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE;YACxB,KAAK,EAAE,SAAS;SACjB,CAAC,CACH;KACJ,CAAC;AACJ,CAAC;AAEY,QAAA,sBAAsB,GAAkB;IACnD,KAAK,CAAC,MAAM,CAAC,GAAkB;QAC7B,MAAM,MAAM,GAAG,IAAA,gCAAsB,EAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QAC3E,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,IAAI,mBAAW,CACnB,gBAAgB,EAChB,4EAA4E,CAC7E,CAAC;QACJ,CAAC;QACD,kFAAkF;QAClF,mFAAmF;QACnF,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;QAC5C,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;QAC7C,MAAM,IAAI,GAAqB;YAC7B,IAAI,EAAE,IAAI,mBAAa,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC;YACjD,OAAO,EAAE,IAAI,aAAO,CAAC,GAAG,CAAC,OAAO,CAAC;YACjC,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,MAAM;YACN,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,GAAG,EAAE,GAAG,CAAC,GAAG;YACZ,OAAO,EAAE,IAAI,uBAAa,EAAE;SAC7B,CAAC;QACF,OAAO;YACL,QAAQ,EAAE,QAAQ;YAClB,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,OAAO,EAAE,IAAA,qBAAY,EAAC,IAAI,CAAC;YAC3B,MAAM,EAAE,IAAA,oBAAW,EAAC,IAAI,CAAC;YACzB,OAAO,EAAE,IAAA,0BAAgB,EAAC,IAAI,CAAC;YAC/B,WAAW,EAAE,IAAA,8BAAoB,EAAC,IAAI,CAAC;YACvC,MAAM,EAAE,IAAA,oBAAW,EAAC,IAAI,CAAC;YACzB,MAAM,EAAE,IAAA,oBAAW,EAAC,IAAI,CAAC;YACzB,OAAO,EAAE,IAAA,uBAAc,EAAC,IAAI,CAAC;YAC7B,GAAG,EAAE;gBACH,SAAS,EAAE;oBACT,WAAW,EAAE,CAAC,OAAe,EAAE,EAAE,CAAC,IAAA,oBAAW,EAAC,IAAI,EAAE,OAAO,CAAC;iBAC7D;aACqB;YACxB,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,qBAAW,EAAE,CAAC;YAC3C,kBAAkB,EAAE,GAAG,EAAE;gBACvB,MAAM,MAAM,GAA0B;oBACpC,SAAS,EAAT,eAAS;oBACT,OAAO,EAAE,IAAA,kBAAU,EAAC,MAAM,CAAC;oBAC3B,GAAG,EAAE,CAAI,MAAc,EAAE,MAAgB,EAAE,EAAE,CAC3C,GAAG,CAAC,SAAS,CAAC,GAAG,CAAI,MAAM,EAAE,MAAM,IAAI,EAAE,EAAE,cAAI,CAAC;iBACnD,CAAC;gBACF,OAAO,EAAE,MAAM,EAAE,CAAC;YACpB,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC","sourcesContent":["/**\n * The Avalanche driver factory: validated network config, endpoint probes on both\n * transports, and the ports. Loaded only by the manifest's `load()`, with\n * `@avalabs/avalanchejs`.\n */\nimport type { ChainDriver, DriverContext, DriverFactory } from '../../core/driver/types';\nimport { ConfigError } from '../../core/errors/error';\nimport type { EndpointCall, HealthProbes } from '../../core/transport/types';\nimport { AvalancheNode, DataApi, parseBlock, parseHeight } from './api';\nimport { avalancheBroadcaster, avalancheBuilder, MAX_OUTPUTS } from './builder';\nimport { sdkContext } from './codec';\nimport { LocationCache, READ, type AvalancheContext } from './context';\nimport { avalancheNetworkConfig, type AvalancheNetworkConfig } from './network';\nimport { blockSource, proofSource } from './proofs';\nimport { addressCodec, addressHistory, chainReader, listUnspent } from './reader';\nimport { avalanche, type AvalancheSdk, type SdkContext } from './sdk';\nimport type { AvalancheExt } from './types';\n\n/**\n * What `native(bc, '@avalabs/avalanchejs')` hands out. It mirrors the SDK, so it is outside\n * semver: a new avalanchejs line may change it in a minor release.\n */\nexport interface AvalancheNativeClient {\n /**\n * The `@avalabs/avalanchejs` module. Its type names the members this library uses; cast\n * it to reach the rest of the SDK.\n */\n readonly avalanche: AvalancheSdk;\n /**\n * avalanchejs's `Context` for this network and chain (network id, HRP, AVAX asset id,\n * this chain's id). Its fee fields are zero: read the fees from the chain.\n */\n readonly context: SdkContext;\n /** A JSON-RPC call (e.g. `avm.getTxFee`) to the handle's node endpoints, through the transport. */\n rpc<T = unknown>(method: string, params?: unknown): Promise<T>;\n}\n\nfunction nodeProbes(config: AvalancheNetworkConfig): HealthProbes {\n const prefix = config.vm === 'avm' ? 'avm' : 'platform';\n return {\n identity: async (call: EndpointCall) =>\n parseBlock(\n await call.rpc(`${prefix}.getBlockByHeight`, { height: '0', encoding: 'json' }),\n ).id,\n expectedIdentity: config.genesisBlockId,\n height: async (call: EndpointCall) =>\n parseHeight(\n ((await call.rpc(`${prefix}.getHeight`, {})) as { height?: unknown } | null)\n ?.height,\n ),\n };\n}\n\nfunction indexerProbes(config: AvalancheNetworkConfig): HealthProbes {\n return {\n identity: async (call: EndpointCall) =>\n DataApi.blockZero(\n await call.http({ method: 'GET', path: '/blocks/0', route: '/blocks/:id' }),\n ),\n expectedIdentity: config.genesisBlockId,\n height: async (call: EndpointCall) =>\n DataApi.latestHeight(\n await call.http({\n method: 'GET',\n path: '/blocks',\n query: { pageSize: '1' },\n route: '/blocks',\n }),\n ),\n };\n}\n\nexport const avalancheDriverFactory: DriverFactory = {\n async create(ctx: DriverContext): Promise<ChainDriver> {\n const config = avalancheNetworkConfig(ctx.chain, ctx.network, ctx.options);\n if (!ctx.indexer) {\n throw new ConfigError(\n 'CONFIG_INVALID',\n 'the Avalanche driver requires an indexer provider (the Avalanche Data API)',\n );\n }\n // Probes on both transports, once, before any traffic: without them an endpoint's\n // identity is never checked, and an endpoint of another network is never disabled.\n ctx.transport.setProbes(nodeProbes(config));\n ctx.indexer.setProbes(indexerProbes(config));\n const avax: AvalancheContext = {\n node: new AvalancheNode(ctx.transport, config.vm),\n dataApi: new DataApi(ctx.indexer),\n chain: ctx.chain,\n network: ctx.network,\n config,\n clock: ctx.clock,\n log: ctx.log,\n located: new LocationCache(),\n };\n return {\n ordering: 'inputs',\n capabilities: config.capabilities,\n address: addressCodec(avax),\n reader: chainReader(avax),\n builder: avalancheBuilder(avax),\n broadcaster: avalancheBroadcaster(avax),\n proofs: proofSource(avax),\n blocks: blockSource(avax),\n history: addressHistory(avax),\n ext: {\n avalanche: {\n listUnspent: (address: string) => listUnspent(avax, address),\n },\n } satisfies AvalancheExt,\n limits: () => ({ maxOutputs: MAX_OUTPUTS }),\n createNativeClient: () => {\n const client: AvalancheNativeClient = {\n avalanche,\n context: sdkContext(config),\n rpc: <T>(method: string, params?: unknown) =>\n ctx.transport.rpc<T>(method, params ?? {}, READ),\n };\n return { client };\n },\n };\n },\n};\n"]}
|
|
@@ -11,19 +11,24 @@
|
|
|
11
11
|
export interface SdkSerializable {
|
|
12
12
|
readonly _type: string;
|
|
13
13
|
}
|
|
14
|
+
/** The part of avalanchejs's `Id` this library uses; it mirrors the SDK, outside semver. */
|
|
14
15
|
export interface SdkId {
|
|
15
16
|
toString(): string;
|
|
16
17
|
toBytes(): Uint8Array;
|
|
17
18
|
}
|
|
19
|
+
/** The part of avalanchejs's `Int` this library uses; it mirrors the SDK, outside semver. */
|
|
18
20
|
export interface SdkInt {
|
|
19
21
|
value(): number;
|
|
20
22
|
}
|
|
23
|
+
/** The part of avalanchejs's `BigIntPr` this library uses; it mirrors the SDK, outside semver. */
|
|
21
24
|
export interface SdkBigInt {
|
|
22
25
|
value(): bigint;
|
|
23
26
|
}
|
|
27
|
+
/** The part of avalanchejs's `Address` this library uses; it mirrors the SDK, outside semver. */
|
|
24
28
|
export interface SdkAddress {
|
|
25
29
|
toBytes(): Uint8Array;
|
|
26
30
|
}
|
|
31
|
+
/** The part of avalanchejs's `OutputOwners` this library uses; it mirrors the SDK, outside semver. */
|
|
27
32
|
export interface SdkOutputOwners {
|
|
28
33
|
readonly locktime: SdkBigInt;
|
|
29
34
|
readonly threshold: SdkInt;
|
|
@@ -34,21 +39,25 @@ export interface SdkTransferOutput extends SdkSerializable {
|
|
|
34
39
|
readonly outputOwners: SdkOutputOwners;
|
|
35
40
|
amount(): bigint;
|
|
36
41
|
}
|
|
42
|
+
/** The part of avalanchejs's `TransferableOutput` this library uses; it mirrors the SDK, outside semver. */
|
|
37
43
|
export interface SdkTransferableOutput extends SdkSerializable {
|
|
38
44
|
readonly assetId: SdkId;
|
|
39
45
|
readonly output: SdkSerializable;
|
|
40
46
|
amount(): bigint;
|
|
41
47
|
}
|
|
48
|
+
/** The part of avalanchejs's `UTXOID` this library uses; it mirrors the SDK, outside semver. */
|
|
42
49
|
export interface SdkUtxoId {
|
|
43
50
|
readonly txID: SdkId;
|
|
44
51
|
readonly outputIdx: SdkInt;
|
|
45
52
|
}
|
|
53
|
+
/** The part of avalanchejs's `TransferableInput` this library uses; it mirrors the SDK, outside semver. */
|
|
46
54
|
export interface SdkTransferableInput extends SdkSerializable {
|
|
47
55
|
readonly utxoID: SdkUtxoId;
|
|
48
56
|
readonly assetId: SdkId;
|
|
49
57
|
amount(): bigint;
|
|
50
58
|
sigIndicies(): number[];
|
|
51
59
|
}
|
|
60
|
+
/** The part of avalanchejs's `Utxo` this library uses; it mirrors the SDK, outside semver. */
|
|
52
61
|
export interface SdkUtxo extends SdkSerializable {
|
|
53
62
|
readonly utxoId: SdkUtxoId;
|
|
54
63
|
readonly assetId: SdkId;
|
|
@@ -72,10 +81,12 @@ export interface SdkTransaction extends SdkSerializable {
|
|
|
72
81
|
readonly baseTx?: SdkBaseTx;
|
|
73
82
|
getSigIndices(): number[][];
|
|
74
83
|
}
|
|
84
|
+
/** The part of avalanchejs's `Credential` this library uses; it mirrors the SDK, outside semver. */
|
|
75
85
|
export interface SdkCredential extends SdkSerializable {
|
|
76
86
|
/** Each signature as hex (65 bytes: r, s, recovery id). */
|
|
77
87
|
getSignatures(): string[];
|
|
78
88
|
}
|
|
89
|
+
/** The part of avalanchejs's `SignedTx` this library uses; it mirrors the SDK, outside semver. */
|
|
79
90
|
export interface SdkSignedTx {
|
|
80
91
|
readonly unsignedTx: SdkTransaction;
|
|
81
92
|
getCredentials(): SdkCredential[];
|
|
@@ -86,6 +97,7 @@ export interface SdkUnsignedTx {
|
|
|
86
97
|
getTx(): SdkTransaction;
|
|
87
98
|
toBytes(): Uint8Array;
|
|
88
99
|
}
|
|
100
|
+
/** The part of avalanchejs's `codec Manager` this library uses; it mirrors the SDK, outside semver. */
|
|
89
101
|
export interface SdkManager {
|
|
90
102
|
getDefaultCodec(): unknown;
|
|
91
103
|
unpack<T>(bytes: Uint8Array, unpacker: SdkUnpacker<T>): T;
|
|
@@ -96,6 +108,7 @@ export interface SdkManager {
|
|
|
96
108
|
export interface SdkUnpacker<T> {
|
|
97
109
|
fromBytes(bytes: Uint8Array, codec: unknown): [T, Uint8Array];
|
|
98
110
|
}
|
|
111
|
+
/** The part of avalanchejs's `fee Dimensions` this library uses; it mirrors the SDK, outside semver. */
|
|
99
112
|
export interface SdkDimensions {
|
|
100
113
|
readonly 0: number;
|
|
101
114
|
readonly 1: number;
|
|
@@ -121,12 +134,14 @@ export interface SdkContext {
|
|
|
121
134
|
readonly excessConversionConstant: bigint;
|
|
122
135
|
};
|
|
123
136
|
}
|
|
137
|
+
/** The part of avalanchejs's `FeeState` this library uses; it mirrors the SDK, outside semver. */
|
|
124
138
|
export interface SdkFeeState {
|
|
125
139
|
readonly capacity: bigint;
|
|
126
140
|
readonly excess: bigint;
|
|
127
141
|
readonly price: bigint;
|
|
128
142
|
readonly timestamp: string;
|
|
129
143
|
}
|
|
144
|
+
/** The part of avalanchejs's `Signature` this library uses; it mirrors the SDK, outside semver. */
|
|
130
145
|
export interface SdkSignature extends SdkSerializable {
|
|
131
146
|
toString(): string;
|
|
132
147
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.js","sourceRoot":"","sources":["../../../src/adapters/avalanche/sdk.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;
|
|
1
|
+
{"version":3,"file":"sdk.js","sourceRoot":"","sources":["../../../src/adapters/avalanche/sdk.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AA4NH,iEAAiE;AACpD,QAAA,SAAS,GAAG,OAAO,CAAC,sBAAsB,CAAiB,CAAC;AAEzE,2DAA2D;AAC9C,QAAA,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;IACjC,cAAc,EAAE,4BAA4B;IAC5C,gBAAgB,EAAE,sBAAsB;IACxC,UAAU,EAAE,wBAAwB;CACrC,CAAC,CAAC","sourcesContent":["/**\n * The one place that loads `@avalabs/avalanchejs`, at run time with `require()` (its 5.x\n * package is an ES module with a CommonJS build). Its type declarations re-export their own\n * modules without file extensions, which TypeScript cannot follow under `node16`\n * resolution, so the part of the SDK this library uses is declared here instead: the codec\n * managers, the transaction builders, the P-Chain fee calculator and the serializable\n * classes the driver reads. The tests run every declared member against the real package.\n * Loaded only through the manifest's `load()`.\n */\n\n/** A serializable avalanchejs object; `_type` names its class (e.g. `avm.BaseTx`). */\nexport interface SdkSerializable {\n readonly _type: string;\n}\n\n/** The part of avalanchejs's `Id` this library uses; it mirrors the SDK, outside semver. */\nexport interface SdkId {\n toString(): string;\n toBytes(): Uint8Array;\n}\n\n/** The part of avalanchejs's `Int` this library uses; it mirrors the SDK, outside semver. */\nexport interface SdkInt {\n value(): number;\n}\n\n/** The part of avalanchejs's `BigIntPr` this library uses; it mirrors the SDK, outside semver. */\nexport interface SdkBigInt {\n value(): bigint;\n}\n\n/** The part of avalanchejs's `Address` this library uses; it mirrors the SDK, outside semver. */\nexport interface SdkAddress {\n toBytes(): Uint8Array;\n}\n\n/** The part of avalanchejs's `OutputOwners` this library uses; it mirrors the SDK, outside semver. */\nexport interface SdkOutputOwners {\n readonly locktime: SdkBigInt;\n readonly threshold: SdkInt;\n readonly addrs: readonly SdkAddress[];\n}\n\n/** A `secp256k1fx.TransferOutput`. */\nexport interface SdkTransferOutput extends SdkSerializable {\n readonly outputOwners: SdkOutputOwners;\n amount(): bigint;\n}\n\n/** The part of avalanchejs's `TransferableOutput` this library uses; it mirrors the SDK, outside semver. */\nexport interface SdkTransferableOutput extends SdkSerializable {\n readonly assetId: SdkId;\n readonly output: SdkSerializable;\n amount(): bigint;\n}\n\n/** The part of avalanchejs's `UTXOID` this library uses; it mirrors the SDK, outside semver. */\nexport interface SdkUtxoId {\n readonly txID: SdkId;\n readonly outputIdx: SdkInt;\n}\n\n/** The part of avalanchejs's `TransferableInput` this library uses; it mirrors the SDK, outside semver. */\nexport interface SdkTransferableInput extends SdkSerializable {\n readonly utxoID: SdkUtxoId;\n readonly assetId: SdkId;\n amount(): bigint;\n sigIndicies(): number[];\n}\n\n/** The part of avalanchejs's `Utxo` this library uses; it mirrors the SDK, outside semver. */\nexport interface SdkUtxo extends SdkSerializable {\n readonly utxoId: SdkUtxoId;\n readonly assetId: SdkId;\n readonly output: SdkSerializable;\n /** Its bytes without the codec version, in `codec`. */\n toBytes(codec: unknown): Uint8Array;\n}\n\n/** The `avax.BaseTx` every X-Chain and most P-Chain transactions carry. */\nexport interface SdkBaseTx {\n readonly NetworkId: SdkInt;\n readonly BlockchainId: SdkId;\n readonly outputs: readonly SdkTransferableOutput[];\n readonly inputs: readonly SdkTransferableInput[];\n readonly memo: { readonly bytes: Uint8Array };\n}\n\n/** An unsigned transaction of any type (`avm.*`, `pvm.*`). */\nexport interface SdkTransaction extends SdkSerializable {\n readonly vm: string;\n readonly baseTx?: SdkBaseTx;\n getSigIndices(): number[][];\n}\n\n/** The part of avalanchejs's `Credential` this library uses; it mirrors the SDK, outside semver. */\nexport interface SdkCredential extends SdkSerializable {\n /** Each signature as hex (65 bytes: r, s, recovery id). */\n getSignatures(): string[];\n}\n\n/** The part of avalanchejs's `SignedTx` this library uses; it mirrors the SDK, outside semver. */\nexport interface SdkSignedTx {\n readonly unsignedTx: SdkTransaction;\n getCredentials(): SdkCredential[];\n toBytes(): Uint8Array;\n}\n\n/** A builder's result. */\nexport interface SdkUnsignedTx {\n getTx(): SdkTransaction;\n toBytes(): Uint8Array;\n}\n\n/** The part of avalanchejs's `codec Manager` this library uses; it mirrors the SDK, outside semver. */\nexport interface SdkManager {\n getDefaultCodec(): unknown;\n unpack<T>(bytes: Uint8Array, unpacker: SdkUnpacker<T>): T;\n unpackTransaction(bytes: Uint8Array): SdkTransaction;\n packCodec(serializable: SdkSerializable): Uint8Array;\n}\n\n/** A class `Manager.unpack` reads (`Utxo`, `avaxSerial.SignedTx`). */\nexport interface SdkUnpacker<T> {\n fromBytes(bytes: Uint8Array, codec: unknown): [T, Uint8Array];\n}\n\n/** The part of avalanchejs's `fee Dimensions` this library uses; it mirrors the SDK, outside semver. */\nexport interface SdkDimensions {\n readonly 0: number;\n readonly 1: number;\n readonly 2: number;\n readonly 3: number;\n}\n\n/** avalanchejs's `Context`: what its builders need to know about the network. */\nexport interface SdkContext {\n readonly networkID: number;\n readonly hrp: string;\n readonly xBlockchainID: string;\n readonly pBlockchainID: string;\n readonly cBlockchainID: string;\n readonly avaxAssetID: string;\n readonly baseTxFee: bigint;\n readonly createAssetTxFee: bigint;\n readonly platformFeeConfig: {\n readonly weights: SdkDimensions;\n readonly maxCapacity: bigint;\n readonly maxPerSecond: bigint;\n readonly targetPerSecond: bigint;\n readonly minPrice: bigint;\n readonly excessConversionConstant: bigint;\n };\n}\n\n/** The part of avalanchejs's `FeeState` this library uses; it mirrors the SDK, outside semver. */\nexport interface SdkFeeState {\n readonly capacity: bigint;\n readonly excess: bigint;\n readonly price: bigint;\n readonly timestamp: string;\n}\n\n/** The part of avalanchejs's `Signature` this library uses; it mirrors the SDK, outside semver. */\nexport interface SdkSignature extends SdkSerializable {\n toString(): string;\n}\n\n/** The members of `@avalabs/avalanchejs` this library calls. */\nexport interface AvalancheSdk {\n readonly Utxo: SdkUnpacker<SdkUtxo>;\n readonly avaxSerial: {\n readonly SignedTx: SdkUnpacker<SdkSignedTx> &\n (new (tx: SdkTransaction, credentials: SdkSerializable[]) => SdkSignedTx);\n };\n readonly Credential: new (signatures: SdkSignature[]) => SdkCredential;\n readonly Signature: new (bytes: Uint8Array) => SdkSignature;\n readonly TransferableOutput: {\n fromNative(\n assetId: string,\n amount: bigint,\n addresses: readonly Uint8Array[],\n locktime?: bigint,\n threshold?: number,\n ): SdkTransferableOutput;\n };\n readonly Common: {\n createDimensions(dimensions: {\n bandwidth: number;\n dbRead: number;\n dbWrite: number;\n compute: number;\n }): SdkDimensions;\n };\n readonly utils: {\n getManagerForVM(vm: 'AVM' | 'PVM'): SdkManager;\n getBurnedAmountByTx(tx: SdkTransaction, context: SdkContext): Map<string, bigint>;\n };\n readonly avm: {\n newBaseTx(\n context: SdkContext,\n fromAddressesBytes: readonly Uint8Array[],\n utxos: readonly SdkUtxo[],\n outputs: readonly SdkTransferableOutput[],\n options: {\n readonly changeAddresses: readonly Uint8Array[];\n readonly memo: Uint8Array;\n readonly minIssuanceTime: bigint;\n },\n ): SdkUnsignedTx;\n };\n readonly pvm: {\n newBaseTx(\n props: {\n readonly feeState: SdkFeeState;\n readonly fromAddressesBytes: readonly Uint8Array[];\n readonly changeAddressesBytes: readonly Uint8Array[];\n readonly outputs: readonly SdkTransferableOutput[];\n readonly utxos: readonly SdkUtxo[];\n readonly memo: Uint8Array;\n readonly minIssuanceTime: bigint;\n },\n context: SdkContext,\n ): SdkUnsignedTx;\n calculateFee(tx: SdkTransaction, weights: SdkDimensions, price: bigint): bigint;\n };\n}\n\n// eslint-disable-next-line @typescript-eslint/no-require-imports\nexport const avalanche = require('@avalabs/avalanchejs') as AvalancheSdk;\n\n/** The serializable class names the driver tells apart. */\nexport const TYPES = Object.freeze({\n transferOutput: 'secp256k1fx.TransferOutput',\n stakeableLockOut: 'pvm.StakeableLockOut',\n credential: 'secp256k1fx.Credential',\n});\n"]}
|
|
@@ -12,6 +12,7 @@ export declare function evmManifests(family: string, chains: readonly string[]):
|
|
|
12
12
|
* Arbitrum One, OP Mainnet and Base, with their testnets.
|
|
13
13
|
*/
|
|
14
14
|
export declare function evmPlugin(): Plugin;
|
|
15
|
+
/** `evmChainPlugin()`'s options: one EVM chain to register, with its networks and tokens. */
|
|
15
16
|
export interface EvmChainPluginOptions {
|
|
16
17
|
/**
|
|
17
18
|
* A unique name matching `/^[a-z][a-z0-9-]*$/`. The plugin registers as `evm:<name>`, so
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../../src/adapters/evm/plugin.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The EVM family plugin: chains, tokens and provider presets as data, plus one\n * adapter manifest per library. SDK-free: only a manifest's `load()` requires a client\n * module, and with it the SDK. `ethers` is registered first, so it is the family default.\n */\nimport { keccak_256 } from '@noble/hashes/sha3';\nimport type {\n AdapterManifest,\n DriverFactory,\n PeerDependency,\n} from '../../core/driver/types';\nimport { ConfigError } from '../../core/errors/error';\nimport type { ChainInfo } from '../../core/model/chain';\nimport type { AssetRegistration } from '../../core/registry/assets';\nimport type { Plugin } from '../../core/registry/plugin';\nimport type { ProviderPreset } from '../../core/registry/providers';\nimport { toHex, utf8ToBytes } from '../../core/util/bytes';\nimport { EVM_CHAINS } from './chains';\nimport { EVM_CAPABILITIES, evmNetworkConfig } from './network';\nimport { EVM_PRESETS } from './presets';\nimport { EVM_TOKENS } from './tokens';\n\n/** The SDK versions this adapter is validated against. */\nexport const EVM_PEER_DEPENDENCIES: Readonly<Record<'ethers' | 'web3', PeerDependency>> =\n {\n ethers: { name: 'ethers', range: '^6.17.0' },\n web3: { name: 'web3', range: '^4.16.0' },\n };\n\n/**\n * The manifests' `load` functions, shared by every `evmManifests(...)` call, so that\n * registering `evmPlugin()` or the same `evmChainPlugin(...)` again is the same plugin:\n * the registry compares a plugin's functions by identity, and refuses a different plugin\n * under a registered name. Each `require`s its client module, and with it the SDK, only\n * when called.\n */\nconst loadEthers = async (): Promise<DriverFactory> => {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const mod = require('./ethers-client') as typeof import('./ethers-client');\n return mod.ethersDriverFactory;\n};\n\nconst loadWeb3 = async (): Promise<DriverFactory> => {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const mod = require('./web3-client') as typeof import('./web3-client');\n return mod.web3DriverFactory;\n};\n\n/** The `ethers` and `web3` manifests for `chains`, keyed `<family>/<library>`. */\nexport function evmManifests(\n family: string,\n chains: readonly string[],\n): AdapterManifest[] {\n return [\n {\n family,\n library: 'ethers',\n chains,\n capabilities: EVM_CAPABILITIES,\n peerDependencies: [EVM_PEER_DEPENDENCIES.ethers],\n load: loadEthers,\n },\n {\n family,\n library: 'web3',\n chains,\n capabilities: EVM_CAPABILITIES,\n peerDependencies: [EVM_PEER_DEPENDENCIES.web3],\n load: loadWeb3,\n },\n ];\n}\n\n/**\n * The built-in EVM family: Ethereum, BNB Smart Chain, Polygon PoS, Avalanche C-Chain,\n * Arbitrum One, OP Mainnet and Base, with their testnets.\n */\nexport function evmPlugin(): Plugin {\n return {\n name: 'evm',\n chains: EVM_CHAINS,\n adapters: evmManifests(\n 'evm',\n EVM_CHAINS.map((chain) => chain.id),\n ),\n presets: EVM_PRESETS,\n assets: EVM_TOKENS,\n };\n}\n\n/** A plugin name: lower-case letters, digits and hyphens, starting with a letter. */\nconst PLUGIN_NAME = /^[a-z][a-z0-9-]*$/;\n\n/** `0x` and 40 hex digits, in any case. */\nconst HEX_ADDRESS = /^0x[0-9a-fA-F]{40}$/;\n\n/** EIP-55: each letter upper-cased where the keccak-256 of the lower-case hex has 8 or more. */\nfunction eip55(address: string): string {\n const hex = address.slice(2).toLowerCase();\n const hash = toHex(keccak_256(utf8ToBytes(hex)));\n let out = '0x';\n for (let i = 0; i < hex.length; i++) {\n const c = hex[i] as string;\n out += Number.parseInt(hash[i] as string, 16) >= 8 ? c.toUpperCase() : c;\n }\n return out;\n}\n\n/**\n * An ERC-20 registration under the contract the driver names it by. The driver normalizes\n * every token ref it is given, reads or decodes to the EIP-55 form, and an asset id carries\n * the contract as registered, so a lower-case registration would be a second asset of the\n * same token: its alias would resolve to one id, and the token's own transfers, deposits\n * and balances by ref to another. A mixed-case contract with a wrong checksum is a typo,\n * refused as the driver refuses it in a transfer. The refusal never repeats the value.\n */\nfunction erc20Registration(asset: AssetRegistration, name: string): AssetRegistration {\n const { ref } = asset;\n if (ref === 'native') return asset;\n const fail = (reason: string): never => {\n throw new ConfigError(\n 'CONFIG_INVALID',\n `EVM chain plugin '${name}': the asset ${JSON.stringify(asset.metadata.symbol)} on ${asset.chain}:${asset.network} ${reason}`,\n );\n };\n if (ref.standard !== 'erc20') fail(`must use the 'erc20' standard`);\n if (!HEX_ADDRESS.test(ref.contract)) fail('needs a 0x-prefixed 20-byte hex contract');\n const contract = eip55(ref.contract);\n const digits = ref.contract.slice(2);\n const mixedCase = /[a-f]/.test(digits) && /[A-F]/.test(digits);\n if (mixedCase && contract !== ref.contract)\n fail('has a contract with a wrong checksum');\n return contract === ref.contract ? asset : { ...asset, ref: { ...ref, contract } };\n}\n\nexport interface EvmChainPluginOptions {\n /**\n * A unique name matching `/^[a-z][a-z0-9-]*$/`. The plugin registers as `evm:<name>`, so\n * it never collides with a family plugin, and its manifests as `evm:<name>/ethers` and\n * `evm:<name>/web3`.\n */\n readonly name: string;\n /** Chains with `family: 'evm'`, nonce ordering and the `secp256k1-ecdsa` scheme. */\n readonly chains: readonly ChainInfo[];\n readonly presets?: readonly ProviderPreset[];\n /**\n * Tokens: `erc20` refs, each registered under its EIP-55 checksummed contract, whatever\n * case it is given in, so its alias and its transfers name one asset id.\n */\n readonly assets?: readonly AssetRegistration[];\n}\n\n/**\n * A plugin for EVM chains of your own, served by the built-in EVM driver with either\n * library. Every network and token is validated here, so bad data fails at registration.\n */\nexport function evmChainPlugin(options: EvmChainPluginOptions): Plugin {\n if (!PLUGIN_NAME.test(options.name)) {\n throw new ConfigError(\n 'CONFIG_INVALID',\n `EVM chain plugin name ${JSON.stringify(options.name)} must match ${String(PLUGIN_NAME)}`,\n );\n }\n const name = `evm:${options.name}`;\n for (const chain of options.chains) {\n const fail = (reason: string): never => {\n throw new ConfigError('CONFIG_INVALID', `EVM chain '${chain.id}': ${reason}`);\n };\n if (chain.family !== 'evm') fail(`its family must be 'evm'`);\n if (chain.model !== 'account' || chain.ordering !== 'nonce') {\n fail(`it must use the account model and nonce ordering`);\n }\n if (chain.schemes.length !== 1 || chain.schemes[0] !== 'secp256k1-ecdsa') {\n fail(`its only scheme must be 'secp256k1-ecdsa'`);\n }\n for (const network of Object.values(chain.networks)) evmNetworkConfig(chain, network);\n }\n return {\n name,\n chains: options.chains,\n adapters: evmManifests(\n name,\n options.chains.map((chain) => chain.id),\n ),\n ...(options.presets ? { presets: options.presets } : {}),\n ...(options.assets\n ? { assets: options.assets.map((asset) => erc20Registration(asset, name)) }\n : {}),\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../../src/adapters/evm/plugin.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The EVM family plugin: chains, tokens and provider presets as data, plus one\n * adapter manifest per library. SDK-free: only a manifest's `load()` requires a client\n * module, and with it the SDK. `ethers` is registered first, so it is the family default.\n */\nimport { keccak_256 } from '@noble/hashes/sha3';\nimport type {\n AdapterManifest,\n DriverFactory,\n PeerDependency,\n} from '../../core/driver/types';\nimport { ConfigError } from '../../core/errors/error';\nimport type { ChainInfo } from '../../core/model/chain';\nimport type { AssetRegistration } from '../../core/registry/assets';\nimport type { Plugin } from '../../core/registry/plugin';\nimport type { ProviderPreset } from '../../core/registry/providers';\nimport { toHex, utf8ToBytes } from '../../core/util/bytes';\nimport { EVM_CHAINS } from './chains';\nimport { EVM_CAPABILITIES, evmNetworkConfig } from './network';\nimport { EVM_PRESETS } from './presets';\nimport { EVM_TOKENS } from './tokens';\n\n/** The SDK versions this adapter is validated against. */\nexport const EVM_PEER_DEPENDENCIES: Readonly<Record<'ethers' | 'web3', PeerDependency>> =\n {\n ethers: { name: 'ethers', range: '^6.17.0' },\n web3: { name: 'web3', range: '^4.16.0' },\n };\n\n/**\n * The manifests' `load` functions, shared by every `evmManifests(...)` call, so that\n * registering `evmPlugin()` or the same `evmChainPlugin(...)` again is the same plugin:\n * the registry compares a plugin's functions by identity, and refuses a different plugin\n * under a registered name. Each `require`s its client module, and with it the SDK, only\n * when called.\n */\nconst loadEthers = async (): Promise<DriverFactory> => {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const mod = require('./ethers-client') as typeof import('./ethers-client');\n return mod.ethersDriverFactory;\n};\n\nconst loadWeb3 = async (): Promise<DriverFactory> => {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const mod = require('./web3-client') as typeof import('./web3-client');\n return mod.web3DriverFactory;\n};\n\n/** The `ethers` and `web3` manifests for `chains`, keyed `<family>/<library>`. */\nexport function evmManifests(\n family: string,\n chains: readonly string[],\n): AdapterManifest[] {\n return [\n {\n family,\n library: 'ethers',\n chains,\n capabilities: EVM_CAPABILITIES,\n peerDependencies: [EVM_PEER_DEPENDENCIES.ethers],\n load: loadEthers,\n },\n {\n family,\n library: 'web3',\n chains,\n capabilities: EVM_CAPABILITIES,\n peerDependencies: [EVM_PEER_DEPENDENCIES.web3],\n load: loadWeb3,\n },\n ];\n}\n\n/**\n * The built-in EVM family: Ethereum, BNB Smart Chain, Polygon PoS, Avalanche C-Chain,\n * Arbitrum One, OP Mainnet and Base, with their testnets.\n */\nexport function evmPlugin(): Plugin {\n return {\n name: 'evm',\n chains: EVM_CHAINS,\n adapters: evmManifests(\n 'evm',\n EVM_CHAINS.map((chain) => chain.id),\n ),\n presets: EVM_PRESETS,\n assets: EVM_TOKENS,\n };\n}\n\n/** A plugin name: lower-case letters, digits and hyphens, starting with a letter. */\nconst PLUGIN_NAME = /^[a-z][a-z0-9-]*$/;\n\n/** `0x` and 40 hex digits, in any case. */\nconst HEX_ADDRESS = /^0x[0-9a-fA-F]{40}$/;\n\n/** EIP-55: each letter upper-cased where the keccak-256 of the lower-case hex has 8 or more. */\nfunction eip55(address: string): string {\n const hex = address.slice(2).toLowerCase();\n const hash = toHex(keccak_256(utf8ToBytes(hex)));\n let out = '0x';\n for (let i = 0; i < hex.length; i++) {\n const c = hex[i] as string;\n out += Number.parseInt(hash[i] as string, 16) >= 8 ? c.toUpperCase() : c;\n }\n return out;\n}\n\n/**\n * An ERC-20 registration under the contract the driver names it by. The driver normalizes\n * every token ref it is given, reads or decodes to the EIP-55 form, and an asset id carries\n * the contract as registered, so a lower-case registration would be a second asset of the\n * same token: its alias would resolve to one id, and the token's own transfers, deposits\n * and balances by ref to another. A mixed-case contract with a wrong checksum is a typo,\n * refused as the driver refuses it in a transfer. The refusal never repeats the value.\n */\nfunction erc20Registration(asset: AssetRegistration, name: string): AssetRegistration {\n const { ref } = asset;\n if (ref === 'native') return asset;\n const fail = (reason: string): never => {\n throw new ConfigError(\n 'CONFIG_INVALID',\n `EVM chain plugin '${name}': the asset ${JSON.stringify(asset.metadata.symbol)} on ${asset.chain}:${asset.network} ${reason}`,\n );\n };\n if (ref.standard !== 'erc20') fail(`must use the 'erc20' standard`);\n if (!HEX_ADDRESS.test(ref.contract)) fail('needs a 0x-prefixed 20-byte hex contract');\n const contract = eip55(ref.contract);\n const digits = ref.contract.slice(2);\n const mixedCase = /[a-f]/.test(digits) && /[A-F]/.test(digits);\n if (mixedCase && contract !== ref.contract)\n fail('has a contract with a wrong checksum');\n return contract === ref.contract ? asset : { ...asset, ref: { ...ref, contract } };\n}\n\n/** `evmChainPlugin()`'s options: one EVM chain to register, with its networks and tokens. */\nexport interface EvmChainPluginOptions {\n /**\n * A unique name matching `/^[a-z][a-z0-9-]*$/`. The plugin registers as `evm:<name>`, so\n * it never collides with a family plugin, and its manifests as `evm:<name>/ethers` and\n * `evm:<name>/web3`.\n */\n readonly name: string;\n /** Chains with `family: 'evm'`, nonce ordering and the `secp256k1-ecdsa` scheme. */\n readonly chains: readonly ChainInfo[];\n readonly presets?: readonly ProviderPreset[];\n /**\n * Tokens: `erc20` refs, each registered under its EIP-55 checksummed contract, whatever\n * case it is given in, so its alias and its transfers name one asset id.\n */\n readonly assets?: readonly AssetRegistration[];\n}\n\n/**\n * A plugin for EVM chains of your own, served by the built-in EVM driver with either\n * library. Every network and token is validated here, so bad data fails at registration.\n */\nexport function evmChainPlugin(options: EvmChainPluginOptions): Plugin {\n if (!PLUGIN_NAME.test(options.name)) {\n throw new ConfigError(\n 'CONFIG_INVALID',\n `EVM chain plugin name ${JSON.stringify(options.name)} must match ${String(PLUGIN_NAME)}`,\n );\n }\n const name = `evm:${options.name}`;\n for (const chain of options.chains) {\n const fail = (reason: string): never => {\n throw new ConfigError('CONFIG_INVALID', `EVM chain '${chain.id}': ${reason}`);\n };\n if (chain.family !== 'evm') fail(`its family must be 'evm'`);\n if (chain.model !== 'account' || chain.ordering !== 'nonce') {\n fail(`it must use the account model and nonce ordering`);\n }\n if (chain.schemes.length !== 1 || chain.schemes[0] !== 'secp256k1-ecdsa') {\n fail(`its only scheme must be 'secp256k1-ecdsa'`);\n }\n for (const network of Object.values(chain.networks)) evmNetworkConfig(chain, network);\n }\n return {\n name,\n chains: options.chains,\n adapters: evmManifests(\n name,\n options.chains.map((chain) => chain.id),\n ),\n ...(options.presets ? { presets: options.presets } : {}),\n ...(options.assets\n ? { assets: options.assets.map((asset) => erc20Registration(asset, name)) }\n : {}),\n };\n}\n"]}
|
|
@@ -7,6 +7,7 @@ import type { ChainInfo, NetworkInfo } from '../../core/model/chain';
|
|
|
7
7
|
* transfer carries exactly one output.
|
|
8
8
|
*/
|
|
9
9
|
export declare const TON_CAPABILITIES: readonly Capability[];
|
|
10
|
+
/** The capabilities a TON handle gains when it has an `indexer` (toncenter's v3 API). */
|
|
10
11
|
export declare const TON_INDEXER_CAPABILITIES: readonly Capability[];
|
|
11
12
|
/** The ceiling of each workchain's `network` charge, in nanograms. */
|
|
12
13
|
export interface TonFeeCeiling {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network.js","sourceRoot":"","sources":["../../../src/adapters/ton/network.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * What the TON driver needs from a network's registry entry, validated once when a driver\n * is created, so inconsistent data fails with `CONFIG_INVALID` instead of misbehaving.\n * SDK-free.\n */\nimport { ConfigError } from '../../core/errors/error';\nimport { KNOWN_CAPABILITIES, type Capability } from '../../core/model/capability';\nimport type { ChainInfo, NetworkInfo } from '../../core/model/chain';\nimport { knownName, unknownName } from '../../core/util/names';\nimport { MAX_COINS } from './fees';\n\n/**\n * The TON manifest's capabilities; `address-history` comes with the indexer. No\n * `batch-transfer`: the verdict answers `failed` for a partly delivered batch, and\n * a failed Operation sent again whole would pay twice the outputs that moved, so a TON\n * transfer carries exactly one output.\n */\nexport const TON_CAPABILITIES: readonly Capability[] = Object.freeze([\n 'tokens',\n 'memo',\n 'expiry',\n]);\nexport const TON_INDEXER_CAPABILITIES: readonly Capability[] = Object.freeze([\n 'address-history',\n]);\n/**\n * The only capabilities a TON network may add or remove. Never on TON: `block-scan`\n * (sharded, no block source), `replace-fee` and `cancel` (TON has neither),\n * `batch-transfer` (one output per transfer), nor any other.\n */\nconst OWN_CAPABILITIES: ReadonlySet<Capability> = new Set([\n ...TON_CAPABILITIES,\n ...TON_INDEXER_CAPABILITIES,\n]);\n\n/** The TON network options (`NetworkInfo.params`); any other key is a typo. */\nconst OPTIONS: ReadonlySet<string> = new Set([\n 'validForSeconds',\n 'jettonAttached',\n 'jettonForwardAmount',\n 'finalitySkewBlocks',\n 'maxNetworkFee',\n]);\n\n/** The ceiling of each workchain's `network` charge, in nanograms. */\nexport interface TonFeeCeiling {\n readonly basechain: bigint;\n readonly masterchain: bigint;\n}\n\n/**\n * The default economic ceiling on the `network` charge an endpoint's emulation suggests,\n * which a network replaces with `params.maxNetworkFee`. TON signs no fee: the chain\n * charges gas and forward fees by its config, so an inflated estimate cannot make a\n * transfer pay more, but it would fail the funds check for good (`INSUFFICIENT_FUNDS`) or\n * mislead whoever approves the fee. A basechain wallet's transfer costs about 0.001-0.01\n * TON, and a whole gas limit (1M gas at 400 nanograms) 0.4 TON; a masterchain wallet pays\n * about 25 times the gas and far more storage (about 6 TON a year for a v4r2 wallet at\n * mainnet's config param 18), so 100 TON refuses only a wallet idle for more than about\n * 13 years. Above the ceiling an estimate is a retryable `PROVIDER_INCONSISTENT`.\n */\nexport const DEFAULT_MAX_NETWORK_FEE: TonFeeCeiling = Object.freeze({\n basechain: 1_000_000_000n,\n masterchain: 100_000_000_000n,\n});\n\nconst WORKCHAINS: ReadonlySet<string> = new Set(['basechain', 'masterchain']);\n\n/**\n * A capability as an error may show it: a core capability's name is a fixed word, so\n * it is shown; any other text could be a pasted secret, so it is not. Unknown option keys are\n * never echoed either; their errors list the accepted names instead.\n */\nconst shown = (capability: Capability): string =>\n knownName(capability, KNOWN_CAPABILITIES, 'an unknown capability');\n\nexport interface TonNetworkConfig {\n /** Config param 19; the network identity. */\n readonly globalId: number;\n readonly testnet: boolean;\n /** A message's lifetime past chain time, in seconds. */\n readonly validForSeconds: number;\n /** Nanograms attached to each jetton wallet message; the unspent part is refunded. */\n readonly jettonAttached: bigint;\n /** Nanograms forwarded with each jetton notification. */\n readonly jettonForwardAmount: bigint;\n /** Masterchain blocks the attested head first trails the freshest endpoint by. */\n readonly finalitySkewBlocks: number;\n /** The most an estimate's `network` charge may be, per workchain of the sender. */\n readonly maxNetworkFee: TonFeeCeiling;\n readonly capabilities: ReadonlySet<Capability>;\n}\n\nconst isIntegerIn = (value: unknown, min: number, max: number): value is number =>\n Number.isSafeInteger(value) && (value as number) >= min && (value as number) <= max;\n\n/** The lifetimes a network may configure (`params.validForSeconds`), in seconds. */\nexport const MIN_VALID_FOR_SECONDS = 10;\nexport const MAX_VALID_FOR_SECONDS = 86_400;\n\n/** How far an endpoint's `sync_utime` may be from the local clock, in seconds. */\nexport const CHAIN_TIME_TOLERANCE = 300;\n\n/**\n * A build's recorded chain time (`TonSeqnoOrdering.validFrom`) when the ordering holds\n * a well-formed one for its lifetime: a safe integer at least the shortest lifetime before\n * `validUntil`, and at most the longest (plus the chain-time tolerance) before it. Undefined\n * otherwise (an attempt built before the field existed, or a damaged record).\n */\nexport function recordedValidFrom(slot: {\n readonly validUntil: number;\n}): number | undefined {\n const { validUntil } = slot;\n const { validFrom } = slot as { readonly validFrom?: unknown };\n return typeof validFrom === 'number' &&\n Number.isSafeInteger(validFrom) &&\n validFrom <= validUntil - MIN_VALID_FOR_SECONDS &&\n validFrom >= validUntil - MAX_VALID_FOR_SECONDS - CHAIN_TIME_TOLERANCE\n ? validFrom\n : undefined;\n}\n\n/**\n * The only driver options (`HandleOptions.options`, `chains.ton.options`) the TON driver\n * reads. Any other key is refused, so a typo fails loudly instead of leaving the default\n * in place.\n */\nconst OPTION_KEYS: ReadonlySet<string> = new Set(['maxNetworkFee']);\n\nexport function tonNetworkConfig(\n chain: ChainInfo,\n network: NetworkInfo,\n options: Readonly<Record<string, unknown>> = {},\n): TonNetworkConfig {\n const fail = (reason: string): never => {\n throw new ConfigError(\n 'CONFIG_INVALID',\n `TON network ${chain.id}:${network.id}: ${reason}`,\n );\n };\n const identity = network.identity;\n if (identity === undefined || !/^-?[1-9][0-9]*$/.test(identity)) {\n fail('its identity must be the decimal global id (config param 19)');\n }\n const globalId = Number(identity);\n if (!isIntegerIn(globalId, -(2 ** 31), 2 ** 31 - 1)) {\n fail('the global id must be an int32');\n }\n if (network.feeModel !== 'ton') {\n fail(`its fee model must be 'ton'`);\n }\n if (network.finality.kind !== 'masterchain') {\n fail(`its finality must be 'masterchain'`);\n }\n const params = network.params ?? {};\n for (const key of Object.keys(params)) {\n if (!OPTIONS.has(key)) {\n fail(\n `params has a key that is not a TON network option (${[...OPTIONS].join(', ')})`,\n );\n }\n }\n // Own keys only; an explicit `undefined` is absent, so the library default applies.\n const param = (key: string, fallback: unknown): unknown => {\n const value = Object.hasOwn(params, key) ? params[key] : undefined;\n return value === undefined ? fallback : value;\n };\n const validFor = param('validForSeconds', 60);\n if (!isIntegerIn(validFor, MIN_VALID_FOR_SECONDS, MAX_VALID_FOR_SECONDS)) {\n fail('params.validForSeconds must be an integer in [10, 86400]');\n }\n // Encoded as Coins in every jetton wallet message: range-checked here, never wrapped.\n const attached = param('jettonAttached', 50_000_000n);\n if (typeof attached !== 'bigint' || attached <= 0n || attached > MAX_COINS) {\n fail('params.jettonAttached must be a bigint in [1, 2^120 - 1] (nanograms)');\n }\n const forward = param('jettonForwardAmount', 1n);\n if (typeof forward !== 'bigint' || forward < 0n || forward >= (attached as bigint)) {\n fail('params.jettonForwardAmount must be a bigint in [0, jettonAttached)');\n }\n const skew = param('finalitySkewBlocks', 10);\n if (!isIntegerIn(skew, 1, 1_000)) {\n fail('params.finalitySkewBlocks must be an integer in [1, 1000]');\n }\n // The refusal names the accepted option and shows neither the caller's key, which\n // may be a pasted secret, nor its value.\n for (const key of Object.keys(options)) {\n if (!OPTION_KEYS.has(key)) {\n fail(unknownName('option', OPTION_KEYS));\n }\n }\n // Per workchain, the handle's option, else the network's params, else the\n // default. A network value is checked even where an option overrides it.\n const networkFeeCeiling = feeCeiling(\n param('maxNetworkFee', {}),\n 'params.maxNetworkFee',\n DEFAULT_MAX_NETWORK_FEE,\n fail,\n );\n const option = Object.hasOwn(options, 'maxNetworkFee')\n ? options.maxNetworkFee\n : undefined;\n const maxNetworkFee =\n option === undefined\n ? networkFeeCeiling\n : feeCeiling(option, 'maxNetworkFee', networkFeeCeiling, fail);\n const capabilities = new Set<Capability>([\n ...TON_CAPABILITIES,\n ...TON_INDEXER_CAPABILITIES,\n ]);\n const own = (c: Capability): Capability =>\n OWN_CAPABILITIES.has(c) ? c : fail(`${shown(c)} is not available on TON`);\n for (const c of network.capabilities?.add ?? []) capabilities.add(own(c));\n for (const c of network.capabilities?.remove ?? []) capabilities.delete(own(c));\n return {\n globalId,\n testnet: network.testnet,\n validForSeconds: validFor as number,\n jettonAttached: attached as bigint,\n jettonForwardAmount: forward as bigint,\n finalitySkewBlocks: skew as number,\n maxNetworkFee,\n capabilities,\n };\n}\n\n/**\n * `maxNetworkFee` (`name`: the network's `params.maxNetworkFee` or the handle option):\n * `{ basechain?, masterchain? }`, each a positive bigint within Coins (the charge is\n * compared with nanogram amounts); a workchain left out keeps `fallback`'s. Any other key,\n * or value, is `CONFIG_INVALID`, which never echoes the key.\n */\nfunction feeCeiling(\n value: unknown,\n name: string,\n fallback: TonFeeCeiling,\n fail: (reason: string) => never,\n): TonFeeCeiling {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n return fail(`${name} must be { basechain?, masterchain? } (nanograms)`);\n }\n const record = value as Readonly<Record<string, unknown>>;\n for (const key of Object.keys(record)) {\n if (!WORKCHAINS.has(key)) {\n fail(`${name} takes only 'basechain' and 'masterchain'`);\n }\n }\n const bound = (key: keyof TonFeeCeiling): bigint => {\n const own = Object.hasOwn(record, key) ? record[key] : undefined;\n const ceiling = own === undefined ? fallback[key] : own;\n if (typeof ceiling !== 'bigint' || ceiling <= 0n || ceiling > MAX_COINS) {\n fail(`${name}.${key} must be a bigint in [1, 2^120 - 1] (nanograms)`);\n }\n return ceiling as bigint;\n };\n return Object.freeze({\n basechain: bound('basechain'),\n masterchain: bound('masterchain'),\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"network.js","sourceRoot":"","sources":["../../../src/adapters/ton/network.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * What the TON driver needs from a network's registry entry, validated once when a driver\n * is created, so inconsistent data fails with `CONFIG_INVALID` instead of misbehaving.\n * SDK-free.\n */\nimport { ConfigError } from '../../core/errors/error';\nimport { KNOWN_CAPABILITIES, type Capability } from '../../core/model/capability';\nimport type { ChainInfo, NetworkInfo } from '../../core/model/chain';\nimport { knownName, unknownName } from '../../core/util/names';\nimport { MAX_COINS } from './fees';\n\n/**\n * The TON manifest's capabilities; `address-history` comes with the indexer. No\n * `batch-transfer`: the verdict answers `failed` for a partly delivered batch, and\n * a failed Operation sent again whole would pay twice the outputs that moved, so a TON\n * transfer carries exactly one output.\n */\nexport const TON_CAPABILITIES: readonly Capability[] = Object.freeze([\n 'tokens',\n 'memo',\n 'expiry',\n]);\n/** The capabilities a TON handle gains when it has an `indexer` (toncenter's v3 API). */\nexport const TON_INDEXER_CAPABILITIES: readonly Capability[] = Object.freeze([\n 'address-history',\n]);\n/**\n * The only capabilities a TON network may add or remove. Never on TON: `block-scan`\n * (sharded, no block source), `replace-fee` and `cancel` (TON has neither),\n * `batch-transfer` (one output per transfer), nor any other.\n */\nconst OWN_CAPABILITIES: ReadonlySet<Capability> = new Set([\n ...TON_CAPABILITIES,\n ...TON_INDEXER_CAPABILITIES,\n]);\n\n/** The TON network options (`NetworkInfo.params`); any other key is a typo. */\nconst OPTIONS: ReadonlySet<string> = new Set([\n 'validForSeconds',\n 'jettonAttached',\n 'jettonForwardAmount',\n 'finalitySkewBlocks',\n 'maxNetworkFee',\n]);\n\n/** The ceiling of each workchain's `network` charge, in nanograms. */\nexport interface TonFeeCeiling {\n readonly basechain: bigint;\n readonly masterchain: bigint;\n}\n\n/**\n * The default economic ceiling on the `network` charge an endpoint's emulation suggests,\n * which a network replaces with `params.maxNetworkFee`. TON signs no fee: the chain\n * charges gas and forward fees by its config, so an inflated estimate cannot make a\n * transfer pay more, but it would fail the funds check for good (`INSUFFICIENT_FUNDS`) or\n * mislead whoever approves the fee. A basechain wallet's transfer costs about 0.001-0.01\n * TON, and a whole gas limit (1M gas at 400 nanograms) 0.4 TON; a masterchain wallet pays\n * about 25 times the gas and far more storage (about 6 TON a year for a v4r2 wallet at\n * mainnet's config param 18), so 100 TON refuses only a wallet idle for more than about\n * 13 years. Above the ceiling an estimate is a retryable `PROVIDER_INCONSISTENT`.\n */\nexport const DEFAULT_MAX_NETWORK_FEE: TonFeeCeiling = Object.freeze({\n basechain: 1_000_000_000n,\n masterchain: 100_000_000_000n,\n});\n\nconst WORKCHAINS: ReadonlySet<string> = new Set(['basechain', 'masterchain']);\n\n/**\n * A capability as an error may show it: a core capability's name is a fixed word, so\n * it is shown; any other text could be a pasted secret, so it is not. Unknown option keys are\n * never echoed either; their errors list the accepted names instead.\n */\nconst shown = (capability: Capability): string =>\n knownName(capability, KNOWN_CAPABILITIES, 'an unknown capability');\n\nexport interface TonNetworkConfig {\n /** Config param 19; the network identity. */\n readonly globalId: number;\n readonly testnet: boolean;\n /** A message's lifetime past chain time, in seconds. */\n readonly validForSeconds: number;\n /** Nanograms attached to each jetton wallet message; the unspent part is refunded. */\n readonly jettonAttached: bigint;\n /** Nanograms forwarded with each jetton notification. */\n readonly jettonForwardAmount: bigint;\n /** Masterchain blocks the attested head first trails the freshest endpoint by. */\n readonly finalitySkewBlocks: number;\n /** The most an estimate's `network` charge may be, per workchain of the sender. */\n readonly maxNetworkFee: TonFeeCeiling;\n readonly capabilities: ReadonlySet<Capability>;\n}\n\nconst isIntegerIn = (value: unknown, min: number, max: number): value is number =>\n Number.isSafeInteger(value) && (value as number) >= min && (value as number) <= max;\n\n/** The lifetimes a network may configure (`params.validForSeconds`), in seconds. */\nexport const MIN_VALID_FOR_SECONDS = 10;\nexport const MAX_VALID_FOR_SECONDS = 86_400;\n\n/** How far an endpoint's `sync_utime` may be from the local clock, in seconds. */\nexport const CHAIN_TIME_TOLERANCE = 300;\n\n/**\n * A build's recorded chain time (`TonSeqnoOrdering.validFrom`) when the ordering holds\n * a well-formed one for its lifetime: a safe integer at least the shortest lifetime before\n * `validUntil`, and at most the longest (plus the chain-time tolerance) before it. Undefined\n * otherwise (an attempt built before the field existed, or a damaged record).\n */\nexport function recordedValidFrom(slot: {\n readonly validUntil: number;\n}): number | undefined {\n const { validUntil } = slot;\n const { validFrom } = slot as { readonly validFrom?: unknown };\n return typeof validFrom === 'number' &&\n Number.isSafeInteger(validFrom) &&\n validFrom <= validUntil - MIN_VALID_FOR_SECONDS &&\n validFrom >= validUntil - MAX_VALID_FOR_SECONDS - CHAIN_TIME_TOLERANCE\n ? validFrom\n : undefined;\n}\n\n/**\n * The only driver options (`HandleOptions.options`, `chains.ton.options`) the TON driver\n * reads. Any other key is refused, so a typo fails loudly instead of leaving the default\n * in place.\n */\nconst OPTION_KEYS: ReadonlySet<string> = new Set(['maxNetworkFee']);\n\nexport function tonNetworkConfig(\n chain: ChainInfo,\n network: NetworkInfo,\n options: Readonly<Record<string, unknown>> = {},\n): TonNetworkConfig {\n const fail = (reason: string): never => {\n throw new ConfigError(\n 'CONFIG_INVALID',\n `TON network ${chain.id}:${network.id}: ${reason}`,\n );\n };\n const identity = network.identity;\n if (identity === undefined || !/^-?[1-9][0-9]*$/.test(identity)) {\n fail('its identity must be the decimal global id (config param 19)');\n }\n const globalId = Number(identity);\n if (!isIntegerIn(globalId, -(2 ** 31), 2 ** 31 - 1)) {\n fail('the global id must be an int32');\n }\n if (network.feeModel !== 'ton') {\n fail(`its fee model must be 'ton'`);\n }\n if (network.finality.kind !== 'masterchain') {\n fail(`its finality must be 'masterchain'`);\n }\n const params = network.params ?? {};\n for (const key of Object.keys(params)) {\n if (!OPTIONS.has(key)) {\n fail(\n `params has a key that is not a TON network option (${[...OPTIONS].join(', ')})`,\n );\n }\n }\n // Own keys only; an explicit `undefined` is absent, so the library default applies.\n const param = (key: string, fallback: unknown): unknown => {\n const value = Object.hasOwn(params, key) ? params[key] : undefined;\n return value === undefined ? fallback : value;\n };\n const validFor = param('validForSeconds', 60);\n if (!isIntegerIn(validFor, MIN_VALID_FOR_SECONDS, MAX_VALID_FOR_SECONDS)) {\n fail('params.validForSeconds must be an integer in [10, 86400]');\n }\n // Encoded as Coins in every jetton wallet message: range-checked here, never wrapped.\n const attached = param('jettonAttached', 50_000_000n);\n if (typeof attached !== 'bigint' || attached <= 0n || attached > MAX_COINS) {\n fail('params.jettonAttached must be a bigint in [1, 2^120 - 1] (nanograms)');\n }\n const forward = param('jettonForwardAmount', 1n);\n if (typeof forward !== 'bigint' || forward < 0n || forward >= (attached as bigint)) {\n fail('params.jettonForwardAmount must be a bigint in [0, jettonAttached)');\n }\n const skew = param('finalitySkewBlocks', 10);\n if (!isIntegerIn(skew, 1, 1_000)) {\n fail('params.finalitySkewBlocks must be an integer in [1, 1000]');\n }\n // The refusal names the accepted option and shows neither the caller's key, which\n // may be a pasted secret, nor its value.\n for (const key of Object.keys(options)) {\n if (!OPTION_KEYS.has(key)) {\n fail(unknownName('option', OPTION_KEYS));\n }\n }\n // Per workchain, the handle's option, else the network's params, else the\n // default. A network value is checked even where an option overrides it.\n const networkFeeCeiling = feeCeiling(\n param('maxNetworkFee', {}),\n 'params.maxNetworkFee',\n DEFAULT_MAX_NETWORK_FEE,\n fail,\n );\n const option = Object.hasOwn(options, 'maxNetworkFee')\n ? options.maxNetworkFee\n : undefined;\n const maxNetworkFee =\n option === undefined\n ? networkFeeCeiling\n : feeCeiling(option, 'maxNetworkFee', networkFeeCeiling, fail);\n const capabilities = new Set<Capability>([\n ...TON_CAPABILITIES,\n ...TON_INDEXER_CAPABILITIES,\n ]);\n const own = (c: Capability): Capability =>\n OWN_CAPABILITIES.has(c) ? c : fail(`${shown(c)} is not available on TON`);\n for (const c of network.capabilities?.add ?? []) capabilities.add(own(c));\n for (const c of network.capabilities?.remove ?? []) capabilities.delete(own(c));\n return {\n globalId,\n testnet: network.testnet,\n validForSeconds: validFor as number,\n jettonAttached: attached as bigint,\n jettonForwardAmount: forward as bigint,\n finalitySkewBlocks: skew as number,\n maxNetworkFee,\n capabilities,\n };\n}\n\n/**\n * `maxNetworkFee` (`name`: the network's `params.maxNetworkFee` or the handle option):\n * `{ basechain?, masterchain? }`, each a positive bigint within Coins (the charge is\n * compared with nanogram amounts); a workchain left out keeps `fallback`'s. Any other key,\n * or value, is `CONFIG_INVALID`, which never echoes the key.\n */\nfunction feeCeiling(\n value: unknown,\n name: string,\n fallback: TonFeeCeiling,\n fail: (reason: string) => never,\n): TonFeeCeiling {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n return fail(`${name} must be { basechain?, masterchain? } (nanograms)`);\n }\n const record = value as Readonly<Record<string, unknown>>;\n for (const key of Object.keys(record)) {\n if (!WORKCHAINS.has(key)) {\n fail(`${name} takes only 'basechain' and 'masterchain'`);\n }\n }\n const bound = (key: keyof TonFeeCeiling): bigint => {\n const own = Object.hasOwn(record, key) ? record[key] : undefined;\n const ceiling = own === undefined ? fallback[key] : own;\n if (typeof ceiling !== 'bigint' || ceiling <= 0n || ceiling > MAX_COINS) {\n fail(`${name}.${key} must be a bigint in [1, 2^120 - 1] (nanograms)`);\n }\n return ceiling as bigint;\n };\n return Object.freeze({\n basechain: bound('basechain'),\n masterchain: bound('masterchain'),\n });\n}\n"]}
|
|
@@ -19,6 +19,7 @@ declare module '../../index' {
|
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
+
/** The wallet contracts the TON driver sends from (`wallet.ton.version`). */
|
|
22
23
|
export type TonWalletVersion = 'v4r2' | 'v5r1';
|
|
23
24
|
/**
|
|
24
25
|
* The wallet contract behind a TON address. Every field determines the address,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/adapters/ton/types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * SDK-free types of the TON family: the wallet identity, the `ext.ton` API, fee\n * details and overrides, and the transport tags. Nothing here imports an SDK, so the\n * composition root can export these types.\n */\nimport type { CallOptions } from '../../core/transport/types';\n\n// Augment the registries through the package entry, as users do with 'crypto-aio'.\ndeclare module '../../index' {\n interface ChainRegistry {\n ton: { family: 'ton'; network: 'mainnet' | 'testnet' };\n }\n interface FamilyRegistry {\n ton: { library: '@ton/ton'; ext: TonExt; fee: TonFeeDetails };\n }\n}\n\nexport type TonWalletVersion = 'v4r2' | 'v5r1';\n\n/**\n * The wallet contract behind a TON address. Every field determines the address,\n * so it is wallet config (`wallets.<name>.ton`), never a per-call option.\n * - v4r2: `subwalletId` defaults to `698983191 + workchain`.\n * - v5r1: `subwalletNumber` defaults to 0 (15 bits); `networkGlobalId` defaults to the\n * network's global id (-239 mainnet, -3 testnet) and must equal it.\n */\nexport type TonWalletIdentity =\n | {\n readonly version: 'v4r2';\n readonly workchain?: 0 | -1;\n readonly subwalletId?: number;\n }\n | {\n readonly version: 'v5r1';\n readonly workchain?: 0 | -1;\n readonly subwalletNumber?: number;\n readonly networkGlobalId?: number;\n };\n\n/** `bc.ext.ton`: the TON family extension. */\nexport interface TonExt {\n readonly ton: {\n /** The wallet's seqno at the latest masterchain block; 0 while it is not deployed. */\n getSeqno(address: string): Promise<bigint>;\n /** The jetton wallet that `owner` holds for the jetton `master` (raw form). */\n jettonWallet(owner: string, master: string): Promise<string>;\n };\n}\n\n/**\n * `FeeEstimate.details` of the `ton` fee kind, in nanograms. The `network` charge is\n * `importFee + gasFee + storageFee + forwardFee`; a jetton transfer adds an `attached`\n * charge (`attached` per output), whose unspent part the jetton wallet refunds.\n */\nexport interface TonFeeDetails {\n /** The inbound external message's import fee. */\n readonly importFee: bigint;\n /** The wallet's compute phase, from the endpoint's emulation. */\n readonly gasFee: bigint;\n readonly storageFee: bigint;\n /** The forward fees of every outgoing internal message (full `fwd_fee`), counted once. */\n readonly forwardFee: bigint;\n /**\n * Where `forwardFee` comes from: the endpoint's emulation (`fwd_fee`, which follows\n * the real action list), or, when it reports none, config params 24/25.\n */\n readonly forwardFeeSource: 'emulated' | 'computed';\n /** Jetton transfers: the value attached to each jetton wallet message. */\n readonly attached?: bigint;\n /** Jetton transfers: `forward_ton_amount`, which pays for the recipient's notification. */\n readonly forwardAmount?: bigint;\n /** Whether the message deploys the wallet (its first send carries the `StateInit`). */\n readonly deploy: boolean;\n}\n\n/**\n * An explicit TON fee (`TransferIntent.fee`). TON fees are fixed by the network config, so\n * there is nothing to bid; a jetton transfer may change the value attached to each jetton\n * wallet message (default: the network's `jettonAttached`).\n */\nexport interface TonFeeOverride {\n readonly attached?: bigint;\n}\n\n/**\n * The seqno ordering a TON build records: the signed seqno and `valid_until`, and\n * `validFrom`, the chain time the build ran at (the state's `sync_utime`, and never later\n * than the local clock), in seconds. The message cannot run in a block older than that, less\n * the builder's chain-time tolerance, so a proof that it was not included walks the\n * wallet's history back to there, whatever the network's `validForSeconds` is now. It is a\n * core `seqno` ordering with one more property, which the core stores whole. A store that\n * drops `validFrom` costs only liveness (the proof and the replay guard fall back to a\n * one-day window); one that moves it later could hide a wallet reset and prove \"not\n * included\" falsely, and a `rebuild` would then pay twice.\n */\nexport interface TonSeqnoOrdering {\n readonly kind: 'seqno';\n readonly seqno: bigint;\n readonly validUntil: number;\n readonly validFrom: number;\n}\n\n/**\n * The transport tags every TON I/O call carries, as the `ChainDriver` contract table sets\n * them. A caller's `quorumKey` replaces the call's default consensus key: proofs attest a\n * monotone predicate, such as \"my seqno is above n\", instead of comparing data read at a\n * moving head.\n */\nexport type TonCallTags = Pick<\n CallOptions,\n 'purpose' | 'retry' | 'quorum' | 'quorumKey' | 'fanout' | 'signal'\n>;\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/adapters/ton/types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * SDK-free types of the TON family: the wallet identity, the `ext.ton` API, fee\n * details and overrides, and the transport tags. Nothing here imports an SDK, so the\n * composition root can export these types.\n */\nimport type { CallOptions } from '../../core/transport/types';\n\n// Augment the registries through the package entry, as users do with 'crypto-aio'.\ndeclare module '../../index' {\n interface ChainRegistry {\n ton: { family: 'ton'; network: 'mainnet' | 'testnet' };\n }\n interface FamilyRegistry {\n ton: { library: '@ton/ton'; ext: TonExt; fee: TonFeeDetails };\n }\n}\n\n/** The wallet contracts the TON driver sends from (`wallet.ton.version`). */\nexport type TonWalletVersion = 'v4r2' | 'v5r1';\n\n/**\n * The wallet contract behind a TON address. Every field determines the address,\n * so it is wallet config (`wallets.<name>.ton`), never a per-call option.\n * - v4r2: `subwalletId` defaults to `698983191 + workchain`.\n * - v5r1: `subwalletNumber` defaults to 0 (15 bits); `networkGlobalId` defaults to the\n * network's global id (-239 mainnet, -3 testnet) and must equal it.\n */\nexport type TonWalletIdentity =\n | {\n readonly version: 'v4r2';\n readonly workchain?: 0 | -1;\n readonly subwalletId?: number;\n }\n | {\n readonly version: 'v5r1';\n readonly workchain?: 0 | -1;\n readonly subwalletNumber?: number;\n readonly networkGlobalId?: number;\n };\n\n/** `bc.ext.ton`: the TON family extension. */\nexport interface TonExt {\n readonly ton: {\n /** The wallet's seqno at the latest masterchain block; 0 while it is not deployed. */\n getSeqno(address: string): Promise<bigint>;\n /** The jetton wallet that `owner` holds for the jetton `master` (raw form). */\n jettonWallet(owner: string, master: string): Promise<string>;\n };\n}\n\n/**\n * `FeeEstimate.details` of the `ton` fee kind, in nanograms. The `network` charge is\n * `importFee + gasFee + storageFee + forwardFee`; a jetton transfer adds an `attached`\n * charge (`attached` per output), whose unspent part the jetton wallet refunds.\n */\nexport interface TonFeeDetails {\n /** The inbound external message's import fee. */\n readonly importFee: bigint;\n /** The wallet's compute phase, from the endpoint's emulation. */\n readonly gasFee: bigint;\n readonly storageFee: bigint;\n /** The forward fees of every outgoing internal message (full `fwd_fee`), counted once. */\n readonly forwardFee: bigint;\n /**\n * Where `forwardFee` comes from: the endpoint's emulation (`fwd_fee`, which follows\n * the real action list), or, when it reports none, config params 24/25.\n */\n readonly forwardFeeSource: 'emulated' | 'computed';\n /** Jetton transfers: the value attached to each jetton wallet message. */\n readonly attached?: bigint;\n /** Jetton transfers: `forward_ton_amount`, which pays for the recipient's notification. */\n readonly forwardAmount?: bigint;\n /** Whether the message deploys the wallet (its first send carries the `StateInit`). */\n readonly deploy: boolean;\n}\n\n/**\n * An explicit TON fee (`TransferIntent.fee`). TON fees are fixed by the network config, so\n * there is nothing to bid; a jetton transfer may change the value attached to each jetton\n * wallet message (default: the network's `jettonAttached`).\n */\nexport interface TonFeeOverride {\n readonly attached?: bigint;\n}\n\n/**\n * The seqno ordering a TON build records: the signed seqno and `valid_until`, and\n * `validFrom`, the chain time the build ran at (the state's `sync_utime`, and never later\n * than the local clock), in seconds. The message cannot run in a block older than that, less\n * the builder's chain-time tolerance, so a proof that it was not included walks the\n * wallet's history back to there, whatever the network's `validForSeconds` is now. It is a\n * core `seqno` ordering with one more property, which the core stores whole. A store that\n * drops `validFrom` costs only liveness (the proof and the replay guard fall back to a\n * one-day window); one that moves it later could hide a wallet reset and prove \"not\n * included\" falsely, and a `rebuild` would then pay twice.\n */\nexport interface TonSeqnoOrdering {\n readonly kind: 'seqno';\n readonly seqno: bigint;\n readonly validUntil: number;\n readonly validFrom: number;\n}\n\n/**\n * The transport tags every TON I/O call carries, as the `ChainDriver` contract table sets\n * them. A caller's `quorumKey` replaces the call's default consensus key: proofs attest a\n * monotone predicate, such as \"my seqno is above n\", instead of comparing data read at a\n * moving head.\n */\nexport type TonCallTags = Pick<\n CallOptions,\n 'purpose' | 'retry' | 'quorum' | 'quorumKey' | 'fanout' | 'signal'\n>;\n"]}
|
|
@@ -261,8 +261,9 @@ function decodeTransaction(codec, tx, info, blockHash, pending = false) {
|
|
|
261
261
|
...(info ? { fee: [{ asset: 'native', amount: info.fee }] } : {}),
|
|
262
262
|
transfers,
|
|
263
263
|
decoding,
|
|
264
|
-
// The block's time: the client-set
|
|
265
|
-
|
|
264
|
+
// The block's time, in Unix seconds as every family reports it: the client-set
|
|
265
|
+
// `raw_data.timestamp` is display only.
|
|
266
|
+
...(info ? { timestamp: (0, http_1.unixSeconds)(info.blockTimestamp) } : {}),
|
|
266
267
|
details: {
|
|
267
268
|
contract: raw?.contract.type ?? 'unknown',
|
|
268
269
|
...(owner ? { owner } : {}),
|