Skip to content

Abstract 0.26 with Polytone prediction #163

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/many-beers-camp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@abstract-money/core": minor
---

Abstract 0.26
5 changes: 5 additions & 0 deletions .changeset/warm-laws-wink.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@abstract-money/core": patch
---

Add polytone proxy address prediction functions
10 changes: 5 additions & 5 deletions packages/core/abstract.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,23 @@ import { registry, vanilla } from '@abstract-money/cli/plugins'
const contractsConfig = [
{
name: 'account',
version: '0.25.0',
version: '0.26.0',
},
{
name: 'registry',
version: '0.25.0',
version: '0.26.0',
},
{
name: 'ans-host',
version: '0.25.0',
version: '0.26.0',
},
{
name: 'ibc-client',
version: '0.25.0',
version: '0.26.0',
},
{
name: 'ica-client',
version: '0.25.0',
version: '0.26.0',
},
]

Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ export * from './events'
export * from './authz'
export * from './cosmwasm'
export * from './modules'
export * from './polytone'

export { ABSTRACT_NAMESPACE } from './modules/abstract-module-id'
1 change: 1 addition & 0 deletions packages/core/src/utils/polytone/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './predict-proxy-address'
54 changes: 54 additions & 0 deletions packages/core/src/utils/polytone/predict-proxy-address.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { describe, expect, it } from 'vitest'
import { getInstantiate2Address } from '../module-factory'
import {
generateSha512Salt,
predictPolytoneProxyAddress,
} from './predict-proxy-address'

describe('predictPolytoneProxyAddress', () => {
// https://github.com/DA0-DA0/polytone/blob/f70440a35f12f97a9018849ca7e6d241a53582ce/cw-orch-state.json
const neutronNoteAddress =
'neutron1767kfqeglqyctuqsmvyzgjecs60lpqju2f590smxevk9duq5fhaqgk5eca'
const neutronToOsmosisVoiceAddress =
'osmo1vw02frqejfw2v2w7dy6ws35jp9743dwkxy0laalwsuvzzvkszz7s8d93yw'
// https://celatone.osmosis.zone/osmosis-1/codes/127
const osmosisProxyChecksum =
'5094551145BCD256538775A0611CE9E88F8D7A182A06F082F901FFED9184BB5A'
// The sender from the source chain
const neutronSenderAddress =
'neutron13vzaav9pdsnuccy9wjzauv205q4e70t8lwtvngsqhyqs3xdjlu0sglylyv'
// From state of Voice contract
const connectionIdFromVoice = 'connection-2338'
// https://celatone.osmosis.zone/osmosis-1/contracts/osmo1fgdp4k54nmhuydwmgfzygm0fjyvaz0thz8rglctpl5lehe57tcyqqfy698
const expectedAddress =
'osmo1fgdp4k54nmhuydwmgfzygm0fjyvaz0thz8rglctpl5lehe57tcyqqfy698'

it('returns the correct address with raw functions', async () => {
const salt = generateSha512Salt(
connectionIdFromVoice,
`wasm.${neutronNoteAddress}`,
neutronSenderAddress,
)

const result = await getInstantiate2Address(
neutronToOsmosisVoiceAddress,
osmosisProxyChecksum,
salt,
)

// https://celatone.osmosis.zone/osmosis-1/contracts/osmo1fgdp4k54nmhuydwmgfzygm0fjyvaz0thz8rglctpl5lehe57tcyqqfy698
expect(result).toBe(expectedAddress)
})

it('returns the correct address with full function', async () => {
const result = await predictPolytoneProxyAddress({
hostVoiceAddress: neutronToOsmosisVoiceAddress,
hostProxyChecksum: osmosisProxyChecksum,
hostVoiceConnectionId: connectionIdFromVoice,
controllerNoteAddress: neutronNoteAddress,
controllerSender: neutronSenderAddress,
})

expect(result).toBe(expectedAddress)
})
})
72 changes: 72 additions & 0 deletions packages/core/src/utils/polytone/predict-proxy-address.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { createHash } from 'node:crypto'
import { fromBech32 } from '@cosmjs/encoding'
import { getInstantiate2Address } from '../module-factory'

/**
* Generates a salt by hashing the provided inputs with SHA-512.
*
* @param inputs - An array of strings to hash. Each input will be concatenated in the order provided.
* @returns A Uint8Array containing the 64-byte (512-bit) hash.
*/
export const generateSha512Salt = (...inputs: string[]): Uint8Array => {
const hash = createHash('sha512')
for (const input of inputs) {
hash.update(input)
}
return Uint8Array.from(hash.digest())
}

/**
* Generate the salt for a new Polytone proxy.
* @param connectionId
* @param counterpartyPort
* @param sender
*/
export const generatePolytoneProxySalt = ({
connectionId,
counterpartyPort,
sender,
}: {
connectionId: `connection-${string}`
counterpartyPort: `wasm.${string}`
sender: string
}) => generateSha512Salt(connectionId, counterpartyPort, sender)

/**
* Predicts the address of a Polytone proxy contract.
* @param controllerNoteAddress - The address of the controller chain's Note contract.
* @param controllerSender - The sending address on the controller chain.
* @param hostVoiceAddress - The address of the host chain's Voice contract.
* @param hostProxyChecksum - The checksum of the host chain's proxy contract.
* @param hostVoiceConnectionId - The connection ID of the Voice contract to the Note.
*/
export const predictPolytoneProxyAddress = async ({
controllerNoteAddress,
controllerSender,
hostVoiceAddress,
hostVoiceConnectionId,
hostProxyChecksum,
}: {
controllerNoteAddress: string
controllerSender: string
hostVoiceAddress: string
hostVoiceConnectionId: `connection-${string}`
hostProxyChecksum: string
}) => {
// Sanity check
const notePrefix = fromBech32(controllerNoteAddress).prefix
const senderPrefix = fromBech32(controllerSender).prefix
if (notePrefix !== senderPrefix) {
throw new Error(
`Sender and note address prefixes do not match: ${senderPrefix} !== ${notePrefix}`,
)
}

const salt = generatePolytoneProxySalt({
connectionId: hostVoiceConnectionId,
counterpartyPort: `wasm.${controllerNoteAddress}`,
sender: controllerSender,
})

return await getInstantiate2Address(hostVoiceAddress, hostProxyChecksum, salt)
}
Loading