@agoric/fast-usdc 0.1.1-dev-ddff762.0 → 0.1.1-dev-c7a005e.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/fast-usdc",
3
- "version": "0.1.1-dev-ddff762.0+ddff762",
3
+ "version": "0.1.1-dev-c7a005e.0+c7a005e",
4
4
  "description": "CLI and library for Fast USDC product",
5
5
  "type": "module",
6
6
  "files": [
@@ -22,9 +22,9 @@
22
22
  "lint:eslint": "eslint ."
23
23
  },
24
24
  "devDependencies": {
25
- "@agoric/swingset-liveslots": "0.10.3-dev-ddff762.0+ddff762",
26
- "@agoric/vats": "0.15.2-dev-ddff762.0+ddff762",
27
- "@agoric/zone": "0.2.3-dev-ddff762.0+ddff762",
25
+ "@agoric/swingset-liveslots": "0.10.3-dev-c7a005e.0+c7a005e",
26
+ "@agoric/vats": "0.15.2-dev-c7a005e.0+c7a005e",
27
+ "@agoric/zone": "0.2.3-dev-c7a005e.0+c7a005e",
28
28
  "@fast-check/ava": "^2.0.1",
29
29
  "ava": "^5.3.0",
30
30
  "c8": "^10.1.2",
@@ -32,15 +32,16 @@
32
32
  "ts-blank-space": "^0.4.4"
33
33
  },
34
34
  "dependencies": {
35
- "@agoric/client-utils": "0.1.1-dev-ddff762.0+ddff762",
36
- "@agoric/ertp": "0.16.3-dev-ddff762.0+ddff762",
37
- "@agoric/internal": "0.3.3-dev-ddff762.0+ddff762",
38
- "@agoric/notifier": "0.6.3-dev-ddff762.0+ddff762",
39
- "@agoric/orchestration": "0.1.1-dev-ddff762.0+ddff762",
40
- "@agoric/store": "0.9.3-dev-ddff762.0+ddff762",
41
- "@agoric/vat-data": "0.5.3-dev-ddff762.0+ddff762",
42
- "@agoric/vow": "0.1.1-dev-ddff762.0+ddff762",
43
- "@agoric/zoe": "0.26.3-dev-ddff762.0+ddff762",
35
+ "@agoric/client-utils": "0.1.1-dev-c7a005e.0+c7a005e",
36
+ "@agoric/cosmic-proto": "0.4.1-dev-c7a005e.0+c7a005e",
37
+ "@agoric/ertp": "0.16.3-dev-c7a005e.0+c7a005e",
38
+ "@agoric/internal": "0.3.3-dev-c7a005e.0+c7a005e",
39
+ "@agoric/notifier": "0.6.3-dev-c7a005e.0+c7a005e",
40
+ "@agoric/orchestration": "0.1.1-dev-c7a005e.0+c7a005e",
41
+ "@agoric/store": "0.9.3-dev-c7a005e.0+c7a005e",
42
+ "@agoric/vat-data": "0.5.3-dev-c7a005e.0+c7a005e",
43
+ "@agoric/vow": "0.1.1-dev-c7a005e.0+c7a005e",
44
+ "@agoric/zoe": "0.26.3-dev-c7a005e.0+c7a005e",
44
45
  "@cosmjs/proto-signing": "^0.32.4",
45
46
  "@cosmjs/stargate": "^0.32.4",
46
47
  "@endo/base64": "^1.0.9",
@@ -80,5 +81,5 @@
80
81
  "publishConfig": {
81
82
  "access": "public"
82
83
  },
83
- "gitHead": "ddff762be0166b7973abca7bb202901afa494e53"
84
+ "gitHead": "c7a005e773fc75fa7ce97fbc2b95d9df82593556"
84
85
  }
@@ -6,6 +6,7 @@ import {
6
6
  makeVStorage,
7
7
  pickEndpoint,
8
8
  } from '@agoric/client-utils';
9
+ import { encodeAddressHook } from '@agoric/cosmic-proto/address-hooks.js';
9
10
  import { queryFastUSDCLocalChainAccount } from '../util/agoric.js';
10
11
  import { depositForBurn, makeProvider } from '../util/cctp.js';
11
12
  import {
@@ -22,7 +23,7 @@ import {
22
23
  const transfer = async (
23
24
  /** @type {File} */ configFile,
24
25
  /** @type {string} */ amount,
25
- /** @type {string} */ destination,
26
+ /** @type {string} */ EUD,
26
27
  out = console,
27
28
  fetch = globalThis.fetch,
28
29
  /** @type {VStorage | undefined} */ vstorage,
@@ -39,13 +40,13 @@ const transfer = async (
39
40
  { chainName: 'agoric', rpcAddrs: [pickEndpoint(netConfig)] },
40
41
  );
41
42
  const agoricAddr = await queryFastUSDCLocalChainAccount(vstorage, out);
42
- const appendedAddr = `${agoricAddr}?EUD=${destination}`;
43
- out.log(`forwarding destination ${appendedAddr}`);
43
+ const encodedAddr = encodeAddressHook(agoricAddr, { EUD });
44
+ out.log(`forwarding destination ${encodedAddr}`);
44
45
 
45
46
  const { exists, address } = await queryForwardingAccount(
46
47
  config.nobleApi,
47
48
  config.nobleToAgoricChannel,
48
- appendedAddr,
49
+ encodedAddr,
49
50
  out,
50
51
  fetch,
51
52
  );
@@ -58,13 +59,13 @@ const transfer = async (
58
59
  signer,
59
60
  signerAddress,
60
61
  config.nobleToAgoricChannel,
61
- appendedAddr,
62
+ encodedAddr,
62
63
  out,
63
64
  );
64
65
  out.log(res);
65
66
  } catch (e) {
66
67
  out.error(
67
- `Error registering noble forwarding account for ${appendedAddr} on channel ${config.nobleToAgoricChannel}`,
68
+ `Error registering noble forwarding account for ${encodedAddr} on channel ${config.nobleToAgoricChannel}`,
68
69
  );
69
70
  throw e;
70
71
  }
@@ -1,16 +1,16 @@
1
+ import { decodeAddressHook } from '@agoric/cosmic-proto/address-hooks.js';
1
2
  import { AmountMath } from '@agoric/ertp';
2
3
  import { assertAllDefined, makeTracer } from '@agoric/internal';
3
4
  import { AnyNatAmountShape, ChainAddressShape } from '@agoric/orchestration';
4
5
  import { pickFacet } from '@agoric/vat-data';
5
6
  import { VowShape } from '@agoric/vow';
6
7
  import { E } from '@endo/far';
7
- import { M } from '@endo/patterns';
8
+ import { M, mustMatch } from '@endo/patterns';
8
9
  import {
9
10
  CctpTxEvidenceShape,
10
- EudParamShape,
11
+ AddressHookShape,
11
12
  EvmHashShape,
12
13
  } from '../type-guards.js';
13
- import { addressTools } from '../utils/address.js';
14
14
  import { makeFeeTools } from '../utils/fees.js';
15
15
 
16
16
  /**
@@ -21,7 +21,7 @@ import { makeFeeTools } from '../utils/fees.js';
21
21
  * @import {ZoeTools} from '@agoric/orchestration/src/utils/zoe-tools.js';
22
22
  * @import {VowTools} from '@agoric/vow';
23
23
  * @import {Zone} from '@agoric/zone';
24
- * @import {CctpTxEvidence, EvmHash, FeeConfig, LogFn, NobleAddress} from '../types.js';
24
+ * @import {CctpTxEvidence, AddressHook, EvmHash, FeeConfig, LogFn, NobleAddress} from '../types.js';
25
25
  * @import {StatusManager} from './status-manager.js';
26
26
  * @import {LiquidityPoolKit} from './liquidity-pool.js';
27
27
  */
@@ -147,11 +147,9 @@ export const prepareAdvancerKit = (
147
147
 
148
148
  const { borrowerFacet, poolAccount } = this.state;
149
149
  const { recipientAddress } = evidence.aux;
150
- // throws if EUD is not found
151
- const { EUD } = addressTools.getQueryParams(
152
- recipientAddress,
153
- EudParamShape,
154
- );
150
+ const decoded = decodeAddressHook(recipientAddress);
151
+ mustMatch(decoded, AddressHookShape);
152
+ const { EUD } = /** @type {AddressHook['query']} */ (decoded.query);
155
153
  log(`decoded EUD: ${EUD}`);
156
154
  // throws if the bech32 prefix is not found
157
155
  const destination = chainHub.makeChainAddress(EUD);
@@ -5,8 +5,8 @@ import { atob } from '@endo/base64';
5
5
  import { E } from '@endo/far';
6
6
  import { M } from '@endo/patterns';
7
7
 
8
+ import { decodeAddressHook } from '@agoric/cosmic-proto/address-hooks.js';
8
9
  import { PendingTxStatus } from '../constants.js';
9
- import { addressTools } from '../utils/address.js';
10
10
  import { makeFeeTools } from '../utils/fees.js';
11
11
  import { EvmHashShape } from '../type-guards.js';
12
12
 
@@ -151,14 +151,19 @@ export const prepareSettler = (
151
151
  return;
152
152
  }
153
153
 
154
- if (!addressTools.hasQueryParams(tx.receiver)) {
155
- console.log('not query params', tx.receiver);
156
- return;
157
- }
158
-
159
- const { EUD } = addressTools.getQueryParams(tx.receiver);
160
- if (!EUD) {
161
- console.log('no EUD parameter', tx.receiver);
154
+ let EUD;
155
+ try {
156
+ ({ EUD } = decodeAddressHook(tx.receiver).query);
157
+ if (!EUD) {
158
+ log('no EUD parameter', tx.receiver);
159
+ return;
160
+ }
161
+ if (typeof EUD !== 'string') {
162
+ log('EUD is not a string', EUD);
163
+ return;
164
+ }
165
+ } catch (e) {
166
+ log('no query params', tx.receiver);
162
167
  return;
163
168
  }
164
169
 
@@ -6,7 +6,7 @@ import { PendingTxStatus } from './constants.js';
6
6
  * @import {TypedPattern} from '@agoric/internal';
7
7
  * @import {FastUsdcTerms} from './fast-usdc.contract.js';
8
8
  * @import {USDCProposalShapes} from './pool-share-math.js';
9
- * @import {CctpTxEvidence, FeeConfig, PendingTx, PoolMetrics, ChainPolicy, FeedPolicy} from './types.js';
9
+ * @import {CctpTxEvidence, FeeConfig, PendingTx, PoolMetrics, ChainPolicy, FeedPolicy, AddressHook} from './types.js';
10
10
  */
11
11
 
12
12
  /**
@@ -67,10 +67,12 @@ export const PendingTxShape = {
67
67
  };
68
68
  harden(PendingTxShape);
69
69
 
70
- export const EudParamShape = {
71
- EUD: M.string(),
70
+ /** @type {TypedPattern<AddressHook>} */
71
+ export const AddressHookShape = {
72
+ baseAddress: M.string(),
73
+ query: { EUD: M.string() },
72
74
  };
73
- harden(EudParamShape);
75
+ harden(AddressHookShape);
74
76
 
75
77
  const NatAmountShape = { brand: BrandShape, value: M.nat() };
76
78
  /** @type {TypedPattern<FeeConfig>} */
package/src/types.ts CHANGED
@@ -85,5 +85,14 @@ export type FastUSDCConfig = {
85
85
  assetInfo: [Denom, DenomDetail & { brandKey?: string }][];
86
86
  } & CopyRecord;
87
87
 
88
+ /** decoded address hook parameters */
89
+ export type AddressHook = {
90
+ baseAddress: string;
91
+ query: {
92
+ /** end user destination address */
93
+ EUD: string;
94
+ };
95
+ };
96
+
88
97
  export type * from './constants.js';
89
98
  export type { LiquidityPoolKit } from './exos/liquidity-pool.js';
@@ -1,71 +0,0 @@
1
- import { makeError, q } from '@endo/errors';
2
- import { M, mustMatch } from '@endo/patterns';
3
-
4
- /**
5
- * @import {Pattern} from '@endo/patterns';
6
- */
7
-
8
- /**
9
- * Default pattern matcher for `getQueryParams`.
10
- * Does not assert keys exist, but ensures existing keys are strings.
11
- */
12
- const QueryParamsShape = M.splitRecord(
13
- {},
14
- {},
15
- M.recordOf(M.string(), M.string()),
16
- );
17
-
18
- /**
19
- * Very minimal 'URL query string'-like parser that handles:
20
- * - Query string delimiter (?)
21
- * - Key-value separator (=)
22
- * - Query parameter separator (&)
23
- *
24
- * Does not handle:
25
- * - Subpaths (`agoric1bech32addr/opt/account?k=v`)
26
- * - URI encoding/decoding (`%20` -> ` `)
27
- * - note: `decodeURIComponent` seems to be available in XS
28
- * - Multiple question marks (foo?bar=1?baz=2)
29
- * - Empty parameters (foo=)
30
- * - Array parameters (`foo?k=v1&k=v2` -> k: [v1, v2])
31
- * - Parameters without values (foo&bar=2)
32
- */
33
- export const addressTools = {
34
- /**
35
- * @param {string} address
36
- * @returns {boolean}
37
- */
38
- hasQueryParams: address => {
39
- try {
40
- const params = addressTools.getQueryParams(address);
41
- return Object.keys(params).length > 0;
42
- } catch {
43
- return false;
44
- }
45
- },
46
- /**
47
- * @param {string} address
48
- * @param {Pattern} [shape]
49
- * @returns {Record<string, string>}
50
- * @throws {Error} if the address cannot be parsed or params do not match `shape`
51
- */
52
- getQueryParams: (address, shape = QueryParamsShape) => {
53
- const parts = address.split('?');
54
- if (parts.length !== 2) {
55
- throw makeError(`Unable to parse query params: ${q(address)}`);
56
- }
57
- /** @type {Record<string, string>} */
58
- const result = {};
59
- const paramPairs = parts[1].split('&');
60
- for (const pair of paramPairs) {
61
- const [key, value] = pair.split('=');
62
- if (!key || !value) {
63
- throw makeError(`Invalid parameter format in pair: ${q(pair)}`);
64
- }
65
- result[key] = value;
66
- }
67
- harden(result);
68
- mustMatch(result, shape);
69
- return result;
70
- },
71
- };