@unicitylabs/bridge-plugin 0.2.0-dev.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/DEMO.md +255 -0
- package/README.md +89 -0
- package/lib/BridgeLockJustification.d.ts +31 -0
- package/lib/BridgeLockJustification.js +41 -0
- package/lib/BridgeMintJustificationVerifier.d.ts +12 -0
- package/lib/BridgeMintJustificationVerifier.js +35 -0
- package/lib/LockMintJustificationVerifier.d.ts +42 -0
- package/lib/LockMintJustificationVerifier.js +108 -0
- package/lib/address.d.ts +13 -0
- package/lib/address.js +71 -0
- package/lib/bridge-back/abi.d.ts +30 -0
- package/lib/bridge-back/abi.js +89 -0
- package/lib/bridge-back/burn.d.ts +79 -0
- package/lib/bridge-back/burn.js +78 -0
- package/lib/bridge-back/burned-blob.d.ts +6 -0
- package/lib/bridge-back/burned-blob.js +16 -0
- package/lib/bridge-back/cbor.d.ts +32 -0
- package/lib/bridge-back/cbor.js +146 -0
- package/lib/bridge-back/derivations.d.ts +112 -0
- package/lib/bridge-back/derivations.js +201 -0
- package/lib/bridge-back/index.d.ts +11 -0
- package/lib/bridge-back/index.js +11 -0
- package/lib/cli/main.d.ts +2 -0
- package/lib/cli/main.js +149 -0
- package/lib/cli/scenario.d.ts +36 -0
- package/lib/cli/scenario.js +94 -0
- package/lib/config.d.ts +25 -0
- package/lib/config.js +1 -0
- package/lib/contract-call.d.ts +13 -0
- package/lib/contract-call.js +19 -0
- package/lib/evm/EvmRpcClient.d.ts +25 -0
- package/lib/evm/EvmRpcClient.js +54 -0
- package/lib/evm/config.d.ts +6 -0
- package/lib/evm/config.js +6 -0
- package/lib/evm/family.d.ts +3 -0
- package/lib/evm/family.js +21 -0
- package/lib/evm/index.d.ts +6 -0
- package/lib/evm/index.js +6 -0
- package/lib/evm/presentation.d.ts +4 -0
- package/lib/evm/presentation.js +21 -0
- package/lib/evm/providers.d.ts +3 -0
- package/lib/evm/providers.js +9 -0
- package/lib/evm/signer.d.ts +43 -0
- package/lib/evm/signer.js +91 -0
- package/lib/families.d.ts +4 -0
- package/lib/families.js +11 -0
- package/lib/family.d.ts +16 -0
- package/lib/family.js +1 -0
- package/lib/hex.d.ts +4 -0
- package/lib/hex.js +33 -0
- package/lib/identifiers.d.ts +14 -0
- package/lib/identifiers.js +22 -0
- package/lib/index.d.ts +48 -0
- package/lib/index.js +55 -0
- package/lib/lock-event.d.ts +28 -0
- package/lib/lock-event.js +48 -0
- package/lib/source-chain.d.ts +29 -0
- package/lib/source-chain.js +1 -0
- package/lib/tron/TronRpcClient.d.ts +39 -0
- package/lib/tron/TronRpcClient.js +100 -0
- package/lib/tron/config.d.ts +11 -0
- package/lib/tron/config.js +31 -0
- package/lib/tron/family.d.ts +4 -0
- package/lib/tron/family.js +18 -0
- package/lib/tron/presentation.d.ts +10 -0
- package/lib/tron/presentation.js +18 -0
- package/lib/tron/providers.d.ts +46 -0
- package/lib/tron/providers.js +32 -0
- package/lib/tron/signer.d.ts +166 -0
- package/lib/tron/signer.js +238 -0
- package/lib/value.d.ts +23 -0
- package/lib/value.js +58 -0
- package/lib/wallet/allowance.d.ts +20 -0
- package/lib/wallet/allowance.js +27 -0
- package/lib/wallet/backing.d.ts +2 -0
- package/lib/wallet/backing.js +15 -0
- package/lib/wallet/facade.d.ts +97 -0
- package/lib/wallet/facade.js +100 -0
- package/lib/wallet/finality.d.ts +8 -0
- package/lib/wallet/finality.js +28 -0
- package/lib/wallet/index.d.ts +25 -0
- package/lib/wallet/index.js +25 -0
- package/lib/wallet/manifest.d.ts +69 -0
- package/lib/wallet/manifest.js +81 -0
- package/lib/wallet/manifests.d.ts +31 -0
- package/lib/wallet/manifests.js +70 -0
- package/lib/wallet/payout.d.ts +5 -0
- package/lib/wallet/payout.js +14 -0
- package/lib/wallet/registry.d.ts +40 -0
- package/lib/wallet/registry.js +34 -0
- package/lib/wallet/return-client.d.ts +91 -0
- package/lib/wallet/return-client.js +100 -0
- package/lib/wallet/self-mint-verifier.d.ts +10 -0
- package/lib/wallet/self-mint-verifier.js +5 -0
- package/lib/wallet/signer.d.ts +18 -0
- package/lib/wallet/signer.js +1 -0
- package/lib/wallet/source-adapter.d.ts +33 -0
- package/lib/wallet/source-adapter.js +99 -0
- package/lib/wallet/token-plugin.d.ts +4 -0
- package/lib/wallet/token-plugin.js +20 -0
- package/manifests/bridges.nile.json +23 -0
- package/package.json +71 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wallet integration surface (06 §A2.2). The single entry point a wallet (Sphere)
|
|
3
|
+
* imports — façade (plan builders), manifest (loader/type), the family-neutral
|
|
4
|
+
* signer contract and each family's wallets. Kept as a subpath, *not* merged
|
|
5
|
+
* into the package root, so the read-only re-exports here don't collide with
|
|
6
|
+
* the root's bridge-back exports.
|
|
7
|
+
*/
|
|
8
|
+
export * from './facade.js';
|
|
9
|
+
export * from './manifests.js';
|
|
10
|
+
export * from './registry.js';
|
|
11
|
+
export * from './signer.js';
|
|
12
|
+
export * from '../tron/signer.js';
|
|
13
|
+
export * from '../tron/providers.js';
|
|
14
|
+
export * from '../tron/presentation.js';
|
|
15
|
+
export * from '../evm/signer.js';
|
|
16
|
+
export * from '../evm/providers.js';
|
|
17
|
+
export * from '../evm/presentation.js';
|
|
18
|
+
export * from './allowance.js';
|
|
19
|
+
export * from './source-adapter.js';
|
|
20
|
+
export * from './return-client.js';
|
|
21
|
+
export * from './self-mint-verifier.js';
|
|
22
|
+
export * from './token-plugin.js';
|
|
23
|
+
export * from './backing.js';
|
|
24
|
+
export * from './finality.js';
|
|
25
|
+
export * from './payout.js';
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bridge manifest — the integrity-pinned descriptor a wallet (Sphere) loads to
|
|
3
|
+
* surface one bridged asset, plus the loader that turns it into a ready plugin.
|
|
4
|
+
*
|
|
5
|
+
* Decision #2 (06 §A2): Sphere holds *zero* chain-specific bridge code. It
|
|
6
|
+
* imports this façade + a manifest and renders UI; everything else (derivations,
|
|
7
|
+
* chain specifics, the verifier) lives here in the plugin. The manifest names the
|
|
8
|
+
* deployed vault/asset/config so the loader can (a) build the bridge plugin and
|
|
9
|
+
* its `IMintJustificationVerifier`, and (b) cross-check the declared `configHash`
|
|
10
|
+
* against the one recomputed from the manifest fields — a misconfigured manifest
|
|
11
|
+
* fails loudly at load, never silently accepts a wrong trust anchor.
|
|
12
|
+
*/
|
|
13
|
+
import type { BridgeManifestBase, BridgePresentation } from '@unicitylabs/bridge-core';
|
|
14
|
+
import { toEvmAddressHex } from '../address.js';
|
|
15
|
+
import { type BridgeConfig } from '../bridge-back/derivations.js';
|
|
16
|
+
import { BRIDGE_LOCK_JUSTIFICATION_TAG } from '../BridgeLockJustification.js';
|
|
17
|
+
import type { BridgeAssetConfig } from '../config.js';
|
|
18
|
+
import { type BridgePlugin, type CreateBridgePluginDeps } from '../index.js';
|
|
19
|
+
export type { BridgeManifestBase } from '@unicitylabs/bridge-core';
|
|
20
|
+
export { evmChainRef } from '../evm/family.js';
|
|
21
|
+
export { tronChainRef } from '../tron/family.js';
|
|
22
|
+
/** A Tron-family bridged-asset manifest. `chainId` is Tron's genesis-derived id, cross-checked against `chainRef`. */
|
|
23
|
+
export interface TronBridgeManifest extends BridgeManifestBase {
|
|
24
|
+
readonly family: 'tron';
|
|
25
|
+
readonly chainId: number;
|
|
26
|
+
/** Tron HTTP RPC base URL. */
|
|
27
|
+
readonly rpcUrl: string;
|
|
28
|
+
/** Optional TronGrid API key. */
|
|
29
|
+
readonly apiKey?: string;
|
|
30
|
+
}
|
|
31
|
+
/** An Ethereum-family (eip155) bridged-asset manifest. `chainId` is the EIP-155 id, cross-checked against `chainRef`. */
|
|
32
|
+
export interface EvmBridgeManifest extends BridgeManifestBase {
|
|
33
|
+
readonly family: 'eip155';
|
|
34
|
+
readonly chainId: number;
|
|
35
|
+
/** JSON-RPC endpoint. */
|
|
36
|
+
readonly rpcUrl: string;
|
|
37
|
+
}
|
|
38
|
+
export type BridgeManifest = TronBridgeManifest | EvmBridgeManifest;
|
|
39
|
+
/** A manifest entry resolved into everything the wallet needs to use it. */
|
|
40
|
+
export interface LoadedBridge {
|
|
41
|
+
readonly manifest: BridgeManifest;
|
|
42
|
+
/** The ready plugin (TokenType/coinId derivations + the registered verifier). */
|
|
43
|
+
readonly plugin: BridgePlugin;
|
|
44
|
+
/** The `BridgeConfig` the bridge-back reason/nullifier bind to (00 §2). */
|
|
45
|
+
readonly bridgeConfig: BridgeConfig;
|
|
46
|
+
/** 32-byte `configHash` recomputed from the manifest (== `manifest.configHash`). */
|
|
47
|
+
readonly configHash: Uint8Array;
|
|
48
|
+
}
|
|
49
|
+
export declare function assetConfigFromManifest(m: BridgeManifest, confirmations: number): BridgeAssetConfig;
|
|
50
|
+
/** Build the canonical {BridgeConfig} (00 §2) from a manifest + a resolved plugin. */
|
|
51
|
+
export declare function bridgeConfigFromManifest(m: BridgeManifest, plugin: BridgePlugin): BridgeConfig;
|
|
52
|
+
/**
|
|
53
|
+
* Resolve a manifest (or array) into ready {LoadedBridge}s. Throws if a declared
|
|
54
|
+
* identifier (`tokenTypeHex`/`coinIdHex`/`configHash`) does not match the value
|
|
55
|
+
* recomputed from the manifest fields — the integrity-pin (06 Risks: manifest
|
|
56
|
+
* trust-anchor misconfig).
|
|
57
|
+
*/
|
|
58
|
+
export declare function loadBridges(manifest: BridgeManifest | readonly BridgeManifest[], deps?: CreateBridgePluginDeps): LoadedBridge[];
|
|
59
|
+
/**
|
|
60
|
+
* The {BridgePresentation} for a resolved bridge, from its chain family, so the
|
|
61
|
+
* wallet UI asks the bridge for its explorer link / address validation instead
|
|
62
|
+
* of keying on a numeric chainId (08 §8).
|
|
63
|
+
*/
|
|
64
|
+
export declare function bridgePresentation(bridge: LoadedBridge): BridgePresentation;
|
|
65
|
+
export declare function chainName(bridge: LoadedBridge): string;
|
|
66
|
+
/** The justification CBOR tag every bridged mint reason carries (dispatch key). */
|
|
67
|
+
export { BRIDGE_LOCK_JUSTIFICATION_TAG };
|
|
68
|
+
/** Normalize any address form to 20-byte EVM-style hex (re-exported for UI). */
|
|
69
|
+
export { toEvmAddressHex };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { toEvmAddressHex } from '../address.js';
|
|
2
|
+
import { configHash as deriveConfigHash } from '../bridge-back/derivations.js';
|
|
3
|
+
import { BRIDGE_LOCK_JUSTIFICATION_TAG } from '../BridgeLockJustification.js';
|
|
4
|
+
import { chainFamily } from '../families.js';
|
|
5
|
+
import { fromHex, toHex } from '../hex.js';
|
|
6
|
+
import { createBridgePlugin } from '../index.js';
|
|
7
|
+
export { evmChainRef } from '../evm/family.js';
|
|
8
|
+
export { tronChainRef } from '../tron/family.js';
|
|
9
|
+
export function assetConfigFromManifest(m, confirmations) {
|
|
10
|
+
return {
|
|
11
|
+
family: m.family,
|
|
12
|
+
chainId: m.chainId,
|
|
13
|
+
lockContract: m.vault,
|
|
14
|
+
assetContract: m.asset,
|
|
15
|
+
confirmations,
|
|
16
|
+
decimals: m.decimals,
|
|
17
|
+
rpcUrl: m.rpcUrl,
|
|
18
|
+
apiKey: m.family === 'tron' ? m.apiKey : undefined,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/** Build the canonical {BridgeConfig} (00 §2) from a manifest + a resolved plugin. */
|
|
22
|
+
export function bridgeConfigFromManifest(m, plugin) {
|
|
23
|
+
return {
|
|
24
|
+
sourceChainId: BigInt(plugin.resolvedConfig.chainId),
|
|
25
|
+
vault: fromHex(plugin.resolvedConfig.lockContractHex),
|
|
26
|
+
asset: fromHex(plugin.resolvedConfig.assetContractHex),
|
|
27
|
+
tokenType: plugin.resolvedConfig.tokenType,
|
|
28
|
+
coinId: plugin.resolvedConfig.coinId,
|
|
29
|
+
reasonTag: BigInt(m.reasonTag),
|
|
30
|
+
lockDomain: fromHex(m.lockDomain),
|
|
31
|
+
nullifierDomain: fromHex(m.nullifierDomain),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Resolve a manifest (or array) into ready {LoadedBridge}s. Throws if a declared
|
|
36
|
+
* identifier (`tokenTypeHex`/`coinIdHex`/`configHash`) does not match the value
|
|
37
|
+
* recomputed from the manifest fields — the integrity-pin (06 Risks: manifest
|
|
38
|
+
* trust-anchor misconfig).
|
|
39
|
+
*/
|
|
40
|
+
export function loadBridges(manifest, deps = {}) {
|
|
41
|
+
const list = Array.isArray(manifest) ? manifest : [manifest];
|
|
42
|
+
return list.map((m) => loadOne(m, deps));
|
|
43
|
+
}
|
|
44
|
+
function loadOne(m, deps) {
|
|
45
|
+
// The generic chainRef must agree with the family's native chainId — an
|
|
46
|
+
// integrity pin like tokenType/coinId/configHash: a misdescribed chain fails
|
|
47
|
+
// loudly at load.
|
|
48
|
+
const expectedRef = chainFamily(m.family).chainRef(m.chainId);
|
|
49
|
+
if (m.chainRef.toLowerCase() !== expectedRef.toLowerCase()) {
|
|
50
|
+
throw new Error(`BridgeManifest(${m.label}): chainRef mismatch — declared ${m.chainRef}, derived ${expectedRef} from chainId ${m.chainId}`);
|
|
51
|
+
}
|
|
52
|
+
const plugin = createBridgePlugin(assetConfigFromManifest(m, m.confirmations), deps);
|
|
53
|
+
if (m.tokenTypeHex && m.tokenTypeHex.toLowerCase() !== plugin.tokenTypeHex) {
|
|
54
|
+
throw new Error(`BridgeManifest(${m.label}): tokenTypeHex mismatch — declared ${m.tokenTypeHex}, derived ${plugin.tokenTypeHex}`);
|
|
55
|
+
}
|
|
56
|
+
if (m.coinIdHex && m.coinIdHex.toLowerCase() !== plugin.coinIdHex) {
|
|
57
|
+
throw new Error(`BridgeManifest(${m.label}): coinIdHex mismatch — declared ${m.coinIdHex}, derived ${plugin.coinIdHex}`);
|
|
58
|
+
}
|
|
59
|
+
const bridgeConfig = bridgeConfigFromManifest(m, plugin);
|
|
60
|
+
const configHash = deriveConfigHash(bridgeConfig);
|
|
61
|
+
if (toHex(configHash) !== m.configHash.toLowerCase()) {
|
|
62
|
+
throw new Error(`BridgeManifest(${m.label}): configHash mismatch — declared ${m.configHash}, derived ${toHex(configHash)}. ` +
|
|
63
|
+
`The manifest does not describe the deployed vault.`);
|
|
64
|
+
}
|
|
65
|
+
return { manifest: m, plugin, bridgeConfig, configHash };
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The {BridgePresentation} for a resolved bridge, from its chain family, so the
|
|
69
|
+
* wallet UI asks the bridge for its explorer link / address validation instead
|
|
70
|
+
* of keying on a numeric chainId (08 §8).
|
|
71
|
+
*/
|
|
72
|
+
export function bridgePresentation(bridge) {
|
|
73
|
+
return chainFamily(bridge.manifest.family).presentation(bridge.manifest.chainId);
|
|
74
|
+
}
|
|
75
|
+
export function chainName(bridge) {
|
|
76
|
+
return chainFamily(bridge.manifest.family).chainName;
|
|
77
|
+
}
|
|
78
|
+
/** The justification CBOR tag every bridged mint reason carries (dispatch key). */
|
|
79
|
+
export { BRIDGE_LOCK_JUSTIFICATION_TAG };
|
|
80
|
+
/** Normalize any address form to 20-byte EVM-style hex (re-exported for UI). */
|
|
81
|
+
export { toEvmAddressHex };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in {BridgeManifest}s for known deployments. Frozen from
|
|
3
|
+
* `deployments/nile/nile-usdt.json` (the cross-stack config freeze —
|
|
4
|
+
* `configHash` equals the deployed vault's on-chain `CONFIG_HASH`). A wallet can
|
|
5
|
+
* import one of these directly instead of shipping its own manifest file.
|
|
6
|
+
*/
|
|
7
|
+
import type { BridgeManifest, EvmBridgeManifest, TronBridgeManifest } from './manifest.js';
|
|
8
|
+
/**
|
|
9
|
+
* Tron Nile testnet USDT — the **live v2** deployment (2026-09-21). Vault
|
|
10
|
+
* `TBKJ84417jdxo6j92TxQuYpZdRZGaeZVrv`, BridgeBackReason tag **39048** (distinct
|
|
11
|
+
* from SpherePaymentData tag 39050), real SP1 verifier `TN4nQmnVz3H3zDnN77NQZTAfBpzkEdoeBR`
|
|
12
|
+
* (vkey `0x0039a542…` — the BRIDGE_PROTO_VERSION 2 guest, which reads the wallet's
|
|
13
|
+
* value payload and rejects empty burn batches), the R6 false-tolerant safe-transfer
|
|
14
|
+
* (with an explicit energy stipend — TVM doesn't reliably forward all remaining
|
|
15
|
+
* energy to a bare nested `.call()`) for the non-standard Nile USDT
|
|
16
|
+
* `TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf`, push-payment. `configHash` equals the
|
|
17
|
+
* vault's on-chain `CONFIG_HASH` (cross-checked TS == Solidity), the integrity
|
|
18
|
+
* pin. tokenType/coinId are asset-derived (stable across vault redeploys).
|
|
19
|
+
*
|
|
20
|
+
* `returnServiceUrl` defaults to a local Part-B service; override per environment.
|
|
21
|
+
*
|
|
22
|
+
* Disabled since 2026-09-22: Tron bounds a transaction to 80 ms of CPU and the
|
|
23
|
+
* Groth16 verification needs more, so no return can settle on any Tron network
|
|
24
|
+
* (docs/OPERATIONS.md §10). The entry stays listed so the wallet keeps showing
|
|
25
|
+
* the deployment and its tokens; it refuses new locks and burns.
|
|
26
|
+
*/
|
|
27
|
+
export declare const NILE_USDT_BRIDGE: TronBridgeManifest;
|
|
28
|
+
export declare const NILE_USDT_BRIDGE_V1: TronBridgeManifest;
|
|
29
|
+
export declare const SEPOLIA_USDC_BRIDGE: EvmBridgeManifest;
|
|
30
|
+
/** Override the return-service URL on a manifest (env-specific, keeps the freeze intact). */
|
|
31
|
+
export declare function withReturnServiceUrl<M extends BridgeManifest>(m: M, returnServiceUrl: string): M;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tron Nile testnet USDT — the **live v2** deployment (2026-09-21). Vault
|
|
3
|
+
* `TBKJ84417jdxo6j92TxQuYpZdRZGaeZVrv`, BridgeBackReason tag **39048** (distinct
|
|
4
|
+
* from SpherePaymentData tag 39050), real SP1 verifier `TN4nQmnVz3H3zDnN77NQZTAfBpzkEdoeBR`
|
|
5
|
+
* (vkey `0x0039a542…` — the BRIDGE_PROTO_VERSION 2 guest, which reads the wallet's
|
|
6
|
+
* value payload and rejects empty burn batches), the R6 false-tolerant safe-transfer
|
|
7
|
+
* (with an explicit energy stipend — TVM doesn't reliably forward all remaining
|
|
8
|
+
* energy to a bare nested `.call()`) for the non-standard Nile USDT
|
|
9
|
+
* `TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf`, push-payment. `configHash` equals the
|
|
10
|
+
* vault's on-chain `CONFIG_HASH` (cross-checked TS == Solidity), the integrity
|
|
11
|
+
* pin. tokenType/coinId are asset-derived (stable across vault redeploys).
|
|
12
|
+
*
|
|
13
|
+
* `returnServiceUrl` defaults to a local Part-B service; override per environment.
|
|
14
|
+
*
|
|
15
|
+
* Disabled since 2026-09-22: Tron bounds a transaction to 80 ms of CPU and the
|
|
16
|
+
* Groth16 verification needs more, so no return can settle on any Tron network
|
|
17
|
+
* (docs/OPERATIONS.md §10). The entry stays listed so the wallet keeps showing
|
|
18
|
+
* the deployment and its tokens; it refuses new locks and burns.
|
|
19
|
+
*/
|
|
20
|
+
export const NILE_USDT_BRIDGE = {
|
|
21
|
+
family: 'tron',
|
|
22
|
+
label: 'USDT (bridged · Tron)',
|
|
23
|
+
symbol: 'USDT',
|
|
24
|
+
chainRef: 'tron:0xcd8690dc',
|
|
25
|
+
chainId: 3448148188,
|
|
26
|
+
vault: 'TBKJ84417jdxo6j92TxQuYpZdRZGaeZVrv',
|
|
27
|
+
asset: 'TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf',
|
|
28
|
+
confirmations: 20,
|
|
29
|
+
decimals: 6,
|
|
30
|
+
rpcUrl: 'https://nile.trongrid.io',
|
|
31
|
+
returnServiceUrl: 'http://localhost:8787',
|
|
32
|
+
reasonTag: 39048,
|
|
33
|
+
lockDomain: '158b847f78b3910a5f5f42820de61abba1bf5ae1fbb29dabfba09118f393f932',
|
|
34
|
+
nullifierDomain: 'd4530e4ea58fc8e38f84506e62b421476c3eeec70f4cbebefc32688a510e2d5d',
|
|
35
|
+
vkey: '0x0039a5424014e57caf45d3451053e6c014547837ae09c9eb724aa569389b90d5',
|
|
36
|
+
configHash: 'fa77a13a6fb24658fa75377b0eef7cf3e92f8caede9ea127afe21be7a036cb1b',
|
|
37
|
+
tokenTypeHex: '6f2d10d27abeb4960a7ef19370c965ec090bb4da1f17752be77334e2dde19c74',
|
|
38
|
+
coinIdHex: 'f1634862e1b932acd1c791a1860c62f69c7f55aa6c6115ba631d3bf4a9d8ddbb',
|
|
39
|
+
disabledReason: 'Tron limits a transaction to 80 ms of CPU, less than the proof verification needs, so returns cannot settle. Bridging on Tron is paused.',
|
|
40
|
+
};
|
|
41
|
+
export const NILE_USDT_BRIDGE_V1 = {
|
|
42
|
+
...NILE_USDT_BRIDGE,
|
|
43
|
+
vault: 'TTKKLyhnRRQ7XV5vsRarV8xWWEvF9225mY',
|
|
44
|
+
vkey: '0x00c34ae0ebb63e86218a754892813f4744b2f6c9ed613c085ea40999b16ce3ad',
|
|
45
|
+
configHash: '7f376b16b3bff3455f375e7cf30b9d29d2a14332912f0ffb69d78e1b31d5193f',
|
|
46
|
+
};
|
|
47
|
+
export const SEPOLIA_USDC_BRIDGE = {
|
|
48
|
+
family: 'eip155',
|
|
49
|
+
label: 'USDC (bridged · Ethereum)',
|
|
50
|
+
symbol: 'USDC',
|
|
51
|
+
chainRef: 'eip155:11155111',
|
|
52
|
+
chainId: 11155111,
|
|
53
|
+
vault: '0x9C2BF4Ed5b85130fFD14BE8FA65c60F299Fc9a2E',
|
|
54
|
+
asset: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238',
|
|
55
|
+
confirmations: 12,
|
|
56
|
+
decimals: 6,
|
|
57
|
+
rpcUrl: 'https://ethereum-sepolia-rpc.publicnode.com',
|
|
58
|
+
returnServiceUrl: 'http://localhost:8787',
|
|
59
|
+
reasonTag: 39048,
|
|
60
|
+
lockDomain: '158b847f78b3910a5f5f42820de61abba1bf5ae1fbb29dabfba09118f393f932',
|
|
61
|
+
nullifierDomain: 'd4530e4ea58fc8e38f84506e62b421476c3eeec70f4cbebefc32688a510e2d5d',
|
|
62
|
+
vkey: '0x0039a5424014e57caf45d3451053e6c014547837ae09c9eb724aa569389b90d5',
|
|
63
|
+
configHash: '4058e87dff330d9c6925af755e0732dbc80be85643fdce46c8315eae51c9f7e8',
|
|
64
|
+
tokenTypeHex: '2ccbf3157add2b9a2dcc10e772abf5cf328e2723f9f290a9d2b6c4a42a132d6c',
|
|
65
|
+
coinIdHex: 'eae954053183b9d1836d6b5c892867014bcc1571fcc6813f5b56b16a78d0497f',
|
|
66
|
+
};
|
|
67
|
+
/** Override the return-service URL on a manifest (env-specific, keeps the freeze intact). */
|
|
68
|
+
export function withReturnServiceUrl(m, returnServiceUrl) {
|
|
69
|
+
return { ...m, returnServiceUrl };
|
|
70
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ContractCall } from '../contract-call.js';
|
|
2
|
+
import type { ConstantCaller } from '../source-chain.js';
|
|
3
|
+
import type { LoadedBridge } from './manifest.js';
|
|
4
|
+
export declare function owedTo(bridge: LoadedBridge, rpc: ConstantCaller, destination: string): Promise<bigint>;
|
|
5
|
+
export declare function withdrawCall(bridge: LoadedBridge): ContractCall;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { toEvmAddressHex } from '../address.js';
|
|
2
|
+
export async function owedTo(bridge, rpc, destination) {
|
|
3
|
+
const destinationHex = toEvmAddressHex(destination);
|
|
4
|
+
const word = await rpc.constantCall({
|
|
5
|
+
ownerHex: destinationHex,
|
|
6
|
+
contractHex: bridge.plugin.resolvedConfig.lockContractHex,
|
|
7
|
+
functionSignature: 'owed(address)',
|
|
8
|
+
parameterHex: destinationHex.padStart(64, '0'),
|
|
9
|
+
});
|
|
10
|
+
return word ? BigInt('0x' + word) : 0n;
|
|
11
|
+
}
|
|
12
|
+
export function withdrawCall(bridge) {
|
|
13
|
+
return { contractHex: bridge.plugin.resolvedConfig.lockContractHex, functionSignature: 'withdraw()', parameters: [] };
|
|
14
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bridge registry (08 Phase 4 — "manifest registry keyed by family+chain+asset").
|
|
3
|
+
*
|
|
4
|
+
* A wallet may load several bridged assets across chains; this indexes the
|
|
5
|
+
* resolved {LoadedBridge}s so a flow can address one deterministically. The
|
|
6
|
+
* canonical key is **family + chain + asset** — expressed as `chainRef` (which
|
|
7
|
+
* already encodes `family:chain`, e.g. `tron:0xcd8690dc`) plus the resolved asset
|
|
8
|
+
* hex. That key is **stable across vault redeploys**: a redeploy changes the vault
|
|
9
|
+
* address (and `configHash`), but the same asset on the same chain keeps the same
|
|
10
|
+
* key — so pending balances/records keep resolving to their bridge (00 "redeploy /
|
|
11
|
+
* migration discipline"). Registering two manifests for the same key is a config
|
|
12
|
+
* error and throws.
|
|
13
|
+
*
|
|
14
|
+
* Chain-neutral: it reads only `manifest.chainRef` + the plugin's resolved asset
|
|
15
|
+
* hex / coinId / tokenType — no Tron-specific logic — so a second family drops in
|
|
16
|
+
* without touching this file.
|
|
17
|
+
*/
|
|
18
|
+
import type { LoadedBridge } from './manifest.js';
|
|
19
|
+
/**
|
|
20
|
+
* The family+chain+asset key for a resolved bridge — stable across vault
|
|
21
|
+
* redeploys. `chainRef` carries `family:chain`; the resolved asset hex completes it.
|
|
22
|
+
*/
|
|
23
|
+
export declare function bridgeAssetKey(bridge: LoadedBridge): string;
|
|
24
|
+
/** An index over the app's resolved bridges, keyed for deterministic lookup. */
|
|
25
|
+
export interface BridgeRegistry {
|
|
26
|
+
/** Every registered bridge (insertion order). */
|
|
27
|
+
readonly all: readonly LoadedBridge[];
|
|
28
|
+
/** By the family+chain+asset key ({bridgeAssetKey}); undefined if not registered. */
|
|
29
|
+
byKey(key: string): LoadedBridge | undefined;
|
|
30
|
+
/** By the bridged coinId (what the wallet UI holds); case-insensitive. */
|
|
31
|
+
byCoinId(coinIdHex: string): LoadedBridge | undefined;
|
|
32
|
+
/** By the Unicity TokenType; case-insensitive. */
|
|
33
|
+
byTokenType(tokenTypeHex: string): LoadedBridge | undefined;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Build a {BridgeRegistry} from resolved bridges. Throws on a duplicate
|
|
37
|
+
* family+chain+asset key — two manifests describing the same bridged asset is a
|
|
38
|
+
* misconfiguration, never a silent last-one-wins.
|
|
39
|
+
*/
|
|
40
|
+
export declare function buildBridgeRegistry(loaded: readonly LoadedBridge[]): BridgeRegistry;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The family+chain+asset key for a resolved bridge — stable across vault
|
|
3
|
+
* redeploys. `chainRef` carries `family:chain`; the resolved asset hex completes it.
|
|
4
|
+
*/
|
|
5
|
+
export function bridgeAssetKey(bridge) {
|
|
6
|
+
return `${bridge.manifest.chainRef}:${bridge.plugin.resolvedConfig.assetContractHex}`;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Build a {BridgeRegistry} from resolved bridges. Throws on a duplicate
|
|
10
|
+
* family+chain+asset key — two manifests describing the same bridged asset is a
|
|
11
|
+
* misconfiguration, never a silent last-one-wins.
|
|
12
|
+
*/
|
|
13
|
+
export function buildBridgeRegistry(loaded) {
|
|
14
|
+
const byKey = new Map();
|
|
15
|
+
const byCoin = new Map();
|
|
16
|
+
const byType = new Map();
|
|
17
|
+
for (const bridge of loaded) {
|
|
18
|
+
const key = bridgeAssetKey(bridge);
|
|
19
|
+
const existing = byKey.get(key);
|
|
20
|
+
if (existing) {
|
|
21
|
+
throw new Error(`Duplicate bridge for ${key}: "${bridge.manifest.label}" and "${existing.manifest.label}" ` +
|
|
22
|
+
`describe the same family+chain+asset.`);
|
|
23
|
+
}
|
|
24
|
+
byKey.set(key, bridge);
|
|
25
|
+
byCoin.set(bridge.plugin.coinIdHex, bridge);
|
|
26
|
+
byType.set(bridge.plugin.tokenTypeHex, bridge);
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
all: loaded,
|
|
30
|
+
byKey: (key) => byKey.get(key),
|
|
31
|
+
byCoinId: (coinIdHex) => byCoin.get(coinIdHex.toLowerCase()),
|
|
32
|
+
byTokenType: (tokenTypeHex) => byType.get(tokenTypeHex.toLowerCase()),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { WitnessRequest } from '../bridge-back/burn.js';
|
|
2
|
+
/** Lifecycle of a submitted return (07 §B4 — matches the service's status enum). */
|
|
3
|
+
export type ReturnStatus = 'queued' | 'proving' | 'proven' | 'submitted' | 'settled' | 'failed';
|
|
4
|
+
/** Typed failure detail (service `failure` object). */
|
|
5
|
+
export interface ReturnFailure {
|
|
6
|
+
readonly kind: string;
|
|
7
|
+
readonly message: string;
|
|
8
|
+
readonly recoverable: boolean;
|
|
9
|
+
}
|
|
10
|
+
/** A return record as the service reports it (camelCase, `/returns/:id`). */
|
|
11
|
+
export interface ReturnRecord {
|
|
12
|
+
readonly returnId: string;
|
|
13
|
+
/** 32-byte nullifier (hex) — the wallet's idempotency key. */
|
|
14
|
+
readonly nullifier: string;
|
|
15
|
+
readonly status: ReturnStatus;
|
|
16
|
+
/** Terminal (`settled`/`failed`) — stop polling. */
|
|
17
|
+
readonly terminal?: boolean;
|
|
18
|
+
readonly success?: boolean | null;
|
|
19
|
+
/** 0–100 coarse progress for the UI. */
|
|
20
|
+
readonly progress?: number;
|
|
21
|
+
/** Human status message. */
|
|
22
|
+
readonly message?: string;
|
|
23
|
+
/** Suggested next poll delay (ms); 0 when terminal. */
|
|
24
|
+
readonly nextPollMs?: number;
|
|
25
|
+
/** Batch the return landed in, once sequenced. */
|
|
26
|
+
readonly batchId?: string;
|
|
27
|
+
/** `fulfillBatch` txid, on settle (denormalized from the batch). */
|
|
28
|
+
readonly settleTxid?: string;
|
|
29
|
+
/** Typed failure detail for `failed`. */
|
|
30
|
+
readonly failure?: ReturnFailure;
|
|
31
|
+
readonly attempts?: number;
|
|
32
|
+
readonly notBeforeMs?: number | null;
|
|
33
|
+
readonly queuePosition?: number | null;
|
|
34
|
+
readonly createdAtMs?: number;
|
|
35
|
+
readonly updatedAtMs?: number;
|
|
36
|
+
/** True only on the `POST /returns` response when the nullifier was already known. */
|
|
37
|
+
readonly duplicate?: boolean;
|
|
38
|
+
}
|
|
39
|
+
/** `/health` snapshot (07 §B4) — used for batch-ETA + ops display. */
|
|
40
|
+
export interface ReturnServiceHealth {
|
|
41
|
+
readonly status: string;
|
|
42
|
+
readonly queueDepth: number;
|
|
43
|
+
/** The batch currently proving, if any. */
|
|
44
|
+
readonly activeBatch?: string | null;
|
|
45
|
+
readonly activeBatchSize: number;
|
|
46
|
+
readonly provingSinceMs?: number | null;
|
|
47
|
+
readonly lastProofMs?: number | null;
|
|
48
|
+
readonly averageProofMs?: number | null;
|
|
49
|
+
readonly maxBatchSize: number;
|
|
50
|
+
readonly idleWaitMs: number;
|
|
51
|
+
/** `PrecheckOnly` | `Sp1Groth16`. */
|
|
52
|
+
readonly proveMode: string;
|
|
53
|
+
}
|
|
54
|
+
/** The published on-chain bundle (07 §B4) — anyone can self-submit it. */
|
|
55
|
+
export interface BatchBundle {
|
|
56
|
+
readonly batchId: string;
|
|
57
|
+
readonly mode: string;
|
|
58
|
+
readonly vkey?: string | null;
|
|
59
|
+
readonly publicValues: string;
|
|
60
|
+
readonly proofBytes: string;
|
|
61
|
+
readonly settleTxid?: string | null;
|
|
62
|
+
}
|
|
63
|
+
export interface ReturnServiceClientOptions {
|
|
64
|
+
/** `fetch` impl (default: the global one). Injectable for tests. */
|
|
65
|
+
readonly fetch?: typeof fetch;
|
|
66
|
+
}
|
|
67
|
+
/** Thin REST client over the return service base URL. */
|
|
68
|
+
export declare class ReturnServiceClient {
|
|
69
|
+
private readonly base;
|
|
70
|
+
private readonly doFetch;
|
|
71
|
+
constructor(baseUrl: string, opts?: ReturnServiceClientOptions);
|
|
72
|
+
/** Submit a witness request; idempotent on `nullifier`. S1 precheck rejects bad burns synchronously. */
|
|
73
|
+
postReturn(req: WitnessRequest): Promise<ReturnRecord>;
|
|
74
|
+
/** Status of a return by id. */
|
|
75
|
+
getReturn(returnId: string): Promise<ReturnRecord>;
|
|
76
|
+
/** Lookup by nullifier (32-byte hex) — wallet idempotency / recovery. */
|
|
77
|
+
getByNullifier(nullifierHex: string): Promise<ReturnRecord | null>;
|
|
78
|
+
/** The published bundle for a batch (self-settle source). */
|
|
79
|
+
getBatch(batchId: string): Promise<BatchBundle>;
|
|
80
|
+
/** Service health (queue depth, prover busy, gas) for batch-ETA + ops UI. */
|
|
81
|
+
getHealth(): Promise<ReturnServiceHealth>;
|
|
82
|
+
private json;
|
|
83
|
+
}
|
|
84
|
+
/** A typed return-service rejection (07 §B4). `recoverable: false` means retrying the
|
|
85
|
+
* exact same request will never succeed (e.g. a stale configHash after a vault
|
|
86
|
+
* redeploy) — callers should stop retrying and surface it as terminal. */
|
|
87
|
+
export declare class ReturnServiceError extends Error {
|
|
88
|
+
readonly code: string;
|
|
89
|
+
readonly recoverable: boolean;
|
|
90
|
+
constructor(message: string, code: string, recoverable: boolean);
|
|
91
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ReturnServiceClient` (06 §W3) — typed client for the Part-B return service
|
|
3
|
+
* (07 §B4). The wallet POSTs the {WitnessRequest} envelope and tracks the claim
|
|
4
|
+
* by polling `/returns/:id`; it *also* watches the vault's `Released{nullifier}`
|
|
5
|
+
* over Tron RPC independently (never trusts the service alone — 06 §A2.4). The
|
|
6
|
+
* service is trustless: it can't steal or forge, only sequence + prove (07 §B2).
|
|
7
|
+
*/
|
|
8
|
+
import { toHex } from '../hex.js';
|
|
9
|
+
/** Thin REST client over the return service base URL. */
|
|
10
|
+
export class ReturnServiceClient {
|
|
11
|
+
base;
|
|
12
|
+
doFetch;
|
|
13
|
+
constructor(baseUrl, opts = {}) {
|
|
14
|
+
this.base = baseUrl.replace(/\/+$/, '');
|
|
15
|
+
// Bind to globalThis: native `fetch` requires `this` to be the real global;
|
|
16
|
+
// calling it later as `this.doFetch(...)` would rebind `this` to the client
|
|
17
|
+
// instance and throw "Illegal invocation".
|
|
18
|
+
this.doFetch = opts.fetch ?? fetch.bind(globalThis);
|
|
19
|
+
}
|
|
20
|
+
/** Submit a witness request; idempotent on `nullifier`. S1 precheck rejects bad burns synchronously. */
|
|
21
|
+
async postReturn(req) {
|
|
22
|
+
const body = {
|
|
23
|
+
tokenCbor: toHex(req.tokenCbor),
|
|
24
|
+
configHash: toHex(req.configHash),
|
|
25
|
+
reasonBytes: toHex(req.reasonBytes),
|
|
26
|
+
...(req.anchorHint !== undefined ? { anchorHint: req.anchorHint.toString() } : {}),
|
|
27
|
+
};
|
|
28
|
+
return this.json('POST', '/returns', body);
|
|
29
|
+
}
|
|
30
|
+
/** Status of a return by id. */
|
|
31
|
+
getReturn(returnId) {
|
|
32
|
+
return this.json('GET', `/returns/${encodeURIComponent(returnId)}`);
|
|
33
|
+
}
|
|
34
|
+
/** Lookup by nullifier (32-byte hex) — wallet idempotency / recovery. */
|
|
35
|
+
getByNullifier(nullifierHex) {
|
|
36
|
+
return this.json('GET', `/returns?nullifier=${encodeURIComponent(nullifierHex.toLowerCase())}`);
|
|
37
|
+
}
|
|
38
|
+
/** The published bundle for a batch (self-settle source). */
|
|
39
|
+
getBatch(batchId) {
|
|
40
|
+
return this.json('GET', `/batches/${encodeURIComponent(batchId)}`);
|
|
41
|
+
}
|
|
42
|
+
/** Service health (queue depth, prover busy, gas) for batch-ETA + ops UI. */
|
|
43
|
+
getHealth() {
|
|
44
|
+
return this.json('GET', '/health');
|
|
45
|
+
}
|
|
46
|
+
async json(method, path, body) {
|
|
47
|
+
const res = await this.doFetch(`${this.base}${path}`, {
|
|
48
|
+
method,
|
|
49
|
+
headers: body === undefined ? undefined : { 'content-type': 'application/json' },
|
|
50
|
+
body: body === undefined ? undefined : JSON.stringify(body),
|
|
51
|
+
});
|
|
52
|
+
if (res.status === 404 && method === 'GET' && path.startsWith('/returns?')) {
|
|
53
|
+
return null; // not-found lookup is a clean "no record", not an error.
|
|
54
|
+
}
|
|
55
|
+
if (!res.ok) {
|
|
56
|
+
const text = await safeText(res);
|
|
57
|
+
const typed = parseTypedError(text);
|
|
58
|
+
if (typed) {
|
|
59
|
+
throw new ReturnServiceError(typed.message, typed.code, typed.recoverable);
|
|
60
|
+
}
|
|
61
|
+
throw new Error(`Return service ${method} ${path} failed: HTTP ${res.status} ${text}`);
|
|
62
|
+
}
|
|
63
|
+
return (await res.json());
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** `{error:{code,message,recoverable}}` (07 §B4 typed error shape). */
|
|
67
|
+
function parseTypedError(text) {
|
|
68
|
+
try {
|
|
69
|
+
const parsed = JSON.parse(text);
|
|
70
|
+
const e = parsed.error;
|
|
71
|
+
if (e && typeof e.code === 'string' && typeof e.message === 'string' && typeof e.recoverable === 'boolean') {
|
|
72
|
+
return { code: e.code, message: e.message, recoverable: e.recoverable };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
/* not JSON — fall through to the generic error */
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
/** A typed return-service rejection (07 §B4). `recoverable: false` means retrying the
|
|
81
|
+
* exact same request will never succeed (e.g. a stale configHash after a vault
|
|
82
|
+
* redeploy) — callers should stop retrying and surface it as terminal. */
|
|
83
|
+
export class ReturnServiceError extends Error {
|
|
84
|
+
code;
|
|
85
|
+
recoverable;
|
|
86
|
+
constructor(message, code, recoverable) {
|
|
87
|
+
super(message);
|
|
88
|
+
this.code = code;
|
|
89
|
+
this.recoverable = recoverable;
|
|
90
|
+
this.name = 'ReturnServiceError';
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async function safeText(res) {
|
|
94
|
+
try {
|
|
95
|
+
return await res.text();
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return '';
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The depositor's own mint-reason verifier: identical to the strict one the
|
|
3
|
+
* wallet registers, but at `confirmations: 0`. The depositor witnessed its own
|
|
4
|
+
* lock, so it accepts the mint as soon as the lock is in a block; every other
|
|
5
|
+
* wallet that receives the token re-verifies under the manifest's `K`.
|
|
6
|
+
*/
|
|
7
|
+
import type { IMintJustificationVerifier } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/IMintJustificationVerifier.js';
|
|
8
|
+
import { type CreateBridgePluginDeps } from '../index.js';
|
|
9
|
+
import { type LoadedBridge } from './manifest.js';
|
|
10
|
+
export declare function selfMintVerifier(bridge: LoadedBridge, deps?: CreateBridgePluginDeps): IMintJustificationVerifier;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ContractCall } from '../contract-call.js';
|
|
2
|
+
export interface SourceSigner {
|
|
3
|
+
connect(): Promise<string>;
|
|
4
|
+
getAddress(): Promise<string>;
|
|
5
|
+
getNetwork(): Promise<number>;
|
|
6
|
+
sendCall(call: ContractCall): Promise<string>;
|
|
7
|
+
onChange?(cb: (e: WalletChange) => void): () => void;
|
|
8
|
+
}
|
|
9
|
+
export interface WalletChange {
|
|
10
|
+
readonly kind: 'accountsChanged' | 'chainChanged' | 'disconnect';
|
|
11
|
+
}
|
|
12
|
+
export interface SourceWalletProvider {
|
|
13
|
+
readonly id: string;
|
|
14
|
+
readonly name: string;
|
|
15
|
+
/** True when this wallet can be used in the current environment (extension present, etc.). */
|
|
16
|
+
isAvailable(): boolean;
|
|
17
|
+
create(chainId: number): SourceSigner;
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bridge-in **source adapter** (08 Phase 4 — the three-boundary abstraction).
|
|
3
|
+
*
|
|
4
|
+
* The orchestrator (Sphere) is chain-neutral: it runs an ordered list of opaque
|
|
5
|
+
* {DepositStep}s, waits for receipts, guards account/network, persists recovery,
|
|
6
|
+
* and mints. Everything chain-specific — how many signatures a deposit takes,
|
|
7
|
+
* whether an ERC-20 `approve` is needed, how the commit (lock) event decodes, and
|
|
8
|
+
* how the mint justification is built — lives behind {BridgeSourceAdapter}.
|
|
9
|
+
*
|
|
10
|
+
* One adapter serves every family: the deposit is the same two calls on the
|
|
11
|
+
* same vault ABI, the lock event decodes the same way, and the signer the
|
|
12
|
+
* wallet hands in encodes the calls for its chain.
|
|
13
|
+
*/
|
|
14
|
+
import type { BridgeSourceAdapter } from '@unicitylabs/bridge-core';
|
|
15
|
+
import type { ContractCall } from '../contract-call.js';
|
|
16
|
+
import type { CreateBridgePluginDeps } from '../index.js';
|
|
17
|
+
import type { ConstantCaller } from '../source-chain.js';
|
|
18
|
+
import { type LoadedBridge } from './manifest.js';
|
|
19
|
+
export type { BridgeSourceAdapter, CommitInfo, DepositParams, DepositRecovery, DepositStep, MintRequest, MintRequestArgs, PreparedDeposit, } from '@unicitylabs/bridge-core';
|
|
20
|
+
/** The wallet capability a deposit step needs. */
|
|
21
|
+
export interface DepositWallet {
|
|
22
|
+
getAddress(): Promise<string>;
|
|
23
|
+
sendCall(call: ContractCall): Promise<string>;
|
|
24
|
+
}
|
|
25
|
+
/** The node read the adapter needs (allowance). */
|
|
26
|
+
export type AllowanceReader = ConstantCaller;
|
|
27
|
+
/**
|
|
28
|
+
* Build the {BridgeSourceAdapter} for a loaded bridge. Closes over the wallet
|
|
29
|
+
* (for the deposit steps) and a node client (for the allowance read); the mint
|
|
30
|
+
* verifier override is built with `deps`; by default it reads the wallet's value
|
|
31
|
+
* payload, which is the production bridge token value format.
|
|
32
|
+
*/
|
|
33
|
+
export declare function createSourceAdapter(bridge: LoadedBridge, wallet: DepositWallet, rpc: AllowanceReader, deps?: CreateBridgePluginDeps): BridgeSourceAdapter;
|