-
Notifications
You must be signed in to change notification settings - Fork 175
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
🪚 OmniGraph™ Sign & Send flow (#108)
- Loading branch information
1 parent
66d923a
commit 878f278
Showing
11 changed files
with
396 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
export * from './filesystem' | ||
export * from './language' | ||
export * from './stdio' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './plurals' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
const cardinalRules = new Intl.PluralRules('en-US') | ||
|
||
const ordinalRules = new Intl.PluralRules('en-US', { type: 'ordinal' }) | ||
const ordinals: Record<Intl.LDMLPluralRule, string> = { | ||
one: 'st', | ||
two: 'nd', | ||
few: 'rd', | ||
other: 'th', | ||
zero: 'th', | ||
many: 'th', | ||
} | ||
|
||
/** | ||
* Turn a number into an ordinal. | ||
* | ||
* ```typescript | ||
* pluralizeOrdinal(7) // 7th | ||
* pluralizeOrdinal(1) // 1st | ||
* pluralizeOrdinal(19) // 19th | ||
* ``` | ||
* | ||
* @param {number} n | ||
* @returns {string} | ||
*/ | ||
export const pluralizeOrdinal = (n: number): string => { | ||
const rule = ordinalRules.select(n) | ||
const suffix = ordinals[rule] | ||
|
||
return `${n}${suffix}` | ||
} | ||
|
||
/** | ||
* Choose a correct form of a noun based on cardinality. | ||
* | ||
* ```typescript | ||
* pluralizeNoun(7, 'cat') // cats | ||
* pluralizeNoun(1, 'cat') // cat | ||
* pluralizeNoun(19, 'cactus', 'cacti') // cacti | ||
* ``` | ||
* | ||
* @param {number} n | ||
* @param {string} singular The signular form of the english noun | ||
* @param {string} [plural] Plural version of the noun for irregular cases | ||
* @returns {string} | ||
*/ | ||
export const pluralizeNoun = (n: number, singular: string, plural: string = `${singular}s`): string => { | ||
const rule = cardinalRules.select(n) | ||
if (rule === 'one') return singular | ||
|
||
return plural | ||
} |
67 changes: 67 additions & 0 deletions
67
packages/io-utils/test/language/__snapshots__/plurals.test.ts.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`language/plurals pluralizeNoun with custom plural should work for 0 1`] = `"cacti"`; | ||
|
||
exports[`language/plurals pluralizeNoun with custom plural should work for 1 1`] = `"cactus"`; | ||
|
||
exports[`language/plurals pluralizeNoun with custom plural should work for 2 1`] = `"cacti"`; | ||
|
||
exports[`language/plurals pluralizeNoun with custom plural should work for 3 1`] = `"cacti"`; | ||
|
||
exports[`language/plurals pluralizeNoun with custom plural should work for 4 1`] = `"cacti"`; | ||
|
||
exports[`language/plurals pluralizeNoun with custom plural should work for 5 1`] = `"cacti"`; | ||
|
||
exports[`language/plurals pluralizeNoun with custom plural should work for 11 1`] = `"cacti"`; | ||
|
||
exports[`language/plurals pluralizeNoun with custom plural should work for 12 1`] = `"cacti"`; | ||
|
||
exports[`language/plurals pluralizeNoun with custom plural should work for 21 1`] = `"cacti"`; | ||
|
||
exports[`language/plurals pluralizeNoun with custom plural should work for 100 1`] = `"cacti"`; | ||
|
||
exports[`language/plurals pluralizeNoun with custom plural should work for 1234 1`] = `"cacti"`; | ||
|
||
exports[`language/plurals pluralizeNoun without custom plural should work for 0 1`] = `"cats"`; | ||
|
||
exports[`language/plurals pluralizeNoun without custom plural should work for 1 1`] = `"cat"`; | ||
|
||
exports[`language/plurals pluralizeNoun without custom plural should work for 2 1`] = `"cats"`; | ||
|
||
exports[`language/plurals pluralizeNoun without custom plural should work for 3 1`] = `"cats"`; | ||
|
||
exports[`language/plurals pluralizeNoun without custom plural should work for 4 1`] = `"cats"`; | ||
|
||
exports[`language/plurals pluralizeNoun without custom plural should work for 5 1`] = `"cats"`; | ||
|
||
exports[`language/plurals pluralizeNoun without custom plural should work for 11 1`] = `"cats"`; | ||
|
||
exports[`language/plurals pluralizeNoun without custom plural should work for 12 1`] = `"cats"`; | ||
|
||
exports[`language/plurals pluralizeNoun without custom plural should work for 21 1`] = `"cats"`; | ||
|
||
exports[`language/plurals pluralizeNoun without custom plural should work for 100 1`] = `"cats"`; | ||
|
||
exports[`language/plurals pluralizeNoun without custom plural should work for 1234 1`] = `"cats"`; | ||
|
||
exports[`language/plurals pluralizeOrdinal should work for 0 1`] = `"0th"`; | ||
|
||
exports[`language/plurals pluralizeOrdinal should work for 1 1`] = `"1st"`; | ||
|
||
exports[`language/plurals pluralizeOrdinal should work for 2 1`] = `"2nd"`; | ||
|
||
exports[`language/plurals pluralizeOrdinal should work for 3 1`] = `"3rd"`; | ||
|
||
exports[`language/plurals pluralizeOrdinal should work for 4 1`] = `"4th"`; | ||
|
||
exports[`language/plurals pluralizeOrdinal should work for 5 1`] = `"5th"`; | ||
|
||
exports[`language/plurals pluralizeOrdinal should work for 11 1`] = `"11th"`; | ||
|
||
exports[`language/plurals pluralizeOrdinal should work for 12 1`] = `"12th"`; | ||
|
||
exports[`language/plurals pluralizeOrdinal should work for 21 1`] = `"21st"`; | ||
|
||
exports[`language/plurals pluralizeOrdinal should work for 100 1`] = `"100th"`; | ||
|
||
exports[`language/plurals pluralizeOrdinal should work for 1234 1`] = `"1234th"`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { pluralizeNoun, pluralizeOrdinal } from '@/language' | ||
|
||
describe('language/plurals', () => { | ||
describe('pluralizeOrdinal', () => { | ||
it.each([0, 1, 2, 3, 4, 5, 11, 12, 21, 100, 1234])(`should work for %d`, (n) => | ||
expect(pluralizeOrdinal(n)).toMatchSnapshot() | ||
) | ||
}) | ||
|
||
describe('pluralizeNoun', () => { | ||
describe('without custom plural', () => { | ||
it.each([0, 1, 2, 3, 4, 5, 11, 12, 21, 100, 1234])(`should work for %d`, (n) => | ||
expect(pluralizeNoun(n, 'cat')).toMatchSnapshot() | ||
) | ||
}) | ||
|
||
describe('with custom plural', () => { | ||
it.each([0, 1, 2, 3, 4, 5, 11, 12, 21, 100, 1234])(`should work for %d`, (n) => | ||
expect(pluralizeNoun(n, 'cactus', 'cacti')).toMatchSnapshot() | ||
) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export * from './format' | ||
export * from './signer' | ||
export * from './types' | ||
export * from './utils' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import { createModuleLogger, pluralizeNoun, pluralizeOrdinal } from '@layerzerolabs/io-utils' | ||
import type { OmniSignerFactory, OmniTransaction, OmniTransactionWithReceipt } from './types' | ||
import { formatOmniPoint } from '@/omnigraph/format' | ||
import type { OmniError } from '@/omnigraph/types' | ||
|
||
/** | ||
* Creates a sign & send utility for a list of transaction | ||
* with a help of `OmniSignerFactory` | ||
* | ||
* @param {OmniSignerFactory} createSigner | ||
*/ | ||
export const createSignAndSend = | ||
(createSigner: OmniSignerFactory) => | ||
async ( | ||
transactions: OmniTransaction[] | ||
): Promise<[successful: OmniTransactionWithReceipt[], errors: OmniError[]]> => { | ||
const logger = createModuleLogger('sign & send') | ||
|
||
// Put it here so that we don't need to type like seven toilet rolls of variable names | ||
const n = transactions.length | ||
|
||
// Just exit when there is nothing to sign | ||
if (n === 0) return logger.debug(`No transactions to sign, exiting`), [[], []] | ||
|
||
// Tell the user how many we are signing | ||
logger.debug(`Signing ${n} ${pluralizeNoun(n, 'transaction')}`) | ||
|
||
// We'll gather the successful transactions here | ||
const successful: OmniTransactionWithReceipt[] = [] | ||
|
||
for (const [index, transaction] of transactions.entries()) { | ||
// We want to refer to this transaction by index so we create an ordinal for it (1st, 2nd etc) | ||
const ordinal = pluralizeOrdinal(index + 1) | ||
|
||
try { | ||
logger.debug(`Signing ${ordinal} transaction to ${formatOmniPoint(transaction.point)}`) | ||
|
||
logger.debug(`Creating signer for ${ordinal} transaction`) | ||
const signer = await createSigner(transaction.point.eid) | ||
|
||
logger.debug(`Signing ${ordinal} transaction`) | ||
const response = await signer.signAndSend(transaction) | ||
|
||
logger.debug(`Signed ${ordinal} transaction, got hash ${response.transactionHash}`) | ||
|
||
const receipt = await response.wait() | ||
logger.debug(`Finished ${ordinal} transaction`) | ||
|
||
successful.push({ transaction, receipt }) | ||
} catch (error) { | ||
logger.debug(`Failed to process ${ordinal} transaction: ${error}`) | ||
|
||
return [successful, [{ point: transaction.point, error }]] | ||
} | ||
} | ||
|
||
// Tell the inquisitive user what a good job we did | ||
logger.debug(`Successfully signed ${n} ${pluralizeNoun(n, 'transaction')}`) | ||
|
||
return [successful, []] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.