@agoric/fast-usdc 0.2.0-u20.0 → 0.2.0-u21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +158 -1
- package/package.json +16 -18
- package/src/cli/cli.js +1 -1
- package/src/cli/transfer.js +1 -3
- package/src/cli/util/agoric.js +4 -5
- package/src/constants.js +2 -2
- package/src/type-guards.js +1 -0
- package/src/types.ts +6 -6
- package/tools/mock-evidence.ts +9 -12
package/README.md
CHANGED
|
@@ -23,5 +23,162 @@ Over time we can update our tooling to decouple this more from the `packages` di
|
|
|
23
23
|
2. Export bootstrap testing utilities from `@aglocal/boot`, allowing this to be
|
|
24
24
|
above `@aglocal/boot` in the package graph
|
|
25
25
|
3. Update CI to support packages that aren't under `packages/`, eg. a top-level
|
|
26
|
-
`dapps` directory
|
|
26
|
+
`dapps` directory. `multichain-testing` does this now but not organized per contract.
|
|
27
27
|
4. Move this package out of agoric-sdk
|
|
28
|
+
|
|
29
|
+
# Funds flow
|
|
30
|
+
|
|
31
|
+
```mermaid
|
|
32
|
+
sequenceDiagram
|
|
33
|
+
actor User as User
|
|
34
|
+
participant NEA as User Wallet<br>[Browser]
|
|
35
|
+
participant ETH as CCTP Contract<br>[Ethereum]
|
|
36
|
+
participant NFA as Noble Forwarding Account<br/>[Noble]
|
|
37
|
+
participant NC as Noble Chain<br/>[Noble]
|
|
38
|
+
participant NAR as Noble-Agoric<br/>[IBC Relayer]
|
|
39
|
+
participant SA as Settlement Account<br/>[Agoric]
|
|
40
|
+
participant CFA as Contract Fee Account<br/>[Agoric]
|
|
41
|
+
participant DAR as Destination-Agoric<br/>[IBC Relayer]
|
|
42
|
+
participant EUD as End User Destination<br/>[Dest Chain]
|
|
43
|
+
|
|
44
|
+
autonumber
|
|
45
|
+
rect rgb(240, 248, 255)
|
|
46
|
+
User ->> NEA: Sign transaction<br/>(MintAmount, to NFA)
|
|
47
|
+
NEA ->> ETH: Submit USDC Burn Txn via CCTP
|
|
48
|
+
end
|
|
49
|
+
rect rgb(200, 255, 230)
|
|
50
|
+
FUC ->> P: Initiate PFM transfer(AdvanceAmount, EUD) from pool<br/>of Noble-Agoric tokens to EUD Chain
|
|
51
|
+
P ->> NC: PFM transfer(AdvanceAmount of Agoric USDC denom) to EUD
|
|
52
|
+
NC ->> EUD: deliver AdvanceAmount as final USDC denom
|
|
53
|
+
end
|
|
54
|
+
Note over User, EUD: User got their AdvanceAmountof IBC USDC<br/>UX COMPLETE
|
|
55
|
+
rect rgb(255, 200, 200)
|
|
56
|
+
Note over ETH, SA: Minting Process
|
|
57
|
+
Note over ETH: ~12 minutes for Ethereum finality
|
|
58
|
+
Note over NC: 1-6 minutes for CCTP<br/>to Mint on Noble
|
|
59
|
+
NC ->> NFA: Noble CCTP contract mints USDC<br/> into Noble Forwarding Address
|
|
60
|
+
NFA ->> NAR: Broadcast Forward MintAmount (as Agoric USDC Denom) to FU Account
|
|
61
|
+
NAR ->> SA: Relay
|
|
62
|
+
end
|
|
63
|
+
rect rgb(255, 245, 230)
|
|
64
|
+
Note over FUC, CFA: Settlement Process
|
|
65
|
+
alt Advance was started:
|
|
66
|
+
FUC ->> SA: Initiate transfers out of settlement
|
|
67
|
+
SA ->> P: Deposit the AdvanceAmount + PoolFee (= MintAmount - ContractFee)
|
|
68
|
+
SA ->> CFA: Deposit ContractFee
|
|
69
|
+
else Advance for matched transaction that has not yet started:
|
|
70
|
+
P ->> NC: PFM transfer(MintAmount of Agoric USDC denom) to EUD
|
|
71
|
+
NC ->> EUD: deliver MintAmount as final USDC denom
|
|
72
|
+
else Settlement for unknown transaction:
|
|
73
|
+
Note over SA: Leave funds in SettlementAccount.
|
|
74
|
+
Note over SA: Wait for observation from watcher
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Not pictured:
|
|
80
|
+
- Circle Attestation Service
|
|
81
|
+
- CCTP Relayer
|
|
82
|
+
|
|
83
|
+
"Noble Forwarding Account" is also owned by the CCTP Relayer as they actually register it
|
|
84
|
+
CCTP Relayer can be many parties, but only one when caller is specified
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
# Transaction flow
|
|
88
|
+
|
|
89
|
+
```mermaid
|
|
90
|
+
%%{init: {
|
|
91
|
+
'theme': 'base',
|
|
92
|
+
'themeVariables': {
|
|
93
|
+
'primaryColor': '#f0f8ff',
|
|
94
|
+
'primaryTextColor': '#2c3e50',
|
|
95
|
+
'primaryBorderColor': '#7fb2e6',
|
|
96
|
+
'lineColor': '#7fb2e6',
|
|
97
|
+
'secondaryColor': '#f6f8fa',
|
|
98
|
+
'tertiaryColor': '#fff5e6'
|
|
99
|
+
}
|
|
100
|
+
}}%%
|
|
101
|
+
sequenceDiagram
|
|
102
|
+
title Fast USDC Transaction Process
|
|
103
|
+
autonumber
|
|
104
|
+
actor User
|
|
105
|
+
%% [Where it runs]
|
|
106
|
+
participant NEA as Noble Express app<br/>[Browser]
|
|
107
|
+
participant ETH as CCTP Contract<br/>[Ethereum]
|
|
108
|
+
participant NFA as Noble Forwarding Account<br/>[Noble]
|
|
109
|
+
participant NC as Noble Chain<br/>[Noble]
|
|
110
|
+
participant NAR as Noble-Agoric<br/>[Relayer]
|
|
111
|
+
participant OCW as Eth Watcher<br/>[Off-chain]
|
|
112
|
+
participant FUC as Fast USDC Contract<br/>[Agoric]
|
|
113
|
+
participant P as Pool<br/>[Agoric]
|
|
114
|
+
participant SA as Settlement Account<br/>[Agoric]
|
|
115
|
+
participant CFA as Contract Fee Account<br/>[Agoric]
|
|
116
|
+
participant DAR as Destination-Agoric<br/>[Relayer]
|
|
117
|
+
participant EUD as End User Destination<br/>[User]
|
|
118
|
+
|
|
119
|
+
%% Notation: --> for async, ->> for sync
|
|
120
|
+
rect rgb(240, 248, 255)
|
|
121
|
+
Note over User,OCW: User request
|
|
122
|
+
Note over NEA: App looks up fees and SettlementAccount address
|
|
123
|
+
User->>NEA: Input desired MintAmount and EUD
|
|
124
|
+
NEA->>User: Display fees and AdvanceAmount
|
|
125
|
+
Note over NEA: Calculate VirtualRecipient from (SettlementAccount, EUD)
|
|
126
|
+
Note over NEA: Calculate NFA address from (VirtualRecipient) using Signerless forwarding
|
|
127
|
+
%% Getting from here to the burn is mostly up to Noble
|
|
128
|
+
User->>NEA: Initiate transfer
|
|
129
|
+
NEA-->>NC: Register NFA
|
|
130
|
+
NEA->>User: Request signature
|
|
131
|
+
User->>NEA: Sign transaction<br/>(MintAmount, to NFA)
|
|
132
|
+
NEA->>ETH: Submit USDC Burn Txn via CCTP
|
|
133
|
+
Note over ETH: Burn succeeds,<br/>implying mint to NFA will happen
|
|
134
|
+
OCW->>ETH: Query CCTP transactions to Noble
|
|
135
|
+
ETH-->>OCW: 1 block confirmed
|
|
136
|
+
OCW->>NC: Look up recipient of NFA<br/>by account query
|
|
137
|
+
NC->>OCW: RPC replies with account including `recipient` (LCA+EUD)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
Note over OCW: Continue if recipient is over the Noble-Agoric channel
|
|
141
|
+
rect rgb(200, 255, 230)
|
|
142
|
+
Note over NC,EUD: Advancement Process
|
|
143
|
+
Note over OCW: Log proof of each confirmation
|
|
144
|
+
Note over OCW,FUC: Provide info needed by policy to make a decision
|
|
145
|
+
OCW->>FUC: Notify of each confirmation<br/>(dest=agoric1 recipient, amount,<br/>metadata=transaction-nonce,chain,block,timestamp)
|
|
146
|
+
Note over FUC: MM's policy decides whether to advance (e.g. 2 confirmations from Ethereum, 5 from Polygon)
|
|
147
|
+
Note over FUC: Syslog with sufficient detail to debug
|
|
148
|
+
Note over FUC: calculate AdvanceAmount = (MintAmount – PoolFee - ContractFee)<br/>based on fee rates at this moment, and record for future lookup
|
|
149
|
+
FUC->>P: Initiate PFM transfer(AdvanceAmount, EUD) from pool<br/>of Noble-Agoric tokens to EUD Chain
|
|
150
|
+
P->>NC: PFM transfer(AdvanceAmount of Agoric USDC denom) to EUD
|
|
151
|
+
NC->>EUD: deliver AdvanceAmount as final USDC denom
|
|
152
|
+
%% TODO do need epsilon tolerance on MintAmount for if Noble takes a small cut of the minted amount
|
|
153
|
+
%% TODO map out the event handling for these states: START: only-observed,advance-started,received-minted-unobserved, END: done
|
|
154
|
+
Note over SA: Wake up the settlement process to handle observed (key=EUD,MintAmount)
|
|
155
|
+
|
|
156
|
+
end
|
|
157
|
+
Note over User,EUD: User got their AdvanceAmountof IBC USDC<br/>UX COMPLETE
|
|
158
|
+
|
|
159
|
+
rect rgb(255, 200, 200)
|
|
160
|
+
Note over ETH,SA: Minting Process
|
|
161
|
+
Note over ETH: ~12 minutes for Ethereum finality
|
|
162
|
+
Note over NC: 1-6 minutes for CCTP<br/>to Mint on Noble
|
|
163
|
+
NC->>NFA: Noble CCTP contract mints USDC<br/> into Noble Forwarding Address
|
|
164
|
+
NFA->>SA: Forward MintAmount (as Agoric USDC Denom) to FU Account
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
rect rgb(255, 245, 230)
|
|
168
|
+
Note over FUC,CFA: Settlement Process
|
|
169
|
+
Note over FUC,SA: Tap on account reads MintAmount,<br/>parses EUD from virtual address recipient<br/>and looks up AdvanceAmount,PoolFee,ContractFee.<br/>Matches against an unsettled transaction (by EUD and approx amount).
|
|
170
|
+
%% Treat starting the advance as an atomic action. Assume it will complete once started.
|
|
171
|
+
alt Advance was started:
|
|
172
|
+
FUC->>SA: Initiate transfers out of settlement
|
|
173
|
+
SA->>P: Deposit the AdvanceAmount + PoolFee (= MintAmount - ContractFee)
|
|
174
|
+
SA->>CFA: Deposit ContractFee
|
|
175
|
+
else Advance for matched transaction that has not yet started:
|
|
176
|
+
P->>NC: PFM transfer(MintAmount of Agoric USDC denom) to EUD
|
|
177
|
+
NC->>EUD: deliver MintAmount as final USDC denom
|
|
178
|
+
else Settlement for unknown transaction:
|
|
179
|
+
%% Have not received notification of this Amount,EUD from the watcher
|
|
180
|
+
Note over SA: Leave funds in SettlementAccount.
|
|
181
|
+
Note over SA: Wait for observation from watcher
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agoric/fast-usdc",
|
|
3
|
-
"version": "0.2.0-
|
|
3
|
+
"version": "0.2.0-u21.0",
|
|
4
4
|
"description": "CLI and library for Fast USDC product",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -8,34 +8,32 @@
|
|
|
8
8
|
"tools"
|
|
9
9
|
],
|
|
10
10
|
"main": "src/main.js",
|
|
11
|
-
"bin":
|
|
12
|
-
"fast-usdc": "./src/cli/bin.js"
|
|
13
|
-
},
|
|
11
|
+
"bin": "./src/cli/bin.js",
|
|
14
12
|
"scripts": {
|
|
15
13
|
"build": "exit 0",
|
|
16
14
|
"test": "ava",
|
|
17
15
|
"test:c8": "c8 --all $C8_OPTIONS ava",
|
|
18
16
|
"test:xs": "exit 0",
|
|
19
17
|
"lint-fix": "yarn lint:eslint --fix",
|
|
20
|
-
"lint": "run-s --continue-on-error lint:*",
|
|
21
|
-
"lint:
|
|
22
|
-
"lint:
|
|
18
|
+
"lint": "yarn run -T run-s --continue-on-error 'lint:*'",
|
|
19
|
+
"lint:eslint": "yarn run -T eslint .",
|
|
20
|
+
"lint:types": "yarn run -T tsc"
|
|
23
21
|
},
|
|
24
22
|
"devDependencies": {
|
|
25
23
|
"@fast-check/ava": "^2.0.1",
|
|
26
24
|
"ava": "^5.3.0",
|
|
27
|
-
"c8": "^10.1.
|
|
28
|
-
"nano-spawn": "^0.2
|
|
29
|
-
"ts-blank-space": "^0.
|
|
25
|
+
"c8": "^10.1.3",
|
|
26
|
+
"nano-spawn": "^1.0.2",
|
|
27
|
+
"ts-blank-space": "^0.6.1"
|
|
30
28
|
},
|
|
31
29
|
"dependencies": {
|
|
32
|
-
"@agoric/client-utils": "
|
|
33
|
-
"@agoric/cosmic-proto": "
|
|
34
|
-
"@agoric/ertp": "
|
|
35
|
-
"@agoric/internal": "
|
|
36
|
-
"@agoric/notifier": "
|
|
37
|
-
"@agoric/orchestration": "
|
|
38
|
-
"@agoric/zoe": "
|
|
30
|
+
"@agoric/client-utils": "workspace:*",
|
|
31
|
+
"@agoric/cosmic-proto": "workspace:*",
|
|
32
|
+
"@agoric/ertp": "workspace:*",
|
|
33
|
+
"@agoric/internal": "workspace:*",
|
|
34
|
+
"@agoric/notifier": "workspace:*",
|
|
35
|
+
"@agoric/orchestration": "workspace:*",
|
|
36
|
+
"@agoric/zoe": "workspace:*",
|
|
39
37
|
"@cosmjs/proto-signing": "^0.33.0",
|
|
40
38
|
"@cosmjs/stargate": "^0.33.0",
|
|
41
39
|
"@endo/base64": "^1.0.9",
|
|
@@ -75,5 +73,5 @@
|
|
|
75
73
|
"publishConfig": {
|
|
76
74
|
"access": "public"
|
|
77
75
|
},
|
|
78
|
-
"gitHead": "
|
|
76
|
+
"gitHead": "e4dd46857133403d584bcf822a81817b355532f9"
|
|
79
77
|
}
|
package/src/cli/cli.js
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
import { addConfigCommands } from './config-commands.js';
|
|
13
13
|
import { addOperatorCommands } from './operator-commands.js';
|
|
14
14
|
import * as configLib from './config.js';
|
|
15
|
-
import transferLib from './transfer.js';
|
|
15
|
+
import * as transferLib from './transfer.js';
|
|
16
16
|
import { makeFile } from './util/file.js';
|
|
17
17
|
import { addLPCommands } from './lp-commands.js';
|
|
18
18
|
|
package/src/cli/transfer.js
CHANGED
|
@@ -21,7 +21,7 @@ import { queryUSDCBalance } from './util/bank.js';
|
|
|
21
21
|
/** @import { SigningStargateClient } from '@cosmjs/stargate' */
|
|
22
22
|
/** @import { JsonRpcProvider as ethProvider } from 'ethers' */
|
|
23
23
|
|
|
24
|
-
const transfer = async (
|
|
24
|
+
export const transfer = async (
|
|
25
25
|
/** @type {File} */ configFile,
|
|
26
26
|
/** @type {string} */ amount,
|
|
27
27
|
/** @type {string} */ EUD,
|
|
@@ -137,5 +137,3 @@ const transfer = async (
|
|
|
137
137
|
}
|
|
138
138
|
await execute(config);
|
|
139
139
|
};
|
|
140
|
-
|
|
141
|
-
export default { transfer };
|
package/src/cli/util/agoric.js
CHANGED
|
@@ -4,9 +4,8 @@ export const queryFastUSDCLocalChainAccount = async (
|
|
|
4
4
|
/** @type {VStorage} */ vstorage,
|
|
5
5
|
out = console,
|
|
6
6
|
) => {
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
);
|
|
10
|
-
|
|
11
|
-
return agoricAddr;
|
|
7
|
+
const { value } = await vstorage.readLatest('published.fastUsdc');
|
|
8
|
+
const { settlementAccount } = JSON.parse(JSON.parse(value).values[0]);
|
|
9
|
+
out.log(`settlementAccount: ${settlementAccount}`);
|
|
10
|
+
return settlementAccount;
|
|
12
11
|
};
|
package/src/constants.js
CHANGED
|
@@ -16,6 +16,8 @@ export const TxStatus = /** @type {const} */ ({
|
|
|
16
16
|
AdvanceSkipped: 'ADVANCE_SKIPPED',
|
|
17
17
|
/** settlement for matching advance received and funds disbursed */
|
|
18
18
|
Disbursed: 'DISBURSED',
|
|
19
|
+
/** No route, forward not attempted */
|
|
20
|
+
ForwardedSkipped: 'FORWARD_SKIPPED',
|
|
19
21
|
/** fallback: do not collect fees */
|
|
20
22
|
Forwarded: 'FORWARDED',
|
|
21
23
|
/** failed to forward to EUD */
|
|
@@ -36,8 +38,6 @@ export const TerminalTxStatus = {
|
|
|
36
38
|
* @enum {(typeof PendingTxStatus)[keyof typeof PendingTxStatus]}
|
|
37
39
|
*/
|
|
38
40
|
export const PendingTxStatus = /** @type {const} */ ({
|
|
39
|
-
/** tx was observed but not advanced */
|
|
40
|
-
Observed: 'OBSERVED',
|
|
41
41
|
/** IBC transfer is initiated */
|
|
42
42
|
Advancing: 'ADVANCING',
|
|
43
43
|
/** IBC transfer failed (timed out) */
|
package/src/type-guards.js
CHANGED
|
@@ -110,6 +110,7 @@ harden(AddressHookShape);
|
|
|
110
110
|
|
|
111
111
|
const NatAmountShape = { brand: BrandShape, value: M.nat() };
|
|
112
112
|
|
|
113
|
+
/** @type {TypedPattern<FeeConfig['destinationOverrides']>} */
|
|
113
114
|
export const DestinationOverridesShape = M.recordOf(
|
|
114
115
|
M.string(),
|
|
115
116
|
M.splitRecord(
|
package/src/types.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
+
import type { Amount } from '@agoric/ertp';
|
|
1
2
|
import type {
|
|
2
3
|
AccountId,
|
|
3
|
-
|
|
4
|
+
BaseChainInfo,
|
|
4
5
|
Bech32Address,
|
|
6
|
+
CaipChainId,
|
|
7
|
+
CosmosChainAddress,
|
|
5
8
|
CosmosChainInfo,
|
|
6
9
|
Denom,
|
|
7
10
|
DenomDetail,
|
|
8
|
-
BaseChainInfo,
|
|
9
11
|
KnownNamespace,
|
|
10
|
-
CaipChainId,
|
|
11
12
|
} from '@agoric/orchestration';
|
|
12
13
|
import type { IBCChannelID } from '@agoric/vats';
|
|
13
|
-
import type {
|
|
14
|
-
import type { CopyRecord, Passable } from '@endo/pass-style';
|
|
14
|
+
import type { CopyRecord } from '@endo/pass-style';
|
|
15
15
|
import type { PendingTxStatus, TxStatus } from './constants.js';
|
|
16
16
|
import type { RepayAmountKWR } from './utils/fees.js';
|
|
17
17
|
|
|
@@ -70,7 +70,7 @@ export interface CctpTxEvidence {
|
|
|
70
70
|
txHash: EvmHash;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
export interface EvidenceWithRisk {
|
|
73
|
+
export interface EvidenceWithRisk extends CopyRecord {
|
|
74
74
|
evidence: CctpTxEvidence;
|
|
75
75
|
risk: RiskAssessment;
|
|
76
76
|
}
|
package/tools/mock-evidence.ts
CHANGED
|
@@ -2,18 +2,15 @@ import { encodeAddressHook } from '@agoric/cosmic-proto/address-hooks.js';
|
|
|
2
2
|
import type { Bech32Address, CosmosChainAddress } from '@agoric/orchestration';
|
|
3
3
|
import type { CctpTxEvidence, EvmAddress } from '../src/types.js';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
'AGORIC_PLUS_OSMO'
|
|
7
|
-
'AGORIC_PLUS_DYDX'
|
|
8
|
-
'AGORIC_PLUS_AGORIC'
|
|
9
|
-
'AGORIC_NO_PARAMS'
|
|
10
|
-
'AGORIC_UNKNOWN_EUD'
|
|
11
|
-
'AGORIC_PLUS_ETHEREUM'
|
|
12
|
-
'AGORIC_PLUS_NOBLE'
|
|
13
|
-
'AGORIC_PLUS_NOBLE_B32EUD'
|
|
14
|
-
] as const;
|
|
15
|
-
|
|
16
|
-
export type MockScenario = (typeof mockScenarios)[number];
|
|
5
|
+
export type MockScenario =
|
|
6
|
+
| 'AGORIC_PLUS_OSMO'
|
|
7
|
+
| 'AGORIC_PLUS_DYDX'
|
|
8
|
+
| 'AGORIC_PLUS_AGORIC'
|
|
9
|
+
| 'AGORIC_NO_PARAMS'
|
|
10
|
+
| 'AGORIC_UNKNOWN_EUD'
|
|
11
|
+
| 'AGORIC_PLUS_ETHEREUM'
|
|
12
|
+
| 'AGORIC_PLUS_NOBLE'
|
|
13
|
+
| 'AGORIC_PLUS_NOBLE_B32EUD';
|
|
17
14
|
|
|
18
15
|
export const Senders = {
|
|
19
16
|
default: '0xDefaultFakeEthereumAddress',
|