@piprail/sdk 1.2.0 → 1.3.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 +39 -0
- package/ERRORS.md +1 -1
- package/README.md +3 -2
- package/dist/aptos-DTAONNMM.js +332 -0
- package/dist/aptos-MKZ5MAGL.cjs +332 -0
- package/dist/{chunk-DTIJYDG6.js → chunk-AGKC3C7Y.js} +4 -2
- package/dist/{chunk-NK64H3RM.cjs → chunk-YJPWIK5L.cjs} +4 -2
- package/dist/index.cjs +59 -46
- package/dist/index.d.cts +10 -3
- package/dist/index.d.ts +10 -3
- package/dist/index.js +21 -8
- package/dist/{near-VZ6XGVNJ.cjs → near-DISWUB7Y.cjs} +19 -19
- package/dist/{near-RJUETWY3.js → near-YX3XOASO.js} +1 -1
- package/dist/{solana-USZHRZFN.js → solana-37F2PR5H.js} +1 -1
- package/dist/{solana-CRLWAM7C.cjs → solana-RJPNEFSN.cjs} +14 -14
- package/dist/{stellar-JZBVCLNV.js → stellar-ALOVOMFD.js} +1 -1
- package/dist/{stellar-LIGJKRRK.cjs → stellar-SUGNX52Z.cjs} +20 -20
- package/dist/{sui-JLVWFDOS.cjs → sui-HZWPHVU4.cjs} +17 -17
- package/dist/{sui-UBDATSQV.js → sui-OLC5ID4X.js} +1 -1
- package/dist/{ton-OVSQZ4OM.cjs → ton-C4KTFXDL.cjs} +14 -14
- package/dist/{ton-2N74GKNB.js → ton-NIDWF77T.js} +1 -1
- package/dist/{tron-V3A6L3X3.cjs → tron-DTU7NPEM.cjs} +24 -24
- package/dist/{tron-N3EAAKU7.js → tron-LPMK57H7.js} +1 -1
- package/dist/{xrpl-RTT3UOLX.js → xrpl-6ODQS7JR.js} +1 -1
- package/dist/{xrpl-QECPQCFS.cjs → xrpl-N6ZAJRGC.cjs} +20 -20
- package/package.json +7 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,45 @@ All notable changes to `@piprail/sdk` are documented here. The format
|
|
|
4
4
|
follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the
|
|
5
5
|
versions follow [Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [1.3.1] — 2026-06-04
|
|
8
|
+
|
|
9
|
+
Aptos pay-path fix surfaced by the live mainnet test — no API change, fully compatible with 1.3.0.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
- **Aptos: cap `maxGasAmount` (50k) on the Fungible-Asset transfer.** Aptos validates
|
|
13
|
+
`max_gas_amount × gas_unit_price` against the sender's balance *before* execution, so the SDK
|
|
14
|
+
default (200k units) made a tiny transfer demand ~0.5 APT held just to be admitted — a wallet
|
|
15
|
+
with a modest APT balance was rejected with `INSUFFICIENT_BALANCE_FOR_TRANSACTION_FEE` even
|
|
16
|
+
though the transfer itself uses a fraction of that. A `primary_fungible_store::transfer` (even
|
|
17
|
+
one that creates the recipient's primary store) stays well under 50k gas units, so the cap keeps
|
|
18
|
+
ample gas headroom while the upfront fee requirement stays small. Live-validated on Aptos mainnet.
|
|
19
|
+
|
|
20
|
+
## [1.3.0] — 2026-06-04
|
|
21
|
+
|
|
22
|
+
A new chain **family** — **Aptos** — the **9th driver family** and the only Move L1 with BOTH
|
|
23
|
+
canonical native stablecoins. Brings the built-in count to **27 chains across 9 families (19 EVM)**.
|
|
24
|
+
Aptos has an official `exact` scheme merged into the canonical `coinbase/x402` repo and is a
|
|
25
|
+
first-class x402 / agent-payments network. Fully backward-compatible; `@aptos-labs/ts-sdk` is a
|
|
26
|
+
lazy-loaded optional peer, so pure-EVM (and other) installs never download it.
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
- **Aptos (`chain: 'aptos'`, CAIP-2 `aptos:1`)** — native Circle **USDC**
|
|
30
|
+
(`0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b`) + native Tether **USD₮**
|
|
31
|
+
(`0x357b0b74bc833e95a115ad22604854d6b0fca151cecd94111770e5d6ffc9dc2b`), both 6 dp, plus native
|
|
32
|
+
**APT** (8 dp). Both Fungible-Asset metadata addresses were verified on-chain
|
|
33
|
+
(`0x1::fungible_asset::Metadata` → matching symbol + decimals) before shipping.
|
|
34
|
+
- **Template B (digest-bound, like Sui/Tron):** the proof ref is the tx hash; `verify()` re-derives
|
|
35
|
+
payTo's primary store for the required FA metadata from the **trusted accept** (never the client
|
|
36
|
+
ref) and matches `0x1::fungible_asset::Deposit` events to it (+ recency window + single-use proof
|
|
37
|
+
set). Every asset — native APT and both stablecoins — transfers via
|
|
38
|
+
`0x1::primary_fungible_store::transfer` (native = the APT FA at `0xa`), which auto-creates the
|
|
39
|
+
recipient's primary store, so there's **no opt-in / coin-store registration to receive** — even a
|
|
40
|
+
fresh recipient works. `@aptos-labs/ts-sdk` is an **optional peer (`>=2 <8`)**, lazy-loaded on
|
|
41
|
+
first use; the built EVM bundle stays free of any static `@aptos-labs/ts-sdk` import (its own chunk).
|
|
42
|
+
|
|
43
|
+
Live mainnet smoke (a real APT + USDC/USDT round-trip) is the separate ship-gate, pending wallet
|
|
44
|
+
funding; the driver is verified against the test contract (typecheck + 416 tests + build).
|
|
45
|
+
|
|
7
46
|
## [1.2.0] — 2026-06-04
|
|
8
47
|
|
|
9
48
|
Two new EVM presets — **HyperEVM (Hyperliquid)** and **Monad** — bringing the built-in count to
|
package/ERRORS.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
This is the **single source of truth** for how `@piprail/sdk` reports errors. It is
|
|
4
4
|
deliberately small and uniform: every module — the client, the server gate, the registry,
|
|
5
|
-
and every chain driver (all
|
|
5
|
+
and every chain driver (all nine families: EVM, Solana, TON, Tron, NEAR, Sui, Stellar, XRPL, Aptos,
|
|
6
6
|
and any future one) — follows it
|
|
7
7
|
*exactly*, so a human developer, a merchant server, or an AI agent always gets a **typed,
|
|
8
8
|
understandable** reason, never an opaque chain-library blob.
|
package/README.md
CHANGED
|
@@ -90,7 +90,7 @@ See [`examples/agent-tools.mjs`](../examples/agent-tools.mjs) for MCP / AI-SDK w
|
|
|
90
90
|
|
|
91
91
|
### Accept several chains at once
|
|
92
92
|
|
|
93
|
-
`requirePayment` (and `createPaymentGate`) take an **`accept: [...]`** array — one challenge that's payable on **any** of several chains/tokens, across **all
|
|
93
|
+
`requirePayment` (and `createPaymentGate`) take an **`accept: [...]`** array — one challenge that's payable on **any** of several chains/tokens, across **all nine families** (EVM, Solana, TON, Tron, Stellar, XRPL, NEAR, Sui, Aptos). The agent pays with whatever it holds:
|
|
94
94
|
|
|
95
95
|
```ts
|
|
96
96
|
requirePayment({
|
|
@@ -133,7 +133,7 @@ requirePayment({ chain: 'ton', token: 'native', amount: '1', payTo }) /
|
|
|
133
133
|
requirePayment({ chain: 'xrpl', token: 'native', amount: '1', payTo }) // XRP
|
|
134
134
|
```
|
|
135
135
|
|
|
136
|
-
**Native or stablecoin — your choice, on every chain.** Every gate accepts the chain's native coin (ETH, BNB, POL, AVAX, SOL, TON, XLM, XRP, SUI, NEAR, **TRX**, …) just as readily as a stablecoin — set `token: 'native'` and the SDK fills in the right decimals (18 on EVM, 9 on Solana/TON/Sui, 7 on Stellar, 6 on XRPL/Tron, 24 on NEAR). Verification, replay protection, and self-custody are identical to the stablecoin path — across **all
|
|
136
|
+
**Native or stablecoin — your choice, on every chain.** Every gate accepts the chain's native coin (ETH, BNB, POL, AVAX, SOL, TON, XLM, XRP, SUI, NEAR, **TRX**, …) just as readily as a stablecoin — set `token: 'native'` and the SDK fills in the right decimals (18 on EVM, 9 on Solana/TON/Sui, 7 on Stellar, 6 on XRPL/Tron, 24 on NEAR). Verification, replay protection, and self-custody are identical to the stablecoin path — across **all nine families, no exceptions**. (On **NEAR**, native is the zero-setup path — no `storage_deposit` — while the NEP-141 token path needs registration; see the NEAR note. On **Tron**, USD₮ is the default since TRX is volatile gas, but native TRX works too.)
|
|
137
137
|
|
|
138
138
|
`token` is **required** — every gate states exactly what it accepts, so there's never any doubt whether a route takes USDC, USDT, or the native coin. Name a built-in symbol (`'USDC'`, `'USDT'`), use `'native'` for the chain's own coin (ETH, BNB, SOL, TON, XLM, …), or pass a custom token by address. The symbol is all you write — the SDK fills in the contract + decimals.
|
|
139
139
|
|
|
@@ -167,6 +167,7 @@ Every token address below was verified on-chain (symbol + decimals) before shipp
|
|
|
167
167
|
| `'tron'` | Tron | USDT |
|
|
168
168
|
| `'near'` | NEAR | USDC, USDT |
|
|
169
169
|
| `'sui'` | Sui | USDC |
|
|
170
|
+
| `'aptos'` | Aptos | USDC, USDT |
|
|
170
171
|
| `'stellar'` | Stellar | USDC, EURC |
|
|
171
172
|
| `'xrpl'` | XRP Ledger | USDC, RLUSD |
|
|
172
173
|
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ConfirmationTimeoutError,
|
|
3
|
+
InsufficientFundsError,
|
|
4
|
+
UnknownTokenError,
|
|
5
|
+
WrongFamilyError,
|
|
6
|
+
nativeCost,
|
|
7
|
+
rejectForeignToken,
|
|
8
|
+
toInsufficientFundsError
|
|
9
|
+
} from "./chunk-AGKC3C7Y.js";
|
|
10
|
+
|
|
11
|
+
// src/drivers/aptos/index.ts
|
|
12
|
+
import { Aptos, AptosConfig, Network, AccountAddress } from "@aptos-labs/ts-sdk";
|
|
13
|
+
|
|
14
|
+
// src/drivers/aptos/chains.ts
|
|
15
|
+
var APT_DECIMALS = 8;
|
|
16
|
+
var APT_SYMBOL = "APT";
|
|
17
|
+
var APT_FA_METADATA = "0xa";
|
|
18
|
+
var APTOS_MAINNET = {
|
|
19
|
+
caip2: "aptos:1",
|
|
20
|
+
defaultRpc: "https://fullnode.mainnet.aptoslabs.com/v1",
|
|
21
|
+
tokens: {
|
|
22
|
+
// Circle USDC — FA metadata + 6 decimals verified live on mainnet
|
|
23
|
+
// (0x1::fungible_asset::Metadata → symbol "USDC", decimals 6) before shipping.
|
|
24
|
+
USDC: {
|
|
25
|
+
metadata: "0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b",
|
|
26
|
+
decimals: 6,
|
|
27
|
+
symbol: "USDC"
|
|
28
|
+
},
|
|
29
|
+
// Tether USD₮ — use the FA *metadata* address (NOT the issuer/creator address
|
|
30
|
+
// 0xf73e…73cb). Verified live (Metadata → name "Tether USD", symbol "USDt", decimals 6).
|
|
31
|
+
USDT: {
|
|
32
|
+
metadata: "0x357b0b74bc833e95a115ad22604854d6b0fca151cecd94111770e5d6ffc9dc2b",
|
|
33
|
+
decimals: 6,
|
|
34
|
+
symbol: "USDT"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// src/drivers/aptos/pay.ts
|
|
40
|
+
var MAX_GAS_AMOUNT = 5e4;
|
|
41
|
+
async function payAptos(params) {
|
|
42
|
+
const { client, signer, sender, accept } = params;
|
|
43
|
+
const metadata = accept.asset === "native" ? APT_FA_METADATA : accept.asset;
|
|
44
|
+
try {
|
|
45
|
+
const transaction = await client.build({
|
|
46
|
+
sender,
|
|
47
|
+
data: {
|
|
48
|
+
function: "0x1::primary_fungible_store::transfer",
|
|
49
|
+
typeArguments: ["0x1::fungible_asset::Metadata"],
|
|
50
|
+
// u64 amount goes as a base-unit string; the FA metadata object + recipient are addresses.
|
|
51
|
+
functionArguments: [metadata, accept.payTo, accept.amount]
|
|
52
|
+
},
|
|
53
|
+
options: { maxGasAmount: MAX_GAS_AMOUNT }
|
|
54
|
+
});
|
|
55
|
+
const res = await client.signSubmit({ signer, transaction });
|
|
56
|
+
return res.hash;
|
|
57
|
+
} catch (err) {
|
|
58
|
+
if (err instanceof InsufficientFundsError) throw err;
|
|
59
|
+
if (isAptosAffordability(err)) {
|
|
60
|
+
throw new InsufficientFundsError(
|
|
61
|
+
err instanceof Error ? err.message : "Insufficient APT/token balance for the payment.",
|
|
62
|
+
{ cause: err }
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
throw toInsufficientFundsError(err) ?? err;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function isAptosAffordability(err) {
|
|
69
|
+
const m = err instanceof Error ? err.message : String(err);
|
|
70
|
+
return /INSUFFICIENT_BALANCE|EINSUFFICIENT_BALANCE|insufficient.*(balance|gas|funds)|coin store|balance is too low|EINSUFFICIENT/i.test(
|
|
71
|
+
m
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// src/drivers/aptos/verify.ts
|
|
76
|
+
async function verifyAptos(params) {
|
|
77
|
+
const { reader, hash, accept } = params;
|
|
78
|
+
const required = BigInt(accept.amount);
|
|
79
|
+
const wantMetadata = accept.asset === "native" ? APT_FA_METADATA : accept.asset;
|
|
80
|
+
let tx;
|
|
81
|
+
try {
|
|
82
|
+
tx = await reader.getTransaction(hash);
|
|
83
|
+
} catch {
|
|
84
|
+
return txNotFound(hash);
|
|
85
|
+
}
|
|
86
|
+
if (!tx) return txNotFound(hash);
|
|
87
|
+
if (!tx.success) {
|
|
88
|
+
return { ok: false, error: "tx_reverted", detail: `Aptos tx ${hash} did not succeed.` };
|
|
89
|
+
}
|
|
90
|
+
if (typeof tx.timestampSeconds === "number") {
|
|
91
|
+
const ageSeconds = Math.floor(Date.now() / 1e3) - tx.timestampSeconds;
|
|
92
|
+
if (ageSeconds > accept.maxTimeoutSeconds) {
|
|
93
|
+
return {
|
|
94
|
+
ok: false,
|
|
95
|
+
error: "payment_expired",
|
|
96
|
+
detail: `Payment is ${ageSeconds}s old; max allowed is ${accept.maxTimeoutSeconds}s.`
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
let wantStore;
|
|
101
|
+
try {
|
|
102
|
+
wantStore = await reader.primaryStore(accept.payTo, wantMetadata);
|
|
103
|
+
} catch {
|
|
104
|
+
return txNotFound(hash);
|
|
105
|
+
}
|
|
106
|
+
let paid = 0n;
|
|
107
|
+
for (const d of tx.deposits) {
|
|
108
|
+
if (d.store !== wantStore) continue;
|
|
109
|
+
try {
|
|
110
|
+
paid += BigInt(d.amount);
|
|
111
|
+
} catch {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (paid < required) {
|
|
116
|
+
return {
|
|
117
|
+
ok: false,
|
|
118
|
+
error: "transfer_not_found",
|
|
119
|
+
detail: `No Aptos transfer of >= ${required} (${wantMetadata}) to ${accept.payTo} in ${hash}.`
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
ok: true,
|
|
124
|
+
receipt: {
|
|
125
|
+
scheme: "onchain-proof",
|
|
126
|
+
success: true,
|
|
127
|
+
network: accept.network,
|
|
128
|
+
transaction: hash,
|
|
129
|
+
asset: accept.asset,
|
|
130
|
+
amount: accept.amount,
|
|
131
|
+
payer: tx.sender,
|
|
132
|
+
payTo: accept.payTo,
|
|
133
|
+
verifiedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
function txNotFound(hash) {
|
|
138
|
+
return {
|
|
139
|
+
ok: false,
|
|
140
|
+
error: "tx_not_found",
|
|
141
|
+
detail: `Aptos tx ${hash} not found or not yet propagated \u2014 retry.`
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// src/drivers/aptos/wallet.ts
|
|
146
|
+
import { Account, Ed25519PrivateKey } from "@aptos-labs/ts-sdk";
|
|
147
|
+
function assertAptosWallet(wallet, network) {
|
|
148
|
+
if (typeof wallet !== "object" || wallet === null) {
|
|
149
|
+
throw new WrongFamilyError(
|
|
150
|
+
`chain ${network} is Aptos; wallet must be { privateKey } (ed25519-priv-0x\u2026) or { account }.`
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
if ("walletClient" in wallet) {
|
|
154
|
+
throw new WrongFamilyError(
|
|
155
|
+
`chain ${network} is Aptos; a viem { walletClient } can't be used \u2014 pass { privateKey } (ed25519-priv-0x\u2026) or { account }.`
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
if ("secretKey" in wallet || "signer" in wallet || "mnemonic" in wallet || "keypair" in wallet || "keyPair" in wallet || "secret" in wallet || "seed" in wallet || "accountId" in wallet) {
|
|
159
|
+
throw new WrongFamilyError(
|
|
160
|
+
`chain ${network} is Aptos; that looks like another family's wallet \u2014 pass { privateKey } (ed25519-priv-0x\u2026) or { account }.`
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
if (!("privateKey" in wallet) && !("account" in wallet)) {
|
|
164
|
+
throw new WrongFamilyError(
|
|
165
|
+
`chain ${network} is Aptos; wallet must be { privateKey } (ed25519-priv-0x\u2026) or { account }.`
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
return wallet;
|
|
169
|
+
}
|
|
170
|
+
function resolveAptosAccount(config) {
|
|
171
|
+
if (config.account) return config.account;
|
|
172
|
+
if (config.privateKey != null) {
|
|
173
|
+
try {
|
|
174
|
+
return Account.fromPrivateKey({ privateKey: new Ed25519PrivateKey(config.privateKey) });
|
|
175
|
+
} catch (cause) {
|
|
176
|
+
throw new WrongFamilyError(
|
|
177
|
+
"Aptos wallet { privateKey } is not a valid ed25519 secret (ed25519-priv-0x\u2026 or 0x\u2026 hex).",
|
|
178
|
+
{ cause }
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
throw new WrongFamilyError("Aptos wallet needs { privateKey } (ed25519-priv-0x\u2026) or { account }.");
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// src/drivers/aptos/index.ts
|
|
186
|
+
var aptosDriver = {
|
|
187
|
+
family: "aptos",
|
|
188
|
+
resolve(opts) {
|
|
189
|
+
if (opts.chain !== "aptos") return null;
|
|
190
|
+
const rpcUrl = opts.rpcUrl ?? APTOS_MAINNET.defaultRpc;
|
|
191
|
+
return makeAptosNetwork(APTOS_MAINNET, rpcUrl);
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
function norm(addr) {
|
|
195
|
+
try {
|
|
196
|
+
return AccountAddress.from(addr).toString();
|
|
197
|
+
} catch {
|
|
198
|
+
return addr;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
function makeAptosNetwork(preset, rpcUrl) {
|
|
202
|
+
const aptos = new Aptos(new AptosConfig({ network: Network.MAINNET, fullnode: rpcUrl }));
|
|
203
|
+
const network = preset.caip2;
|
|
204
|
+
const reader = {
|
|
205
|
+
async getTransaction(hash) {
|
|
206
|
+
const tx = await aptos.getTransactionByHash({ transactionHash: hash });
|
|
207
|
+
if (!tx || tx.type !== "user_transaction") return null;
|
|
208
|
+
const deposits = (tx.events ?? []).filter((e) => e.type === "0x1::fungible_asset::Deposit").map((e) => ({ store: norm(String(e.data.store)), amount: String(e.data.amount) }));
|
|
209
|
+
return {
|
|
210
|
+
success: tx.success === true,
|
|
211
|
+
// Aptos timestamps are microseconds since epoch.
|
|
212
|
+
timestampSeconds: tx.timestamp != null ? Math.floor(Number(tx.timestamp) / 1e6) : void 0,
|
|
213
|
+
sender: tx.sender ? norm(String(tx.sender)) : "",
|
|
214
|
+
deposits
|
|
215
|
+
};
|
|
216
|
+
},
|
|
217
|
+
async primaryStore(owner, metadata) {
|
|
218
|
+
const [addr] = await aptos.view({
|
|
219
|
+
payload: {
|
|
220
|
+
function: "0x1::primary_fungible_store::primary_store_address",
|
|
221
|
+
typeArguments: ["0x1::fungible_asset::Metadata"],
|
|
222
|
+
functionArguments: [owner, metadata]
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
return norm(String(addr));
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
const payClient = {
|
|
229
|
+
build: (input) => aptos.transaction.build.simple({
|
|
230
|
+
sender: input.sender,
|
|
231
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
232
|
+
data: input.data,
|
|
233
|
+
...input.options ? { options: input.options } : {}
|
|
234
|
+
}),
|
|
235
|
+
signSubmit: (input) => aptos.signAndSubmitTransaction({
|
|
236
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
237
|
+
signer: input.signer,
|
|
238
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
239
|
+
transaction: input.transaction
|
|
240
|
+
})
|
|
241
|
+
};
|
|
242
|
+
return {
|
|
243
|
+
family: "aptos",
|
|
244
|
+
network,
|
|
245
|
+
supports: (n) => n === network,
|
|
246
|
+
resolveToken(token) {
|
|
247
|
+
if (token === "native") {
|
|
248
|
+
return { asset: "native", decimals: APT_DECIMALS, symbol: APT_SYMBOL };
|
|
249
|
+
}
|
|
250
|
+
if (typeof token === "string") {
|
|
251
|
+
const info = preset.tokens[token.toUpperCase()];
|
|
252
|
+
if (!info) {
|
|
253
|
+
const known = Object.keys(preset.tokens).join(", ") || "(none built in)";
|
|
254
|
+
throw new UnknownTokenError(
|
|
255
|
+
`token "${token}" isn't built in for Aptos (known: ${known}). Pass { metadata, decimals } for a custom Fungible Asset, or use 'native'.`
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
return { asset: info.metadata, decimals: info.decimals, symbol: info.symbol };
|
|
259
|
+
}
|
|
260
|
+
rejectForeignToken(token, "aptos", network);
|
|
261
|
+
const t = token;
|
|
262
|
+
if (!t.metadata || typeof t.decimals !== "number") {
|
|
263
|
+
throw new WrongFamilyError(
|
|
264
|
+
`chain ${network} is Aptos; a custom token must be { metadata, decimals }.`
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
return {
|
|
268
|
+
asset: t.metadata,
|
|
269
|
+
decimals: t.decimals,
|
|
270
|
+
...t.symbol ? { symbol: t.symbol } : {}
|
|
271
|
+
};
|
|
272
|
+
},
|
|
273
|
+
describeAsset(asset) {
|
|
274
|
+
if (asset === "native") return { symbol: APT_SYMBOL, decimals: APT_DECIMALS };
|
|
275
|
+
for (const info of Object.values(preset.tokens)) {
|
|
276
|
+
if (info.metadata === asset) return { symbol: info.symbol, decimals: info.decimals };
|
|
277
|
+
}
|
|
278
|
+
return null;
|
|
279
|
+
},
|
|
280
|
+
assertValidPayTo(payTo) {
|
|
281
|
+
const evmLike = /^0x[0-9a-fA-F]{40}$/.test(payTo);
|
|
282
|
+
let valid = false;
|
|
283
|
+
try {
|
|
284
|
+
AccountAddress.from(payTo);
|
|
285
|
+
valid = true;
|
|
286
|
+
} catch {
|
|
287
|
+
valid = false;
|
|
288
|
+
}
|
|
289
|
+
if (!valid || evmLike) {
|
|
290
|
+
throw new WrongFamilyError(
|
|
291
|
+
`chain ${network} is Aptos, but payTo "${payTo}" is not a valid Aptos address (0x + 32 bytes).`
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
},
|
|
295
|
+
bindWallet(wallet) {
|
|
296
|
+
return { _native: assertAptosWallet(wallet, network) };
|
|
297
|
+
},
|
|
298
|
+
async send(wallet, accept) {
|
|
299
|
+
const account = resolveAptosAccount(wallet._native);
|
|
300
|
+
return payAptos({
|
|
301
|
+
client: payClient,
|
|
302
|
+
signer: account,
|
|
303
|
+
sender: account.accountAddress.toString(),
|
|
304
|
+
accept
|
|
305
|
+
});
|
|
306
|
+
},
|
|
307
|
+
async confirm(ref) {
|
|
308
|
+
try {
|
|
309
|
+
const tx = await aptos.waitForTransaction({ transactionHash: ref });
|
|
310
|
+
return { height: String(tx.version ?? "0") };
|
|
311
|
+
} catch (err) {
|
|
312
|
+
throw new ConfirmationTimeoutError(`Aptos tx ${ref} did not finalize in time.`, { cause: err });
|
|
313
|
+
}
|
|
314
|
+
},
|
|
315
|
+
async estimateCost() {
|
|
316
|
+
return nativeCost({
|
|
317
|
+
symbol: APT_SYMBOL,
|
|
318
|
+
decimals: APT_DECIMALS,
|
|
319
|
+
fee: 100000n,
|
|
320
|
+
// ~0.001 APT
|
|
321
|
+
basis: "heuristic",
|
|
322
|
+
detail: "\u22480.001 APT (a simple Fungible-Asset transfer; Aptos gas is sub-cent)"
|
|
323
|
+
});
|
|
324
|
+
},
|
|
325
|
+
async verify(ref, accept) {
|
|
326
|
+
return verifyAptos({ reader, hash: ref, accept });
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
export {
|
|
331
|
+
aptosDriver
|
|
332
|
+
};
|