@agoric/fast-usdc 0.1.1-other-dev-3eb1a1d.0 → 0.2.0-u18.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 +43 -0
- package/package.json +19 -16
- package/src/cli/bridge-action.js +40 -0
- package/src/cli/cli.js +45 -152
- package/src/cli/config-commands.js +108 -0
- package/src/cli/config.js +15 -9
- package/src/cli/lp-commands.js +178 -0
- package/src/cli/operator-commands.js +145 -0
- package/src/cli/transfer.js +61 -11
- package/src/constants.js +25 -2
- package/src/exos/advancer.js +149 -103
- package/src/exos/liquidity-pool.js +52 -50
- package/src/exos/operator-kit.js +16 -10
- package/src/exos/settler.js +295 -58
- package/src/exos/status-manager.js +270 -57
- package/src/exos/transaction-feed.js +93 -35
- package/src/fast-usdc-policy.core.js +75 -0
- package/src/fast-usdc.contract.js +152 -63
- package/src/fast-usdc.flows.js +10 -0
- package/src/fast-usdc.start.js +44 -14
- package/src/type-guards.js +42 -20
- package/src/types.ts +58 -12
- package/src/util/agoric.js +1 -1
- package/src/util/bank.js +12 -0
- package/src/util/cctp.js +1 -1
- package/src/util/file.js +1 -1
- package/src/utils/deploy-config.js +166 -0
- package/tools/cli-tools.ts +9 -0
- package/tools/mock-io.ts +14 -0
- package/src/exos/README.md +0 -26
- package/src/utils/address.js +0 -71
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/* eslint-env node */
|
|
2
|
+
/**
|
|
3
|
+
* @import {Command} from 'commander';
|
|
4
|
+
* @import {OfferSpec} from '@agoric/smart-wallet/src/offers.js';
|
|
5
|
+
* @import {ExecuteOfferAction} from '@agoric/smart-wallet/src/smartWallet.js';
|
|
6
|
+
* @import {USDCProposalShapes} from '../pool-share-math.js';
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
fetchEnvNetworkConfig,
|
|
11
|
+
makeSmartWalletKit,
|
|
12
|
+
} from '@agoric/client-utils';
|
|
13
|
+
import { AmountMath } from '@agoric/ertp';
|
|
14
|
+
import {
|
|
15
|
+
assertParsableNumber,
|
|
16
|
+
ceilDivideBy,
|
|
17
|
+
multiplyBy,
|
|
18
|
+
parseRatio,
|
|
19
|
+
} from '@agoric/zoe/src/contractSupport/ratio.js';
|
|
20
|
+
import { InvalidArgumentError } from 'commander';
|
|
21
|
+
import { outputActionAndHint } from './bridge-action.js';
|
|
22
|
+
|
|
23
|
+
export const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
|
|
24
|
+
|
|
25
|
+
/** @param {string} arg */
|
|
26
|
+
const parseDecimal = arg => {
|
|
27
|
+
try {
|
|
28
|
+
assertParsableNumber(arg);
|
|
29
|
+
const n = Number(arg);
|
|
30
|
+
return n;
|
|
31
|
+
} catch {
|
|
32
|
+
throw new InvalidArgumentError('Not a number');
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @param {string} amountString
|
|
38
|
+
* @param {Brand} usdc
|
|
39
|
+
*/
|
|
40
|
+
const parseUSDCAmount = (amountString, usdc) => {
|
|
41
|
+
const USDC_DECIMALS = 6;
|
|
42
|
+
const unit = AmountMath.make(usdc, 10n ** BigInt(USDC_DECIMALS));
|
|
43
|
+
return multiplyBy(unit, parseRatio(amountString, usdc));
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @param {Command} program
|
|
48
|
+
* @param {{
|
|
49
|
+
* fetch?: Window['fetch'];
|
|
50
|
+
* smartWalletKit?: import('@agoric/client-utils').SmartWalletKit;
|
|
51
|
+
* stdout: typeof process.stdout;
|
|
52
|
+
* stderr: typeof process.stderr;
|
|
53
|
+
* env: typeof process.env;
|
|
54
|
+
* now: typeof Date.now;
|
|
55
|
+
* }} io
|
|
56
|
+
*/
|
|
57
|
+
export const addLPCommands = (
|
|
58
|
+
program,
|
|
59
|
+
{ fetch, smartWalletKit, stderr, stdout, env, now },
|
|
60
|
+
) => {
|
|
61
|
+
const loadSwk = async () => {
|
|
62
|
+
if (smartWalletKit) {
|
|
63
|
+
return smartWalletKit;
|
|
64
|
+
}
|
|
65
|
+
assert(fetch);
|
|
66
|
+
const networkConfig = await fetchEnvNetworkConfig({ env, fetch });
|
|
67
|
+
return makeSmartWalletKit({ delay, fetch }, networkConfig);
|
|
68
|
+
};
|
|
69
|
+
/** @type {undefined | ReturnType<typeof loadSwk>} */
|
|
70
|
+
let swkP;
|
|
71
|
+
|
|
72
|
+
program
|
|
73
|
+
.command('deposit')
|
|
74
|
+
.description('Deposit USDC into pool')
|
|
75
|
+
.addHelpText(
|
|
76
|
+
'after',
|
|
77
|
+
'\nPipe the STDOUT to a file such as deposit.json, then use the Agoric CLI to broadcast it:\n agoric wallet send --offer deposit.json --from gov1 --keyring-backend="test"',
|
|
78
|
+
)
|
|
79
|
+
.requiredOption('--amount <number>', 'USDC amount', parseDecimal)
|
|
80
|
+
.option('--offerId <string>', 'Offer id', String, `lpDeposit-${now()}`)
|
|
81
|
+
.action(async opts => {
|
|
82
|
+
swkP ||= loadSwk();
|
|
83
|
+
const swk = await swkP;
|
|
84
|
+
/** @type {Brand<'nat'>} */
|
|
85
|
+
// @ts-expect-error it doesnt recognize usdc as a Brand type
|
|
86
|
+
const usdc = swk.agoricNames.brand.USDC;
|
|
87
|
+
assert(usdc, 'USDC brand not in agoricNames');
|
|
88
|
+
|
|
89
|
+
const usdcAmount = parseUSDCAmount(opts.amount, usdc);
|
|
90
|
+
|
|
91
|
+
/** @type {USDCProposalShapes['deposit']} */
|
|
92
|
+
const proposal = {
|
|
93
|
+
give: {
|
|
94
|
+
USDC: usdcAmount,
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/** @type {OfferSpec} */
|
|
99
|
+
const offer = {
|
|
100
|
+
id: opts.offerId,
|
|
101
|
+
invitationSpec: {
|
|
102
|
+
source: 'agoricContract',
|
|
103
|
+
instancePath: ['fastUsdc'],
|
|
104
|
+
callPipe: [['makeDepositInvitation', []]],
|
|
105
|
+
},
|
|
106
|
+
proposal,
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
/** @type {ExecuteOfferAction} */
|
|
110
|
+
const bridgeAction = {
|
|
111
|
+
method: 'executeOffer',
|
|
112
|
+
offer,
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
outputActionAndHint(bridgeAction, { stderr, stdout }, swk.marshaller);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
program
|
|
119
|
+
.command('withdraw')
|
|
120
|
+
.description("Withdraw USDC from the LP's pool share")
|
|
121
|
+
.addHelpText(
|
|
122
|
+
'after',
|
|
123
|
+
'\nPipe the STDOUT to a file such as withdraw.json, then use the Agoric CLI to broadcast it:\n agoric wallet send --offer withdraw.json --from gov1 --keyring-backend="test"',
|
|
124
|
+
)
|
|
125
|
+
.requiredOption('--amount <number>', 'USDC amount', parseDecimal)
|
|
126
|
+
.option('--offerId <string>', 'Offer id', String, `lpWithdraw-${now()}`)
|
|
127
|
+
.action(async opts => {
|
|
128
|
+
swkP ||= loadSwk();
|
|
129
|
+
swkP ||= loadSwk();
|
|
130
|
+
const swk = await swkP;
|
|
131
|
+
|
|
132
|
+
/** @type {Brand<'nat'>} */
|
|
133
|
+
// @ts-expect-error it doesnt recognize FastLP as a Brand type
|
|
134
|
+
const poolShare = swk.agoricNames.brand.FastLP;
|
|
135
|
+
assert(poolShare, 'FastLP brand not in agoricNames');
|
|
136
|
+
|
|
137
|
+
/** @type {Brand<'nat'>} */
|
|
138
|
+
// @ts-expect-error it doesnt recognize usdc as a Brand type
|
|
139
|
+
const usdc = swk.agoricNames.brand.USDC;
|
|
140
|
+
assert(usdc, 'USDC brand not in agoricNames');
|
|
141
|
+
|
|
142
|
+
const usdcAmount = parseUSDCAmount(opts.amount, usdc);
|
|
143
|
+
|
|
144
|
+
/** @type {import('../types.js').PoolMetrics} */
|
|
145
|
+
// @ts-expect-error it treats this as "unknown"
|
|
146
|
+
const metrics = await swk.readPublished('fastUsdc.poolMetrics');
|
|
147
|
+
const fastLPAmount = ceilDivideBy(usdcAmount, metrics.shareWorth);
|
|
148
|
+
|
|
149
|
+
/** @type {USDCProposalShapes['withdraw']} */
|
|
150
|
+
const proposal = {
|
|
151
|
+
give: {
|
|
152
|
+
PoolShare: fastLPAmount,
|
|
153
|
+
},
|
|
154
|
+
want: {
|
|
155
|
+
USDC: usdcAmount,
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
/** @type {OfferSpec} */
|
|
160
|
+
const offer = {
|
|
161
|
+
id: opts.offerId,
|
|
162
|
+
invitationSpec: {
|
|
163
|
+
source: 'agoricContract',
|
|
164
|
+
instancePath: ['fastUsdc'],
|
|
165
|
+
callPipe: [['makeWithdrawInvitation', []]],
|
|
166
|
+
},
|
|
167
|
+
proposal,
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
outputActionAndHint(
|
|
171
|
+
{ method: 'executeOffer', offer },
|
|
172
|
+
{ stderr, stdout },
|
|
173
|
+
swk.marshaller,
|
|
174
|
+
);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
return program;
|
|
178
|
+
};
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/* eslint-env node */
|
|
2
|
+
/**
|
|
3
|
+
* @import {Command} from 'commander';
|
|
4
|
+
* @import {OfferSpec} from '@agoric/smart-wallet/src/offers.js';
|
|
5
|
+
* @import {ExecuteOfferAction} from '@agoric/smart-wallet/src/smartWallet.js';
|
|
6
|
+
* @import {OperatorKit} from '../exos/operator-kit.js';
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
fetchEnvNetworkConfig,
|
|
11
|
+
makeSmartWalletKit,
|
|
12
|
+
} from '@agoric/client-utils';
|
|
13
|
+
import { mustMatch } from '@agoric/internal';
|
|
14
|
+
import { Nat } from '@endo/nat';
|
|
15
|
+
import { InvalidArgumentError } from 'commander';
|
|
16
|
+
import { INVITATION_MAKERS_DESC } from '../exos/transaction-feed.js';
|
|
17
|
+
import { CctpTxEvidenceShape } from '../type-guards.js';
|
|
18
|
+
import { outputActionAndHint } from './bridge-action.js';
|
|
19
|
+
|
|
20
|
+
export const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
|
|
21
|
+
|
|
22
|
+
/** @param {string} arg */
|
|
23
|
+
const parseNat = arg => {
|
|
24
|
+
const n = Nat(BigInt(arg));
|
|
25
|
+
return n;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/** @param {string} arg */
|
|
29
|
+
const parseHex = arg => {
|
|
30
|
+
if (!arg.startsWith('0x')) throw new InvalidArgumentError('not a hex string');
|
|
31
|
+
return arg;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @param {Command} program
|
|
36
|
+
* @param {{
|
|
37
|
+
* fetch: Window['fetch'];
|
|
38
|
+
* stdout: typeof process.stdout;
|
|
39
|
+
* stderr: typeof process.stderr;
|
|
40
|
+
* env: typeof process.env;
|
|
41
|
+
* now: typeof Date.now;
|
|
42
|
+
* }} io
|
|
43
|
+
*/
|
|
44
|
+
export const addOperatorCommands = (
|
|
45
|
+
program,
|
|
46
|
+
{ fetch, stderr, stdout, env, now },
|
|
47
|
+
) => {
|
|
48
|
+
const operator = program
|
|
49
|
+
.command('operator')
|
|
50
|
+
.description('Oracle operator commands');
|
|
51
|
+
|
|
52
|
+
operator
|
|
53
|
+
.command('accept')
|
|
54
|
+
.description('Accept invitation to be an operator')
|
|
55
|
+
.addHelpText(
|
|
56
|
+
'after',
|
|
57
|
+
'\nPipe the STDOUT to a file such as accept.json, then use the Agoric CLI to broadcast it:\n agoric wallet send --offer accept.json --from gov1 --keyring-backend="test"',
|
|
58
|
+
)
|
|
59
|
+
.option('--offerId <string>', 'Offer id', String, `operatorAccept-${now()}`)
|
|
60
|
+
.action(async opts => {
|
|
61
|
+
const networkConfig = await fetchEnvNetworkConfig({ env, fetch });
|
|
62
|
+
|
|
63
|
+
const swk = await makeSmartWalletKit({ delay, fetch }, networkConfig);
|
|
64
|
+
const instance = swk.agoricNames.instance.fastUsdc;
|
|
65
|
+
assert(instance, 'fastUsdc instance not in agoricNames');
|
|
66
|
+
|
|
67
|
+
/** @type {OfferSpec} */
|
|
68
|
+
const offer = {
|
|
69
|
+
id: opts.offerId,
|
|
70
|
+
invitationSpec: {
|
|
71
|
+
source: 'purse',
|
|
72
|
+
instance,
|
|
73
|
+
description: INVITATION_MAKERS_DESC,
|
|
74
|
+
},
|
|
75
|
+
proposal: {},
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/** @type {ExecuteOfferAction} */
|
|
79
|
+
const bridgeAction = {
|
|
80
|
+
method: 'executeOffer',
|
|
81
|
+
offer,
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
outputActionAndHint(bridgeAction, { stderr, stdout });
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
operator
|
|
88
|
+
.command('attest')
|
|
89
|
+
.description('Attest to an observed Fast USDC transfer')
|
|
90
|
+
.addHelpText(
|
|
91
|
+
'after',
|
|
92
|
+
'\nPipe the STDOUT to a file such as attest.json, then use the Agoric CLI to broadcast it:\n agoric wallet send --offer attest.json --from gov1 --keyring-backend="test"',
|
|
93
|
+
)
|
|
94
|
+
.requiredOption('--previousOfferId <string>', 'Offer id', String)
|
|
95
|
+
.requiredOption('--forwardingChannel <string>', 'Channel id', String)
|
|
96
|
+
.requiredOption('--recipientAddress <string>', 'bech32 address', String)
|
|
97
|
+
.requiredOption('--blockHash <0xhex>', 'hex hash', parseHex)
|
|
98
|
+
.requiredOption('--blockNumber <number>', 'number', parseNat)
|
|
99
|
+
.requiredOption('--chainId <string>', 'chain id', Number)
|
|
100
|
+
.requiredOption('--amount <number>', 'number', parseNat)
|
|
101
|
+
.requiredOption('--forwardingAddress <string>', 'bech32 address', String)
|
|
102
|
+
.requiredOption('--sender <string>', 'Ethereum address initiating', String)
|
|
103
|
+
.requiredOption('--txHash <0xhexo>', 'hex hash', parseHex)
|
|
104
|
+
.option('--offerId <string>', 'Offer id', String, `operatorAttest-${now()}`)
|
|
105
|
+
.action(async opts => {
|
|
106
|
+
const {
|
|
107
|
+
offerId,
|
|
108
|
+
previousOfferId,
|
|
109
|
+
forwardingChannel,
|
|
110
|
+
recipientAddress,
|
|
111
|
+
amount,
|
|
112
|
+
forwardingAddress,
|
|
113
|
+
sender,
|
|
114
|
+
...flat
|
|
115
|
+
} = opts;
|
|
116
|
+
|
|
117
|
+
const evidence = harden({
|
|
118
|
+
aux: { forwardingChannel, recipientAddress },
|
|
119
|
+
tx: { amount, forwardingAddress, sender },
|
|
120
|
+
...flat,
|
|
121
|
+
});
|
|
122
|
+
mustMatch(evidence, CctpTxEvidenceShape);
|
|
123
|
+
|
|
124
|
+
/** @type {OfferSpec} */
|
|
125
|
+
const offer = {
|
|
126
|
+
id: offerId,
|
|
127
|
+
invitationSpec: {
|
|
128
|
+
source: 'continuing',
|
|
129
|
+
previousOffer: previousOfferId,
|
|
130
|
+
/** @type {string & keyof OperatorKit['invitationMakers'] } */
|
|
131
|
+
invitationMakerName: 'SubmitEvidence',
|
|
132
|
+
/** @type {Parameters<OperatorKit['invitationMakers']['SubmitEvidence']> } */
|
|
133
|
+
invitationArgs: [evidence],
|
|
134
|
+
},
|
|
135
|
+
proposal: {},
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
outputActionAndHint(
|
|
139
|
+
{ method: 'executeOffer', offer },
|
|
140
|
+
{ stderr, stdout },
|
|
141
|
+
);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
return operator;
|
|
145
|
+
};
|
package/src/cli/transfer.js
CHANGED
|
@@ -1,44 +1,54 @@
|
|
|
1
|
+
/* eslint-env node */
|
|
1
2
|
/* global globalThis */
|
|
2
3
|
|
|
3
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
fetchEnvNetworkConfig,
|
|
6
|
+
makeVStorage,
|
|
7
|
+
pickEndpoint,
|
|
8
|
+
} from '@agoric/client-utils';
|
|
9
|
+
import { encodeAddressHook } from '@agoric/cosmic-proto/address-hooks.js';
|
|
10
|
+
import { queryFastUSDCLocalChainAccount } from '../util/agoric.js';
|
|
4
11
|
import { depositForBurn, makeProvider } from '../util/cctp.js';
|
|
5
12
|
import {
|
|
6
13
|
makeSigner,
|
|
7
14
|
queryForwardingAccount,
|
|
8
15
|
registerFwdAccount,
|
|
9
16
|
} from '../util/noble.js';
|
|
10
|
-
import {
|
|
17
|
+
import { queryUSDCBalance } from '../util/bank.js';
|
|
11
18
|
|
|
12
|
-
/** @import {
|
|
19
|
+
/** @import { File } from '../util/file' */
|
|
13
20
|
/** @import { VStorage } from '@agoric/client-utils' */
|
|
14
21
|
/** @import { SigningStargateClient } from '@cosmjs/stargate' */
|
|
15
22
|
/** @import { JsonRpcProvider as ethProvider } from 'ethers' */
|
|
16
23
|
|
|
17
24
|
const transfer = async (
|
|
18
|
-
/** @type {
|
|
25
|
+
/** @type {File} */ configFile,
|
|
19
26
|
/** @type {string} */ amount,
|
|
20
|
-
/** @type {string} */
|
|
27
|
+
/** @type {string} */ EUD,
|
|
21
28
|
out = console,
|
|
22
29
|
fetch = globalThis.fetch,
|
|
23
30
|
/** @type {VStorage | undefined} */ vstorage,
|
|
24
31
|
/** @type {{signer: SigningStargateClient, address: string} | undefined} */ nobleSigner,
|
|
25
32
|
/** @type {ethProvider | undefined} */ ethProvider,
|
|
33
|
+
env = process.env,
|
|
34
|
+
setTimeout = globalThis.setTimeout,
|
|
26
35
|
) => {
|
|
27
36
|
const execute = async (
|
|
28
37
|
/** @type {import('./config').ConfigOpts} */ config,
|
|
29
38
|
) => {
|
|
39
|
+
const netConfig = await fetchEnvNetworkConfig({ env, fetch });
|
|
30
40
|
vstorage ||= makeVStorage(
|
|
31
41
|
{ fetch },
|
|
32
|
-
{ chainName: 'agoric', rpcAddrs: [
|
|
42
|
+
{ chainName: 'agoric', rpcAddrs: [pickEndpoint(netConfig)] },
|
|
33
43
|
);
|
|
34
44
|
const agoricAddr = await queryFastUSDCLocalChainAccount(vstorage, out);
|
|
35
|
-
const
|
|
36
|
-
out.log(`forwarding destination ${
|
|
45
|
+
const encodedAddr = encodeAddressHook(agoricAddr, { EUD });
|
|
46
|
+
out.log(`forwarding destination ${encodedAddr}`);
|
|
37
47
|
|
|
38
48
|
const { exists, address } = await queryForwardingAccount(
|
|
39
49
|
config.nobleApi,
|
|
40
50
|
config.nobleToAgoricChannel,
|
|
41
|
-
|
|
51
|
+
encodedAddr,
|
|
42
52
|
out,
|
|
43
53
|
fetch,
|
|
44
54
|
);
|
|
@@ -51,18 +61,30 @@ const transfer = async (
|
|
|
51
61
|
signer,
|
|
52
62
|
signerAddress,
|
|
53
63
|
config.nobleToAgoricChannel,
|
|
54
|
-
|
|
64
|
+
encodedAddr,
|
|
55
65
|
out,
|
|
56
66
|
);
|
|
57
67
|
out.log(res);
|
|
58
68
|
} catch (e) {
|
|
59
69
|
out.error(
|
|
60
|
-
`Error registering noble forwarding account for ${
|
|
70
|
+
`Error registering noble forwarding account for ${encodedAddr} on channel ${config.nobleToAgoricChannel}`,
|
|
61
71
|
);
|
|
62
72
|
throw e;
|
|
63
73
|
}
|
|
64
74
|
}
|
|
65
75
|
|
|
76
|
+
const destChain = config.destinationChains?.find(chain =>
|
|
77
|
+
EUD.startsWith(chain.bech32Prefix),
|
|
78
|
+
);
|
|
79
|
+
if (!destChain) {
|
|
80
|
+
out.error(
|
|
81
|
+
`No destination chain found in config with matching bech32 prefix for ${EUD}, cannot query destination address`,
|
|
82
|
+
);
|
|
83
|
+
throw new Error();
|
|
84
|
+
}
|
|
85
|
+
const { api, USDCDenom } = destChain;
|
|
86
|
+
const startingBalance = await queryUSDCBalance(EUD, api, USDCDenom, fetch);
|
|
87
|
+
|
|
66
88
|
ethProvider ||= makeProvider(config.ethRpc);
|
|
67
89
|
await depositForBurn(
|
|
68
90
|
ethProvider,
|
|
@@ -73,6 +95,34 @@ const transfer = async (
|
|
|
73
95
|
amount,
|
|
74
96
|
out,
|
|
75
97
|
);
|
|
98
|
+
|
|
99
|
+
const refreshDelayMS = 1200;
|
|
100
|
+
const completeP = /** @type {Promise<void>} */ (
|
|
101
|
+
new Promise((res, rej) => {
|
|
102
|
+
const refreshUSDCBalance = async () => {
|
|
103
|
+
out.log('polling usdc balance');
|
|
104
|
+
const currentBalance = await queryUSDCBalance(
|
|
105
|
+
EUD,
|
|
106
|
+
api,
|
|
107
|
+
USDCDenom,
|
|
108
|
+
fetch,
|
|
109
|
+
);
|
|
110
|
+
if (currentBalance !== startingBalance) {
|
|
111
|
+
res();
|
|
112
|
+
} else {
|
|
113
|
+
setTimeout(() => refreshUSDCBalance().catch(rej), refreshDelayMS);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
refreshUSDCBalance().catch(rej);
|
|
117
|
+
})
|
|
118
|
+
).catch(e => {
|
|
119
|
+
out.error(
|
|
120
|
+
'Error checking destination address balance, could not detect completion of transfer.',
|
|
121
|
+
);
|
|
122
|
+
out.error(e.message);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
await completeP;
|
|
76
126
|
};
|
|
77
127
|
|
|
78
128
|
let config;
|
package/src/constants.js
CHANGED
|
@@ -7,12 +7,29 @@ export const TxStatus = /** @type {const} */ ({
|
|
|
7
7
|
/** tx was observed but not advanced */
|
|
8
8
|
Observed: 'OBSERVED',
|
|
9
9
|
/** IBC transfer is initiated */
|
|
10
|
+
Advancing: 'ADVANCING',
|
|
11
|
+
/** IBC transfer is complete */
|
|
10
12
|
Advanced: 'ADVANCED',
|
|
11
|
-
/**
|
|
12
|
-
|
|
13
|
+
/** IBC transfer failed (timed out) */
|
|
14
|
+
AdvanceFailed: 'ADVANCE_FAILED',
|
|
15
|
+
/** Advance skipped and waiting for forward */
|
|
16
|
+
AdvanceSkipped: 'ADVANCE_SKIPPED',
|
|
17
|
+
/** settlement for matching advance received and funds disbursed */
|
|
18
|
+
Disbursed: 'DISBURSED',
|
|
19
|
+
/** fallback: do not collect fees */
|
|
20
|
+
Forwarded: 'FORWARDED',
|
|
21
|
+
/** failed to forward to EUD */
|
|
22
|
+
ForwardFailed: 'FORWARD_FAILED',
|
|
13
23
|
});
|
|
14
24
|
harden(TxStatus);
|
|
15
25
|
|
|
26
|
+
// According to the state diagram
|
|
27
|
+
export const TerminalTxStatus = {
|
|
28
|
+
[TxStatus.Forwarded]: true,
|
|
29
|
+
[TxStatus.ForwardFailed]: true,
|
|
30
|
+
[TxStatus.Disbursed]: true,
|
|
31
|
+
};
|
|
32
|
+
|
|
16
33
|
/**
|
|
17
34
|
* Status values for the StatusManager.
|
|
18
35
|
*
|
|
@@ -22,6 +39,12 @@ export const PendingTxStatus = /** @type {const} */ ({
|
|
|
22
39
|
/** tx was observed but not advanced */
|
|
23
40
|
Observed: 'OBSERVED',
|
|
24
41
|
/** IBC transfer is initiated */
|
|
42
|
+
Advancing: 'ADVANCING',
|
|
43
|
+
/** IBC transfer failed (timed out) */
|
|
44
|
+
AdvanceFailed: 'ADVANCE_FAILED',
|
|
45
|
+
/** IBC transfer is complete */
|
|
25
46
|
Advanced: 'ADVANCED',
|
|
47
|
+
/** Advance skipped and waiting for forward */
|
|
48
|
+
AdvanceSkipped: 'ADVANCE_SKIPPED',
|
|
26
49
|
});
|
|
27
50
|
harden(PendingTxStatus);
|