@agoric/fast-usdc 0.2.0-u19.2 → 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.
@@ -1,7 +1,6 @@
1
1
  import { AmountShape, BrandShape, RatioShape } from '@agoric/ertp';
2
2
  import { M } from '@endo/patterns';
3
3
  import {
4
- CosmosChainInfoShape,
5
4
  DenomDetailShape,
6
5
  DenomShape,
7
6
  } from '@agoric/orchestration/src/typeGuards.js';
@@ -10,13 +9,13 @@ import { PendingTxStatus } from './constants.js';
10
9
  /**
11
10
  * @import {Amount, Brand, NatValue, Payment} from '@agoric/ertp';
12
11
  * @import {TypedPattern} from '@agoric/internal';
13
- * @import {FastUsdcTerms} from './fast-usdc.contract.js';
12
+ * @import {CosmosChainInfo, Denom, DenomDetail, OrchestrationAccount, IBCConnectionInfo, CaipChainId} from '@agoric/orchestration';
14
13
  * @import {USDCProposalShapes} from './pool-share-math.js';
15
- * @import {CctpTxEvidence, FastUSDCConfig, FeeConfig, PendingTx, PoolMetrics, ChainPolicy, FeedPolicy, AddressHook, EvmAddress, EvmHash, RiskAssessment, EvidenceWithRisk} from './types.js';
14
+ * @import {CctpTxEvidence, FastUSDCConfig, FastUsdcTerms, FeeConfig, PendingTx, PoolMetrics, ChainPolicy, FeedPolicy, AddressHook, EvmAddress, EvmHash, RiskAssessment, EvidenceWithRisk} from './types.js';
16
15
  */
17
16
 
18
17
  /**
19
- * @param {Brand} brand must be a 'nat' brand, not checked
18
+ * @param {Brand<'nat'>} brand must be a 'nat' brand, not checked
20
19
  * @param {NatValue} [min]
21
20
  */
22
21
  export const makeNatAmountShape = (brand, min) =>
@@ -110,13 +109,34 @@ export const AddressHookShape = {
110
109
  harden(AddressHookShape);
111
110
 
112
111
  const NatAmountShape = { brand: BrandShape, value: M.nat() };
112
+
113
+ /** @type {TypedPattern<FeeConfig['destinationOverrides']>} */
114
+ export const DestinationOverridesShape = M.recordOf(
115
+ M.string(),
116
+ M.splitRecord(
117
+ {},
118
+ {
119
+ flat: NatAmountShape,
120
+ variableRate: RatioShape,
121
+ contractRate: RatioShape,
122
+ relay: NatAmountShape,
123
+ },
124
+ ),
125
+ );
126
+
113
127
  /** @type {TypedPattern<FeeConfig>} */
114
- export const FeeConfigShape = {
115
- flat: NatAmountShape,
116
- variableRate: RatioShape,
117
- contractRate: RatioShape,
118
- };
119
- harden(FeeConfigShape);
128
+ export const FeeConfigShape = M.splitRecord(
129
+ {
130
+ flat: NatAmountShape,
131
+ variableRate: RatioShape,
132
+ contractRate: RatioShape,
133
+ },
134
+ {
135
+ relay: NatAmountShape,
136
+ destinationOverrides: DestinationOverridesShape,
137
+ },
138
+ {},
139
+ );
120
140
 
121
141
  /** @type {TypedPattern<PoolMetrics>} */
122
142
  export const PoolMetricsShape = {
@@ -150,8 +170,7 @@ harden(ChainPolicyShape);
150
170
  /**
151
171
  * @type {TypedPattern<FeedPolicy>}
152
172
  *
153
- * Should be JSON serializable so CLI can specify policy. E.g. no bigint,
154
- * undefined, remotable, etc.
173
+ * must be CopyData; no Brands or other Remotables
155
174
  */
156
175
  export const FeedPolicyShape = M.splitRecord(
157
176
  {
@@ -163,12 +182,30 @@ export const FeedPolicyShape = M.splitRecord(
163
182
  );
164
183
  harden(FeedPolicyShape);
165
184
 
185
+ /**
186
+ * The version of CosmosChainInfoShape that matches the `valueShape` used in FUSDC's ChainHub's `chainInfos` mapStore.
187
+ * @type {TypedPattern<CosmosChainInfo>}
188
+ */
189
+ export const CosmosChainInfoShapeV1 = M.splitRecord(
190
+ {
191
+ chainId: M.string(),
192
+ },
193
+ {
194
+ bech32Prefix: M.string(),
195
+ connections: M.record(),
196
+ stakingTokens: M.arrayOf({ denom: M.string() }),
197
+ // UNTIL https://github.com/Agoric/agoric-sdk/issues/9326
198
+ icqEnabled: M.boolean(),
199
+ pfmEnabled: M.boolean(),
200
+ },
201
+ );
202
+
166
203
  /** @type {TypedPattern<FastUSDCConfig>} */
167
204
  export const FastUSDCConfigShape = M.splitRecord({
168
205
  terms: FastUSDCTermsShape,
169
206
  oracles: M.recordOf(M.string(), M.string()),
170
207
  feeConfig: FeeConfigShape,
171
208
  feedPolicy: FeedPolicyShape,
172
- chainInfo: M.recordOf(M.string(), CosmosChainInfoShape),
209
+ chainInfo: M.recordOf(M.string(), CosmosChainInfoShapeV1),
173
210
  assetInfo: M.arrayOf([DenomShape, DenomDetailShape]),
174
211
  });
package/src/types.ts CHANGED
@@ -1,17 +1,35 @@
1
+ import type { Amount } from '@agoric/ertp';
1
2
  import type {
2
- ChainAddress,
3
+ AccountId,
4
+ BaseChainInfo,
5
+ Bech32Address,
6
+ CaipChainId,
7
+ CosmosChainAddress,
3
8
  CosmosChainInfo,
4
9
  Denom,
5
10
  DenomDetail,
11
+ KnownNamespace,
6
12
  } from '@agoric/orchestration';
7
13
  import type { IBCChannelID } from '@agoric/vats';
8
- import type { Amount } from '@agoric/ertp';
9
- import type { CopyRecord, Passable } from '@endo/pass-style';
14
+ import type { CopyRecord } from '@endo/pass-style';
10
15
  import type { PendingTxStatus, TxStatus } from './constants.js';
11
- import type { FastUsdcTerms } from './fast-usdc.contract.js';
12
- import type { RepayAmountKWR } from './exos/liquidity-pool.js';
16
+ import type { RepayAmountKWR } from './utils/fees.js';
13
17
 
18
+ // XXX duped with Zoe contractSupport ambient types
19
+ type Ratio = {
20
+ numerator: Amount<'nat'>;
21
+ denominator: Amount<'nat'>;
22
+ };
23
+
24
+ /**
25
+ * Block hash is calculated using the keccak256 algorithm that always results
26
+ * in 32 bytes (64 hex characters prepended by 0x) no matter the input length.
27
+ */
14
28
  export type EvmHash = `0x${string}`;
29
+ /**
30
+ * An address is always the last 20 bytes (40 hex charaters prepended by 0x) of
31
+ * the public key hash.
32
+ */
15
33
  export type EvmAddress = `0x${string & { length: 40 }}`;
16
34
  export type NobleAddress = `noble1${string}`;
17
35
  export type EvmChainID = number;
@@ -25,7 +43,7 @@ export interface CctpTxEvidence {
25
43
  /** from Noble RPC */
26
44
  aux: {
27
45
  forwardingChannel: IBCChannelID;
28
- recipientAddress: ChainAddress['value'];
46
+ recipientAddress: CosmosChainAddress['value'] | AccountId;
29
47
  };
30
48
  /** on the source chain (e.g. L1 Ethereum and L2s Arbitrum, Base) */
31
49
  blockHash: EvmHash;
@@ -52,7 +70,7 @@ export interface CctpTxEvidence {
52
70
  txHash: EvmHash;
53
71
  }
54
72
 
55
- export interface EvidenceWithRisk {
73
+ export interface EvidenceWithRisk extends CopyRecord {
56
74
  evidence: CctpTxEvidence;
57
75
  risk: RiskAssessment;
58
76
  }
@@ -70,8 +88,9 @@ export interface TransactionRecord extends CopyRecord {
70
88
 
71
89
  /** the record in vstorage at the path of the contract's node */
72
90
  export interface ContractRecord extends CopyRecord {
73
- poolAccount: ChainAddress['value'];
74
- settlementAccount: ChainAddress['value'];
91
+ nobleICA?: CosmosChainAddress['value'];
92
+ poolAccount: CosmosChainAddress['value'];
93
+ settlementAccount: CosmosChainAddress['value'];
75
94
  }
76
95
 
77
96
  export type LogFn = (...args: unknown[]) => void;
@@ -81,12 +100,22 @@ export interface PendingTx extends CctpTxEvidence {
81
100
  }
82
101
 
83
102
  export type FeeConfig = {
84
- /** flat fee charged for every advance */
103
+ /** flat fee charged for every advance, eligible for LP disbursement */
85
104
  flat: Amount<'nat'>;
86
- /** proportion of advance kept as a fee */
105
+ /** proportion of advance kept as a fee, eligible for LP disbursement */
87
106
  variableRate: Ratio;
88
- /** proportion of fees that goes to the contract (remaining goes to LPs) */
107
+ /** proportion of `flat` and `variableRate` fees that goes to the contract (remaining goes to LPs) */
89
108
  contractRate: Ratio;
109
+ /**
110
+ * if present, a fee required to relay (e.g. CCTP to EVM/Solana). Not
111
+ * considered for LP disbursement - goes to `contractSeat`.
112
+ */
113
+ relay?: Amount<'nat'>;
114
+ /** Optional destination-specific overrides. If present, must supersede base values. */
115
+ destinationOverrides?: Record<
116
+ CaipChainId,
117
+ Partial<Omit<FeeConfig, 'destinationOverrides'>>
118
+ >;
90
119
  };
91
120
 
92
121
  export interface PoolStats {
@@ -127,13 +156,17 @@ export type FeedPolicy = {
127
156
  eventFilter?: string;
128
157
  } & CopyRecord;
129
158
 
159
+ export type FastUsdcTerms = {
160
+ usdcDenom: Denom;
161
+ };
162
+
130
163
  export type FastUSDCConfig = {
131
164
  terms: FastUsdcTerms;
132
165
  oracles: Record<string, string>;
133
166
  feeConfig: FeeConfig;
134
167
  feedPolicy: FeedPolicy;
135
168
  noNoble: boolean; // support a3p-integration, which has no noble chain
136
- chainInfo: Record<string, CosmosChainInfo & Passable>;
169
+ chainInfo: Record<string, ChainHubChainInfo>;
137
170
  assetInfo: [Denom, DenomDetail & { brandKey?: string }][];
138
171
  } & CopyRecord;
139
172
 
@@ -142,9 +175,22 @@ export type AddressHook = {
142
175
  baseAddress: string;
143
176
  query: {
144
177
  /** end user destination address */
145
- EUD: string;
178
+ EUD: Bech32Address;
146
179
  };
147
180
  };
148
181
 
182
+ /**
183
+ * The shape of ChainInfo ChainHub is expecting for FUSDC.
184
+ *
185
+ * Note: this diverges from `CosmosChainInfo` and `BaseChainInfo` in that:
186
+ * - BaseChainInfo includes chainId for backwards compatibility with `CosmosChainInfoShapeV1`
187
+ */
188
+ export type ChainHubChainInfo<N extends KnownNamespace = KnownNamespace> =
189
+ N extends 'cosmos' ? CosmosChainInfo : BaseChainInfoWithChainId<N>;
190
+
191
+ interface BaseChainInfoWithChainId<N extends KnownNamespace = KnownNamespace>
192
+ extends BaseChainInfo<N> {
193
+ chainId: string;
194
+ }
195
+
149
196
  export type * from './constants.js';
150
- export type { LiquidityPoolKit } from './exos/liquidity-pool.js';
package/src/utils/fees.js CHANGED
@@ -1,56 +1,142 @@
1
1
  import { AmountMath } from '@agoric/ertp';
2
- import { multiplyBy } from '@agoric/zoe/src/contractSupport/ratio.js';
2
+ import { multiplyBy } from '@agoric/ertp/src/ratio.js';
3
3
  import { Fail } from '@endo/errors';
4
4
  import { mustMatch } from '@endo/patterns';
5
+ import { chainOfAccount } from '@agoric/orchestration/src/utils/address.js';
5
6
  import { FeeConfigShape } from '../type-guards.js';
6
7
 
7
- const { add, isGTE, subtract } = AmountMath;
8
+ const { add, isGTE, subtract, makeEmpty } = AmountMath;
8
9
 
9
10
  /**
10
11
  * @import {Amount} from '@agoric/ertp';
12
+ * @import {AccountId} from '@agoric/orchestration';
11
13
  * @import {FeeConfig} from '../types.js';
12
- * @import {RepayAmountKWR} from '../exos/liquidity-pool.js';
13
14
  */
14
15
 
15
- /** @param {FeeConfig} feeConfig */
16
+ /**
17
+ * @typedef {{
18
+ * Principal: Amount<'nat'>;
19
+ * PoolFee: Amount<'nat'>;
20
+ * ContractFee: Amount<'nat'>;
21
+ * RelayFee: Amount<'nat'>;
22
+ * }} RepayAmountKWR
23
+ */
24
+
25
+ /**
26
+ * @typedef {{
27
+ * Principal: Payment<'nat'>;
28
+ * PoolFee: Payment<'nat'>;
29
+ * ContractFee: Payment<'nat'>;
30
+ * RelayFee: Payment<'nat'>;
31
+ * }} RepayPaymentKWR
32
+ */
33
+
34
+ /**
35
+ * @template {keyof Omit<FeeConfig, 'destinationOverrides'>} K
36
+ * @param {FeeConfig} feeConfig
37
+ * @param {K} key
38
+ * @param {AccountId} destination
39
+ * @returns {FeeConfig[K]}
40
+ */
41
+ const getConfigValue = (feeConfig, key, destination) => {
42
+ const chainId = chainOfAccount(destination);
43
+ if (
44
+ feeConfig.destinationOverrides?.[chainId] &&
45
+ feeConfig.destinationOverrides[chainId][key] !== undefined
46
+ ) {
47
+ return feeConfig.destinationOverrides[chainId][key];
48
+ }
49
+ return feeConfig[key];
50
+ };
51
+
52
+ /**
53
+ * @param {FeeConfig} feeConfig
54
+ */
16
55
  export const makeFeeTools = feeConfig => {
17
56
  mustMatch(feeConfig, FeeConfigShape, 'Must provide feeConfig');
18
- const { flat, variableRate } = feeConfig;
57
+ const emptyAmount = makeEmpty(feeConfig.flat.brand);
58
+
19
59
  const feeTools = harden({
20
60
  /**
21
- * Calculate the net amount to advance after withholding fees.
61
+ * Calculate the base fee to charge for the advance (variable + flat).
62
+ * Will be shared between the pool and the contract based on
63
+ * {@link FeeConfig.contractRate}.
22
64
  *
23
65
  * @param {Amount<'nat'>} requested
24
- * @throws {Error} if requested does not exceed fees
66
+ * @param {AccountId} destination
67
+ * @returns {Amount<'nat'>}
25
68
  */
26
- calculateAdvance(requested) {
27
- const fee = feeTools.calculateAdvanceFee(requested);
28
- return subtract(requested, fee);
69
+ calculateBaseFee(requested, destination) {
70
+ const flat = getConfigValue(feeConfig, 'flat', destination);
71
+ const variableRate = getConfigValue(
72
+ feeConfig,
73
+ 'variableRate',
74
+ destination,
75
+ );
76
+ return add(multiplyBy(requested, variableRate), flat);
77
+ },
78
+ /**
79
+ * Calculate the optional relay fee charged for certain destinations.
80
+ * Only disbursed to contract seat.
81
+ *
82
+ * @param {AccountId} destination
83
+ * @returns {Amount<'nat'>}
84
+ */
85
+ calculateRelayFee(destination) {
86
+ const relay = getConfigValue(feeConfig, 'relay', destination);
87
+ return relay || emptyAmount;
29
88
  },
30
89
  /**
31
90
  * Calculate the total fee to charge for the advance.
32
91
  *
33
92
  * @param {Amount<'nat'>} requested
93
+ * @param {AccountId} destination
34
94
  * @throws {Error} if requested does not exceed fees
35
95
  */
36
- calculateAdvanceFee(requested) {
37
- const fee = add(multiplyBy(requested, variableRate), flat);
96
+ calculateAdvanceFee(requested, destination) {
97
+ const baseFee = feeTools.calculateBaseFee(requested, destination);
98
+ const relayFee = feeTools.calculateRelayFee(destination);
99
+ const fee = add(baseFee, relayFee);
38
100
  !isGTE(fee, requested) || Fail`Request must exceed fees.`;
39
101
  return fee;
40
102
  },
103
+ /**
104
+ * Calculate the net amount to advance after withholding fees.
105
+ *
106
+ * @param {Amount<'nat'>} requested
107
+ * @param {AccountId} destination
108
+ * @throws {Error} if requested does not exceed fees
109
+ */
110
+ calculateAdvance(requested, destination) {
111
+ const fee = feeTools.calculateAdvanceFee(requested, destination);
112
+ return subtract(requested, fee);
113
+ },
41
114
  /**
42
115
  * Calculate the split of fees between pool and contract.
43
116
  *
117
+ * The `ContractFee` includes base fees plus the relay fee.
118
+ *
44
119
  * @param {Amount<'nat'>} requested
120
+ * @param {AccountId} destination
45
121
  * @returns {RepayAmountKWR} an {@link AmountKeywordRecord}
46
122
  * @throws {Error} if requested does not exceed fees
47
123
  */
48
- calculateSplit(requested) {
49
- const fee = feeTools.calculateAdvanceFee(requested);
50
- const Principal = subtract(requested, fee);
51
- const ContractFee = multiplyBy(fee, feeConfig.contractRate);
52
- const PoolFee = subtract(fee, ContractFee);
53
- return harden({ Principal, PoolFee, ContractFee });
124
+ calculateSplit(requested, destination) {
125
+ const baseFee = feeTools.calculateBaseFee(requested, destination);
126
+ const relayFee = feeTools.calculateRelayFee(destination);
127
+ const totalFee = add(baseFee, relayFee);
128
+ !isGTE(totalFee, requested) || Fail`Request must exceed fees.`;
129
+
130
+ const contractRate = getConfigValue(
131
+ feeConfig,
132
+ 'contractRate',
133
+ destination,
134
+ );
135
+ const Principal = subtract(requested, totalFee);
136
+ const ContractFee = multiplyBy(baseFee, contractRate);
137
+ const PoolFee = subtract(baseFee, ContractFee);
138
+
139
+ return harden({ Principal, PoolFee, ContractFee, RelayFee: relayFee });
54
140
  },
55
141
  });
56
142
  return feeTools;
@@ -0,0 +1,205 @@
1
+ import { encodeAddressHook } from '@agoric/cosmic-proto/address-hooks.js';
2
+ import type { Bech32Address, CosmosChainAddress } from '@agoric/orchestration';
3
+ import type { CctpTxEvidence, EvmAddress } from '../src/types.js';
4
+
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';
14
+
15
+ export const Senders = {
16
+ default: '0xDefaultFakeEthereumAddress',
17
+ } as unknown as Record<string, EvmAddress>;
18
+
19
+ const blockTimestamp = 1632340000n;
20
+
21
+ export const MockCctpTxEvidences: Record<
22
+ MockScenario,
23
+ (receiverAddress?: Bech32Address) => CctpTxEvidence
24
+ > = {
25
+ AGORIC_PLUS_OSMO: (receiverAddress?: Bech32Address) => ({
26
+ blockHash:
27
+ '0x90d7343e04f8160892e94f02d6a9b9f255663ed0ac34caca98544c8143fee665',
28
+ blockNumber: 21037663n,
29
+ blockTimestamp,
30
+ txHash:
31
+ '0xc81bc6105b60a234c7c50ac17816ebcd5561d366df8bf3be59ff387552761702',
32
+ tx: {
33
+ amount: 150000000n,
34
+ forwardingAddress: 'noble1x0ydg69dh6fqvr27xjvp6maqmrldam6yfelqkd',
35
+ sender: Senders.default,
36
+ },
37
+ aux: {
38
+ forwardingChannel: 'channel-21',
39
+ recipientAddress:
40
+ receiverAddress ||
41
+ encodeAddressHook(settlementAddress.value, {
42
+ EUD: 'osmo183dejcnmkka5dzcu9xw6mywq0p2m5peks28men',
43
+ }),
44
+ },
45
+ chainId: 1,
46
+ }),
47
+ AGORIC_PLUS_DYDX: (receiverAddress?: Bech32Address) => ({
48
+ blockHash:
49
+ '0x80d7343e04f8160892e94f02d6a9b9f255663ed0ac34caca98544c8143fee699',
50
+ blockNumber: 21037669n,
51
+ blockTimestamp,
52
+ txHash:
53
+ '0xd81bc6105b60a234c7c50ac17816ebcd5561d366df8bf3be59ff387552761799',
54
+ tx: {
55
+ amount: 300000000n,
56
+ forwardingAddress: 'noble1x0ydg69dh6fqvr27xjvp6maqmrldam6yfelktz',
57
+ sender: Senders.default,
58
+ },
59
+ aux: {
60
+ forwardingChannel: 'channel-21',
61
+ recipientAddress:
62
+ receiverAddress ||
63
+ encodeAddressHook(settlementAddress.value, {
64
+ EUD: 'dydx183dejcnmkka5dzcu9xw6mywq0p2m5peks28men',
65
+ }),
66
+ },
67
+ chainId: 1,
68
+ }),
69
+ AGORIC_PLUS_AGORIC: (receiverAddress?: Bech32Address) => ({
70
+ blockHash:
71
+ '0x80d7343e04f8160892e94f02d6a9b9f255663ed0ac34caca98544c8143fee6z9',
72
+ blockNumber: 21037600n,
73
+ blockTimestamp,
74
+ txHash:
75
+ '0xd81bc6105b60a234c7c50ac17816ebcd5561d366df8bf3be59ff3875527617z9',
76
+ tx: {
77
+ amount: 250000000n,
78
+ forwardingAddress: 'noble17ww3rfusv895d92c0ncgj0fl9trntn70jz7hd5',
79
+ sender: Senders.default,
80
+ },
81
+ aux: {
82
+ forwardingChannel: 'channel-21',
83
+ recipientAddress:
84
+ receiverAddress ||
85
+ encodeAddressHook(settlementAddress.value, {
86
+ EUD: 'agoric13rj0cc0hm5ac2nt0sdup2l7gvkx4v9tyvgq3h2',
87
+ }),
88
+ },
89
+ chainId: 1,
90
+ }),
91
+ AGORIC_NO_PARAMS: (receiverAddress?: Bech32Address) => ({
92
+ blockHash:
93
+ '0x70d7343e04f8160892e94f02d6a9b9f255663ed0ac34caca98544c8143fee699',
94
+ blockNumber: 21037669n,
95
+ blockTimestamp,
96
+ txHash:
97
+ '0xa81bc6105b60a234c7c50ac17816ebcd5561d366df8bf3be59ff387552761799',
98
+ tx: {
99
+ amount: 200000000n,
100
+ forwardingAddress: 'noble1x0ydg69dh6fqvr27xjvp6maqmrldam6yfelyyy',
101
+ sender: Senders.default,
102
+ },
103
+ aux: {
104
+ forwardingChannel: 'channel-21',
105
+ recipientAddress: receiverAddress || settlementAddress.value,
106
+ },
107
+ chainId: 1,
108
+ }),
109
+ AGORIC_UNKNOWN_EUD: (receiverAddress?: Bech32Address) => ({
110
+ blockHash:
111
+ '0x70d7343e04f8160892e94f02d6a9b9f255663ed0ac34caca98544c8143fee699',
112
+ blockNumber: 21037669n,
113
+ blockTimestamp,
114
+ txHash:
115
+ '0xa81bc6105b60a234c7c50ac17816ebcd5561d366df8bf3be59ff387552761799',
116
+ tx: {
117
+ amount: 200000000n,
118
+ forwardingAddress: 'noble1x0ydg69dh6fqvr27xjvp6maqmrldam6yfelyyy',
119
+ sender: Senders.default,
120
+ },
121
+ aux: {
122
+ forwardingChannel: 'channel-21',
123
+ recipientAddress:
124
+ receiverAddress ||
125
+ encodeAddressHook(settlementAddress.value, {
126
+ EUD: 'random1addr',
127
+ }),
128
+ },
129
+ chainId: 1,
130
+ }),
131
+ AGORIC_PLUS_ETHEREUM: (receiverAddress?: Bech32Address) => ({
132
+ blockHash:
133
+ '0x80d7343e04f8160892e94f02d6a9b9f255663ed0ac34caca98544c8143fee6z9',
134
+ blockNumber: 21037600n,
135
+ blockTimestamp,
136
+ txHash:
137
+ '0xe81bc6105b60a234c7c50ac17816ebcd5561d366df8bf3be59ff3875527617z9',
138
+ tx: {
139
+ amount: 950000000n,
140
+ forwardingAddress: 'noble17ww3rfusv895d92c0ncgj0fl9trntn70jz7ee5',
141
+ sender: Senders.default,
142
+ },
143
+ aux: {
144
+ forwardingChannel: 'channel-21',
145
+ recipientAddress:
146
+ receiverAddress ||
147
+ encodeAddressHook(settlementAddress.value, {
148
+ EUD: 'eip155:1:0x1234567890123456789012345678901234567890',
149
+ }),
150
+ },
151
+ chainId: 8453,
152
+ }),
153
+ AGORIC_PLUS_NOBLE: (receiverAddress?: Bech32Address) => ({
154
+ blockHash:
155
+ '0x80d7343e04f8160892e94f02d6a9b9f255663ed0ac34caca98544c8143fee6z9',
156
+ blockNumber: 21037600n,
157
+ blockTimestamp,
158
+ txHash:
159
+ '0xe81bc6105b60a234c7c50ac17816ebcd5561d366df8bf3be59ff3875527617z9',
160
+ tx: {
161
+ amount: 950000000n,
162
+ forwardingAddress: 'noble17ww3rfusv895d92c0ncgj0fl9trntn70jz7ee5',
163
+ sender: Senders.default,
164
+ },
165
+ aux: {
166
+ forwardingChannel: 'channel-21',
167
+ recipientAddress:
168
+ receiverAddress ||
169
+ encodeAddressHook(settlementAddress.value, {
170
+ EUD: 'cosmos:noble-1:noble1u2l9za2wa7wvffhtekgyuvyvum06lwhqxfyr5d',
171
+ }),
172
+ },
173
+ chainId: 8453,
174
+ }),
175
+ /** Identical to AGORIC_PLUS_NOBLE, but the EUD is a bare bech32 */
176
+ AGORIC_PLUS_NOBLE_B32EUD: (receiverAddress?: Bech32Address) => ({
177
+ blockHash:
178
+ '0x80d7343e04f8160892e94f02d6a9b9f255663ed0ac34caca98544c8143fee6z9',
179
+ blockNumber: 21037600n,
180
+ blockTimestamp,
181
+ txHash:
182
+ '0xe81bc6105b60a234c7c50ac17816ebcd5561d366df8bf3be59ff3875527617z9',
183
+ tx: {
184
+ amount: 950000000n,
185
+ forwardingAddress: 'noble17ww3rfusv895d92c0ncgj0fl9trntn70jz7ee5',
186
+ sender: Senders.default,
187
+ },
188
+ aux: {
189
+ forwardingChannel: 'channel-21',
190
+ recipientAddress:
191
+ receiverAddress ||
192
+ encodeAddressHook(settlementAddress.value, {
193
+ EUD: 'noble1u2l9za2wa7wvffhtekgyuvyvum06lwhqxfyr5d',
194
+ }),
195
+ },
196
+ chainId: 8453,
197
+ }),
198
+ };
199
+
200
+ export const settlementAddress: CosmosChainAddress = harden({
201
+ chainId: 'agoric-3',
202
+ encoding: 'bech32' as const,
203
+ // Random value, copied from tests of address hooks
204
+ value: 'agoric16kv2g7snfc4q24vg3pjdlnnqgngtjpwtetd2h689nz09lcklvh5s8u37ek',
205
+ });
@@ -1,63 +0,0 @@
1
- import { makeTracer } from '@agoric/internal';
2
- import { inviteOracles } from './utils/core-eval.js';
3
-
4
- /**
5
- * @import {ManifestBundleRef} from '@agoric/deploy-script-support/src/externalTypes.js'
6
- * @import {BootstrapManifest} from '@agoric/vats/src/core/lib-boot.js'
7
- * @import {LegibleCapData} from './utils/config-marshal.js'
8
- * @import {FastUSDCConfig} from './types.js'
9
- * @import {FastUSDCCorePowers, FastUSDCKit} from './start-fast-usdc.core.js';
10
- */
11
-
12
- const trace = makeTracer('FUSD-AddOperators', true);
13
-
14
- /**
15
- * @throws if oracle smart wallets are not yet provisioned
16
- *
17
- * @param {BootstrapPowers & FastUSDCCorePowers } powers
18
- * @param {{ options: LegibleCapData<FastUSDCConfig> }} config
19
- */
20
- export const addOperators = async (
21
- { consume: { namesByAddress, fastUsdcKit } },
22
- config,
23
- ) => {
24
- trace(addOperators.name);
25
-
26
- const kit = await fastUsdcKit;
27
-
28
- const { creatorFacet } = kit;
29
-
30
- trace(config);
31
-
32
- // @ts-expect-error XXX LegibleCapData typedef
33
- const { oracles } = config.options.structure;
34
-
35
- await inviteOracles({ creatorFacet, namesByAddress }, oracles);
36
- };
37
- harden(addOperators);
38
-
39
- /**
40
- * @param {{
41
- * restoreRef: (b: ERef<ManifestBundleRef>) => Promise<Installation>;
42
- * }} utils
43
- * @param {{
44
- * options: LegibleCapData<FastUSDCConfig>;
45
- * }} param1
46
- */
47
- export const getManifestForAddOperators = ({ restoreRef: _ }, { options }) => {
48
- return {
49
- /** @type {BootstrapManifest} */
50
- manifest: {
51
- [addOperators.name]: {
52
- consume: {
53
- fastUsdcKit: true,
54
-
55
- // widely shared: name services
56
- agoricNames: true,
57
- namesByAddress: true,
58
- },
59
- },
60
- },
61
- options,
62
- };
63
- };