diff --git a/.changeset/kind-turkeys-smell.md b/.changeset/kind-turkeys-smell.md new file mode 100644 index 0000000..89f434e --- /dev/null +++ b/.changeset/kind-turkeys-smell.md @@ -0,0 +1,5 @@ +--- +'@lens-protocol/metadata': minor +--- + +**feat:** adds `signMetadata` and `lensMessage` helpers diff --git a/package.json b/package.json index d6fd35c..2a67250 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,7 @@ "@jest/globals": "^29.7.0", "@lens-protocol/client": "2.0.0-alpha.25", "@types/fs-extra": "^11.0.1", + "@types/json-stable-stringify": "^1.0.36", "@types/node": "^20.5.0", "@types/uuid": "^9.0.4", "@typescript-eslint/eslint-plugin": "^6.4.0", @@ -106,6 +107,7 @@ }, "packageManager": "pnpm@8.2.0", "dependencies": { + "json-stable-stringify": "^1.1.1", "uuid": "^9.0.1" }, "pnpm": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index acc6318..a8a9f4d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,6 +9,9 @@ overrides: ethers: ^5.7.2 dependencies: + json-stable-stringify: + specifier: ^1.1.1 + version: 1.1.1 uuid: specifier: ^9.0.1 version: 9.0.1 @@ -29,6 +32,9 @@ devDependencies: '@types/fs-extra': specifier: ^11.0.1 version: 11.0.1 + '@types/json-stable-stringify': + specifier: ^1.0.36 + version: 1.0.36 '@types/node': specifier: ^20.5.0 version: 20.5.0 @@ -2537,6 +2543,10 @@ packages: resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} dev: true + /@types/json-stable-stringify@1.0.36: + resolution: {integrity: sha512-b7bq23s4fgBB76n34m2b3RBf6M369B0Z9uRR8aHTMd8kZISRkmDEpPD8hhpYvDFzr3bJCPES96cm3Q6qRNDbQw==} + dev: true + /@types/json5@0.0.29: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} dev: true @@ -3478,10 +3488,21 @@ packages: /call-bind@1.0.2: resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} dependencies: - function-bind: 1.1.1 + function-bind: 1.1.2 get-intrinsic: 1.2.1 dev: true + /call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + dev: false + /callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -3810,6 +3831,15 @@ packages: clone: 1.0.4 dev: true + /define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + dev: false + /define-properties@1.2.0: resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==} engines: {node: '>= 0.4'} @@ -4001,6 +4031,17 @@ packages: which-typed-array: 1.1.11 dev: true + /es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.4 + dev: false + + /es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + /es-set-tostringtag@2.0.1: resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} engines: {node: '>= 0.4'} @@ -4504,7 +4545,6 @@ packages: /function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - dev: true /function.prototype.name@1.1.5: resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} @@ -4533,12 +4573,22 @@ packages: /get-intrinsic@1.2.1: resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} dependencies: - function-bind: 1.1.1 + function-bind: 1.1.2 has: 1.0.3 has-proto: 1.0.1 has-symbols: 1.0.3 dev: true + /get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.1 + has-symbols: 1.0.3 + hasown: 2.0.0 + /get-package-type@0.1.0: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} engines: {node: '>=8.0.0'} @@ -4643,8 +4693,7 @@ packages: /gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: - get-intrinsic: 1.2.1 - dev: true + get-intrinsic: 1.2.4 /graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -4723,15 +4772,19 @@ packages: get-intrinsic: 1.2.1 dev: true + /has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + dependencies: + es-define-property: 1.0.0 + dev: false + /has-proto@1.0.1: resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} engines: {node: '>= 0.4'} - dev: true /has-symbols@1.0.3: resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} engines: {node: '>= 0.4'} - dev: true /has-tostringtag@1.0.0: resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} @@ -4759,7 +4812,6 @@ packages: engines: {node: '>= 0.4'} dependencies: function-bind: 1.1.2 - dev: true /hey-listen@1.0.8: resolution: {integrity: sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==} @@ -5088,7 +5140,6 @@ packages: /isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} - dev: true /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -5645,6 +5696,16 @@ packages: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} dev: true + /json-stable-stringify@1.1.1: + resolution: {integrity: sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + isarray: 2.0.5 + jsonify: 0.0.1 + object-keys: 1.1.1 + dev: false + /json5@1.0.2: resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} hasBin: true @@ -5676,6 +5737,10 @@ packages: graceful-fs: 4.2.11 dev: true + /jsonify@0.0.1: + resolution: {integrity: sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==} + dev: false + /jszip@3.10.1: resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} dependencies: @@ -6150,7 +6215,6 @@ packages: /object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} - dev: true /object.assign@4.1.4: resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} @@ -6778,6 +6842,18 @@ packages: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} dev: true + /set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + dev: false + /setimmediate@1.0.5: resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} dev: true diff --git a/src/__tests__/signMetadata.spec.ts b/src/__tests__/signMetadata.spec.ts new file mode 100644 index 0000000..b418187 --- /dev/null +++ b/src/__tests__/signMetadata.spec.ts @@ -0,0 +1,38 @@ +import { describe, expect, it } from '@jest/globals'; +import { Wallet } from 'ethers'; + +const signer = new Wallet('0xd6e6257e8cf0f321ad0f798dd0b121a7eb4fe9c7c51994e843c0a1ed05867a5f'); + +import { MetadataAttributeType } from '../MetadataAttribute'; +import { textOnly } from '../builders'; +import { signMetadata } from '../signMetadata.js'; + +describe(`Given the ${signMetadata.name} function`, () => { + describe('when called on PublicationMetadata', () => { + it('should return signed metadata with simple flat metadata', async () => { + const metadata = textOnly({ + content: 'Hello, world!', + id: '42', + attributes: [ + { + key: 'string', + value: 'value', + type: MetadataAttributeType.STRING, + }, + { + key: 'boolean', + value: 'true', + type: MetadataAttributeType.BOOLEAN, + }, + ], + }); + + const signed = await signMetadata(metadata, (message) => signer.signMessage(message)); + + expect(signed).toHaveProperty( + 'signature', + '0x28e8944e5ec1ab1cce78ead972262af4e2e0148d7f8eabf36ff03ff827021b685c3858b8e34caef13a932fb992a856a41f9f0a9107d3440dbca52ec4101aca761b', + ); + }); + }); +}); diff --git a/src/builders/encryption.ts b/src/builders/encryption.ts index 2b9fb56..69a427a 100644 --- a/src/builders/encryption.ts +++ b/src/builders/encryption.ts @@ -221,7 +221,7 @@ export type AdvancedContractConditionDetails = { /** * The function ABI. Has to be in a human-readable string format, which you can convert using the ethers library. - * See here for more info https://docs.ethers.io/v5/api/utils/abi/fragments/#human-readable-abi + * See here for more info https://docs.ethers.org/v5/api/utils/abi/formats/#abi-formats--human-readable-abi */ abi: string; diff --git a/src/index.ts b/src/index.ts index 24bf478..56e05ea 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,4 +8,5 @@ export * from './module/index.js'; export * from './primitives.js'; export * from './profile/index.js'; export * from './publication/index.js'; +export * from './signMetadata.js'; export type { Brand, DistributiveOmit, Overwrite, Prettify, TwoAtLeastArray } from './utils.js'; diff --git a/src/profile/ProfileMetadataSchema.ts b/src/profile/ProfileMetadataSchema.ts index 2c778e0..3121583 100644 --- a/src/profile/ProfileMetadataSchema.ts +++ b/src/profile/ProfileMetadataSchema.ts @@ -95,8 +95,6 @@ export type ProfileMetadata = { lens: ProfileMetadataDetails; /** * A cryptographic signature of the `lens` data. - * - * @experimental DO NOT use yet */ signature?: Signature; }; diff --git a/src/publication/3D.ts b/src/publication/3D.ts index be63cf2..529c83b 100644 --- a/src/publication/3D.ts +++ b/src/publication/3D.ts @@ -120,8 +120,6 @@ export type ThreeDMetadata = MarketplaceMetadata & { lens: ThreeDMetadataDetails; /** * A cryptographic signature of the `lens` data. - * - * @experimental DO NOT use yet */ signature?: Signature; }; diff --git a/src/publication/ArticleSchema.ts b/src/publication/ArticleSchema.ts index abd8672..786b381 100644 --- a/src/publication/ArticleSchema.ts +++ b/src/publication/ArticleSchema.ts @@ -67,8 +67,6 @@ export type ArticleMetadata = MarketplaceMetadata & { lens: ArticleMetadataDetails; /** * A cryptographic signature of the `lens` data. - * - * @experimental DO NOT use yet */ signature?: Signature; }; diff --git a/src/publication/AudioSchema.ts b/src/publication/AudioSchema.ts index 4773da0..5a52ec4 100644 --- a/src/publication/AudioSchema.ts +++ b/src/publication/AudioSchema.ts @@ -71,8 +71,6 @@ export type AudioMetadata = MarketplaceMetadata & { lens: AudioMetadataDetails; /** * A cryptographic signature of the `lens` data. - * - * @experimental DO NOT use yet */ signature?: Signature; }; diff --git a/src/publication/CheckingInSchema.ts b/src/publication/CheckingInSchema.ts index e8c64ce..760a13d 100644 --- a/src/publication/CheckingInSchema.ts +++ b/src/publication/CheckingInSchema.ts @@ -84,8 +84,6 @@ export type CheckingInMetadata = MarketplaceMetadata & { lens: CheckingInMetadataDetails; /** * A cryptographic signature of the `lens` data. - * - * @experimental DO NOT use yet */ signature?: Signature; }; diff --git a/src/publication/EmbedSchema.ts b/src/publication/EmbedSchema.ts index 9e3f4f3..17bfec2 100644 --- a/src/publication/EmbedSchema.ts +++ b/src/publication/EmbedSchema.ts @@ -66,8 +66,6 @@ export type EmbedMetadata = MarketplaceMetadata & { lens: EmbedMetadataDetails; /** * A cryptographic signature of the `lens` data. - * - * @experimental DO NOT use yet */ signature?: Signature; }; diff --git a/src/publication/EventSchema.ts b/src/publication/EventSchema.ts index 71ff2a6..599b9e6 100644 --- a/src/publication/EventSchema.ts +++ b/src/publication/EventSchema.ts @@ -171,8 +171,6 @@ export type EventMetadata = MarketplaceMetadata & { lens: EventMetadataDetails; /** * A cryptographic signature of the `lens` data. - * - * @experimental DO NOT use yet */ signature?: Signature; }; diff --git a/src/publication/ImageSchema.ts b/src/publication/ImageSchema.ts index 0796c94..4aa0f78 100644 --- a/src/publication/ImageSchema.ts +++ b/src/publication/ImageSchema.ts @@ -71,8 +71,6 @@ export type ImageMetadata = MarketplaceMetadata & { lens: ImageMetadataDetails; /** * A cryptographic signature of the `lens` data. - * - * @experimental DO NOT use yet */ signature?: Signature; }; diff --git a/src/publication/LinkSchema.ts b/src/publication/LinkSchema.ts index 8edf8f6..549f697 100644 --- a/src/publication/LinkSchema.ts +++ b/src/publication/LinkSchema.ts @@ -66,8 +66,6 @@ export type LinkMetadata = MarketplaceMetadata & { lens: LinkMetadataDetails; /** * A cryptographic signature of the `lens` data. - * - * @experimental DO NOT use yet */ signature?: Signature; }; diff --git a/src/publication/LiveStreamSchema.ts b/src/publication/LiveStreamSchema.ts index 48e3f64..b3cd029 100644 --- a/src/publication/LiveStreamSchema.ts +++ b/src/publication/LiveStreamSchema.ts @@ -128,8 +128,6 @@ export type LiveStreamMetadata = MarketplaceMetadata & { lens: LiveStreamMetadataDetails; /** * A cryptographic signature of the `lens` data. - * - * @experimental DO NOT use yet */ signature?: Signature; }; diff --git a/src/publication/MintSchema.ts b/src/publication/MintSchema.ts index 54d5bd7..aaf1550 100644 --- a/src/publication/MintSchema.ts +++ b/src/publication/MintSchema.ts @@ -77,8 +77,6 @@ export type MintMetadata = MarketplaceMetadata & { lens: MintMetadataDetails; /** * A cryptographic signature of the `lens` data. - * - * @experimental DO NOT use yet */ signature?: Signature; }; diff --git a/src/publication/MirrorMetadataSchema.ts b/src/publication/MirrorMetadataSchema.ts index 2d9e698..eb6f13a 100644 --- a/src/publication/MirrorMetadataSchema.ts +++ b/src/publication/MirrorMetadataSchema.ts @@ -51,8 +51,6 @@ export type MirrorMetadata = ShapeCheck<{ lens: MirrorMetadataDetails; /** * A cryptographic signature of the `lens` data. - * - * @experimental DO NOT use yet */ signature?: Signature; }>; diff --git a/src/publication/SpaceSchema.ts b/src/publication/SpaceSchema.ts index 7c7ea0d..561f9a6 100644 --- a/src/publication/SpaceSchema.ts +++ b/src/publication/SpaceSchema.ts @@ -83,8 +83,6 @@ export type SpaceMetadata = MarketplaceMetadata & { lens: SpaceMetadataDetails; /** * A cryptographic signature of the `lens` data. - * - * @experimental DO NOT use yet */ signature?: Signature; }; diff --git a/src/publication/StorySchema.ts b/src/publication/StorySchema.ts index ef3fe62..9d6d1ac 100644 --- a/src/publication/StorySchema.ts +++ b/src/publication/StorySchema.ts @@ -52,8 +52,6 @@ export type StoryMetadata = MarketplaceMetadata & { lens: StoryMetadataDetails; /** * A cryptographic signature of the `lens` data. - * - * @experimental DO NOT use yet */ signature?: Signature; }; diff --git a/src/publication/TextOnlySchema.ts b/src/publication/TextOnlySchema.ts index 7d89514..8528489 100644 --- a/src/publication/TextOnlySchema.ts +++ b/src/publication/TextOnlySchema.ts @@ -53,8 +53,6 @@ export type TextOnlyMetadata = MarketplaceMetadata & { lens: TextOnlyMetadataDetails; /** * A cryptographic signature of the `lens` data. - * - * @experimental DO NOT use yet */ signature?: Signature; }; diff --git a/src/publication/TransactionSchema.ts b/src/publication/TransactionSchema.ts index 193053e..b117d70 100644 --- a/src/publication/TransactionSchema.ts +++ b/src/publication/TransactionSchema.ts @@ -92,8 +92,6 @@ export type TransactionMetadata = MarketplaceMetadata & { lens: TransactionMetadataDetails; /** * A cryptographic signature of the `lens` data. - * - * @experimental DO NOT use yet */ signature?: Signature; }; diff --git a/src/publication/VideoSchema.ts b/src/publication/VideoSchema.ts index 77317c5..d4dade9 100644 --- a/src/publication/VideoSchema.ts +++ b/src/publication/VideoSchema.ts @@ -74,8 +74,6 @@ export type VideoMetadata = MarketplaceMetadata & { lens: VideoMetadataDetails; /** * A cryptographic signature of the `lens` data. - * - * @experimental DO NOT use yet */ signature?: Signature; }; diff --git a/src/publication/common/encryption.ts b/src/publication/common/encryption.ts index cc1dd59..aeffbf5 100644 --- a/src/publication/common/encryption.ts +++ b/src/publication/common/encryption.ts @@ -176,7 +176,7 @@ export const AdvancedContractConditionSchema = z.object({ .describe( 'The contract ABI. Has to be in human readable ' + 'single string format containing the signature of the function you want to call. See ' + - 'https://docs.ethers.org/v5/api/utils/abi/fragments/#human-readable-abi for more info', + 'https://docs.ethers.org/v5/api/utils/abi/formats/#abi-formats--human-readable-abi for more info', ), params: z .string() diff --git a/src/signMetadata.ts b/src/signMetadata.ts new file mode 100644 index 0000000..6541019 --- /dev/null +++ b/src/signMetadata.ts @@ -0,0 +1,41 @@ +import stringify from 'json-stable-stringify'; + +import { ProfileMetadata } from './profile'; +import { MirrorMetadata, PublicationMetadata } from './publication'; + +/** + * Returns a deterministic message from the `metadata.lens` object. + * + * The message can be used in a signature to prove the origin of the Lens portion of the metadata. + * + * @param metadata - the metadata object + * @returns the message + */ +export function lensMessage( + metadata: MirrorMetadata | ProfileMetadata | PublicationMetadata, +): string { + return stringify(metadata.lens); +} + +/** + * A function that signs a message. + */ +export type SignMessage = (message: string) => Promise; + +/** + * Signs a Lens metadata object using the provided `signMessage` function. + * + * @param metadata - the metadata object + * @param signMessage - the function that signs a message + * @returns the signed Lens Metadata object + */ +export async function signMetadata< + TMetadata extends MirrorMetadata | ProfileMetadata | PublicationMetadata, +>(metadata: TMetadata, signMessage: SignMessage): Promise { + const message = lensMessage(metadata); + + return { + ...metadata, + signature: await signMessage(message), + }; +}